summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
...
* avcodec/options: Fix AVClassCategory of decoders with .receive_frameAndreas Rheinhardt2022-04-05
| | | | Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avfilter/vsrc_gradients: add spiral typePaul B Mahol2022-04-05
|
* avfilter/vsrc_gradients: add circular typePaul B Mahol2022-04-05
|
* avcodec/libvpxenc: avoid unnecessary variable shadowingJames Almer2022-04-05
| | | | Signed-off-by: James Almer <jamrial@gmail.com>
* avcodec/libvpxenc: return quantizer parameter for an encoded frameDanil Chapovalov2022-04-05
|
* fate: add a test for writing channel descriptions in movJames Almer2022-04-05
| | | | Signed-off-by: James Almer <jamrial@gmail.com>
* avformat/movenc: don't use mono layout when a front center label is expectedJames Almer2022-04-05
| | | | | | | | | | | | | | | | On output streams where a multichannel stream needs to be stored as one track per channel, each track will have a channel layout describing the position of the channel they contain. For the track with front center, the mov muxer was using the mov layout "mono" instead of the label for the front center position. Since our channel layout API considers front center == mono, we need to do some heuristics. To achieve this, we make sure all audio tracks contain streams with a single channel, and only one of them is front center. In that case, we write the front center label instead of signaling mono layout. Fixes the last part of ticket #2865 Signed-off-by: James Almer <jamrial@gmail.com>
* avformat/mov_chan: move the definition of MovChannelLayoutTag to the headerJames Almer2022-04-05
| | | | Signed-off-by: James Almer <jamrial@gmail.com>
* avformat/movenc: write channel descriptions when a known layout or a bitmap ↵James Almer2022-04-05
| | | | | | | | can't be used Fixes part of ticket #2865 Signed-off-by: James Almer <jamrial@gmail.com>
* avformat/mov_chan: use a higher log level for a debug messageJames Almer2022-04-05
| | | | | | | Trace is too noisy and this line is useful enough to get it printed at debug level. Signed-off-by: James Almer <jamrial@gmail.com>
* avformat/mov_chan: add a few missing channel label mappingsJames Almer2022-04-05
| | | | Signed-off-by: James Almer <jamrial@gmail.com>
* avformat/mov_chan: rename mov_get_channel_label() to better reflect its purposeJames Almer2022-04-05
| | | | | | This function turns a mov channel label into a lavf native bitmask. Signed-off-by: James Almer <jamrial@gmail.com>
* avfilter/vf_mergeplanes: deprecate mapping optionPaul B Mahol2022-04-05
|
* avfilter/vf_mergeplanes: add alternative for less user friendly optionPaul B Mahol2022-04-05
|
* avfilter/vf_mergeplanes: make map code more verbosePaul B Mahol2022-04-05
|
* avfilter/vf_zscale: fix regression with src/dst_format initializationPaul B Mahol2022-04-05
|
* avcodec/exr: Avoid signed overflow in displayWindowMichael Niedermayer2022-04-03
| | | | | | | | | | | | | The inputs are unused except for this computation so wraparound does not give an attacker any extra values as they are already fully controlled Fixes: signed integer overflow: 0 - -2147483648 cannot be represented in type 'int' Fixes: 45820/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_EXR_fuzzer-5766159019933696 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
* avcodec/diracdec: avoid signed integer overflow in global mvMichael Niedermayer2022-04-03
| | | | | | | | Fixes: signed integer overflow: -128275513086 * -76056576 cannot be represented in type 'long' Fixes: 45818/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_DIRAC_fuzzer-5129799149944832 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
* avcodec/takdsp: Fix integer overflow in decorrelate_sf()Michael Niedermayer2022-04-03
| | | | | | | | Fixes: signed integer overflow: -101 * 71041254 cannot be represented in type 'int' Fixes: 45938/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_TAK_fuzzer-4687974320701440 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
* avcodec/apedec: fix a integer overflow in long_filter_high_3800()Michael Niedermayer2022-04-03
| | | | | | | | Fixes: signed integer overflow: -2146549696 - 3923884 cannot be represented in type 'int' Fixes: 45907/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_APE_fuzzer-5992380584558592 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
* lavfi/vf_siti.c: Relicense to LGPL 2.1Thilo Borgmann2022-04-02
|
* avcodec/dfa: don't check for the bitstream version on every copied lineJames Almer2022-04-02
| | | | | | | And use av_image_copy_plane() while at it to simplify things for version != 0x100. Signed-off-by: James Almer <jamrial@gmail.com>
* avfilter: Constify non-const filtersAndreas Rheinhardt2022-04-01
| | | | | | | | This makes the filters match their declaration in libavfilter/allfilters.c; the earlier discrepancy was btw UB. Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* lavfilter: Add SITI filterBoris Baracaldo2022-04-01
| | | | | | Calculate Spatial Info (SI) and Temporal Info (TI) scores for a video, as defined in ITU-T P.910: Subjective video quality assessment methods for multimedia applications.
* avcodec/mpegvideo_enc: Remove redundant unref+refAndreas Rheinhardt2022-04-01
| | | | | | Setting current_picture will already be done in frame_start(). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/mpegvideo: Make new_picture an ordinary AVFrameAndreas Rheinhardt2022-04-01
| | | | | | | | | It is currently a "Picture", an mpegvideo-specific type that has a lot of baggage, all of which is unnecessary for new_picture, because only its embedded AVFrame is ever used. So just use an ordinary AVFrame. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/mpegvideo: Remove strict_std_compliance from MpegEncContextAndreas Rheinhardt2022-04-01
| | | | | | It just duplicates AVCodecContext.strict_std_compliance. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/speedhqenc: Add SpeedHQEncContext and move slice_start to itAndreas Rheinhardt2022-04-01
| | | | Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/mjpegenc: Fix files with slices > 1, but threads == 1Andreas Rheinhardt2022-04-01
| | | | | | | | | | | | | | | | | In the aforementioned case mpegvideo_enc.c calls ff_mjpeg_encode_stuffing() at the end of every line which pads the output to byte-alignment and escapes it; yet it does not write the restart-markers (and also not the DRI marker when writing the header) and so the output files are broken. Fix this by writing these markers depending upon the number of slices and not the number of threads in use; this also makes the output of the encoder reproducible given a slice count and is therefore important if encoder tests that actually use -threads auto are added in the future. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/mjpegenc, speedhqenc: Remove nonsense assertAndreas Rheinhardt2022-04-01
| | | | | | | | | | | | | | | | | | | | | | Our code for writing optimal huffman tables is incompatible with using multiple slices and hence commit 884506dfe2e29a5b2bd2905ca4f17e277e32acb1 that implemented this also added an assert that slice_context_count is always 1. Yet this was always wrong: a) The MJPEG-encoder has (and had) the AV_CODEC_CAP_SLICE_THREADS capability, so asserting that it always uses one slice context is incorrect. b) This commit did not add any proper checks that ensured that optimal huffman tables are never used together with multiple slices. This only happened with 03eb0515c12637dbd20c2e3ca8503d7b47cf583a. c) This assert is at the wrong place: ff_mjpeg_encode_init() is called before the actual slice_context_count is set. This is the reason why this assert was never triggered. Therefore this commit removes this assert. Also remove an assert from the SpeedHQ encoder sharing b) and c). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/mpegvideo_enc: Allow slices only for slice-thread-able codecsAndreas Rheinhardt2022-04-01
| | | | | | | | | | | | | | | | | One can use slices without slice-threading. The results for mpegvideo-encoders are abysmal: AMV, SpeedHQ, H.263, RV10, RV20, MSMPEG4v2, MSMPEG4v3 and WMV1 produce broken files. WMV2 meanwhile expects the MpegEncContext given to ff_wmv2_encode_mb() to be at the beginning of a Wmv2Context (a structure that this encoder shares with the WMV2 decoder), yet this is only true for the main context and not for the slice contexts, leading to segfaults. SpeedHQ additionally triggers an av_assert2, because it is not byte-aligned at a position where it ought to be byte-aligned. Given that no codec not supporting slice threading works this commit disallows using slices unless the encoder supports slice threading. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* doc/filters: document vf_libplaceboNiklas Haas2022-04-01
| | | | Signed-off-by: Niklas Haas <git@haasn.dev>
* avcodec/vc1: Arm 32-bit NEON unescape fast pathBen Avison2022-04-01
| | | | | | | | | | checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. vc1dsp.vc1_unescape_buffer_c: 918624.7 vc1dsp.vc1_unescape_buffer_neon: 142958.0 Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* avcodec/vc1: Arm 64-bit NEON unescape fast pathBen Avison2022-04-01
| | | | | | | | | | checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. vc1dsp.vc1_unescape_buffer_c: 655617.7 vc1dsp.vc1_unescape_buffer_neon: 118237.0 Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* avcodec/idctdsp: Arm 64-bit NEON block add and clamp fast pathsBen Avison2022-04-01
| | | | | | | | | | | | | | checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. idctdsp.add_pixels_clamped_c: 313.3 idctdsp.add_pixels_clamped_neon: 24.3 idctdsp.put_pixels_clamped_c: 220.3 idctdsp.put_pixels_clamped_neon: 15.5 idctdsp.put_signed_pixels_clamped_c: 210.5 idctdsp.put_signed_pixels_clamped_neon: 19.5 Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* avcodec/vc1: Arm 64-bit NEON inverse transform fast pathsBen Avison2022-04-01
| | | | | | | | | | | | | | | | | | | | | | | | checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. vc1dsp.vc1_inv_trans_4x4_c: 158.2 vc1dsp.vc1_inv_trans_4x4_neon: 65.7 vc1dsp.vc1_inv_trans_4x4_dc_c: 86.5 vc1dsp.vc1_inv_trans_4x4_dc_neon: 26.5 vc1dsp.vc1_inv_trans_4x8_c: 335.2 vc1dsp.vc1_inv_trans_4x8_neon: 106.2 vc1dsp.vc1_inv_trans_4x8_dc_c: 151.2 vc1dsp.vc1_inv_trans_4x8_dc_neon: 25.5 vc1dsp.vc1_inv_trans_8x4_c: 365.7 vc1dsp.vc1_inv_trans_8x4_neon: 97.2 vc1dsp.vc1_inv_trans_8x4_dc_c: 139.7 vc1dsp.vc1_inv_trans_8x4_dc_neon: 16.5 vc1dsp.vc1_inv_trans_8x8_c: 547.7 vc1dsp.vc1_inv_trans_8x8_neon: 137.0 vc1dsp.vc1_inv_trans_8x8_dc_c: 268.2 vc1dsp.vc1_inv_trans_8x8_dc_neon: 30.5 Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* avcodec/vc1: Arm 32-bit NEON deblocking filter fast pathsBen Avison2022-04-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. Note that the C version can still outperform the NEON version in specific cases. The balance between different code paths is stream-dependent, but in practice the best case happens about 5% of the time, the worst case happens about 40% of the time, and the complexity of the remaining cases fall somewhere in between. Therefore, taking the average of the best and worst case timings is probably a conservative estimate of the degree by which the NEON code improves performance. vc1dsp.vc1_h_loop_filter4_bestcase_c: 19.0 vc1dsp.vc1_h_loop_filter4_bestcase_neon: 48.5 vc1dsp.vc1_h_loop_filter4_worstcase_c: 144.7 vc1dsp.vc1_h_loop_filter4_worstcase_neon: 76.2 vc1dsp.vc1_h_loop_filter8_bestcase_c: 41.0 vc1dsp.vc1_h_loop_filter8_bestcase_neon: 75.0 vc1dsp.vc1_h_loop_filter8_worstcase_c: 294.0 vc1dsp.vc1_h_loop_filter8_worstcase_neon: 102.7 vc1dsp.vc1_h_loop_filter16_bestcase_c: 54.7 vc1dsp.vc1_h_loop_filter16_bestcase_neon: 130.0 vc1dsp.vc1_h_loop_filter16_worstcase_c: 569.7 vc1dsp.vc1_h_loop_filter16_worstcase_neon: 186.7 vc1dsp.vc1_v_loop_filter4_bestcase_c: 20.2 vc1dsp.vc1_v_loop_filter4_bestcase_neon: 47.2 vc1dsp.vc1_v_loop_filter4_worstcase_c: 164.2 vc1dsp.vc1_v_loop_filter4_worstcase_neon: 68.5 vc1dsp.vc1_v_loop_filter8_bestcase_c: 43.5 vc1dsp.vc1_v_loop_filter8_bestcase_neon: 55.2 vc1dsp.vc1_v_loop_filter8_worstcase_c: 316.2 vc1dsp.vc1_v_loop_filter8_worstcase_neon: 72.7 vc1dsp.vc1_v_loop_filter16_bestcase_c: 62.2 vc1dsp.vc1_v_loop_filter16_bestcase_neon: 103.7 vc1dsp.vc1_v_loop_filter16_worstcase_c: 646.5 vc1dsp.vc1_v_loop_filter16_worstcase_neon: 110.7 Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* avcodec/vc1: Arm 64-bit NEON deblocking filter fast pathsBen Avison2022-04-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. Note that the C version can still outperform the NEON version in specific cases. The balance between different code paths is stream-dependent, but in practice the best case happens about 5% of the time, the worst case happens about 40% of the time, and the complexity of the remaining cases fall somewhere in between. Therefore, taking the average of the best and worst case timings is probably a conservative estimate of the degree by which the NEON code improves performance. vc1dsp.vc1_h_loop_filter4_bestcase_c: 10.7 vc1dsp.vc1_h_loop_filter4_bestcase_neon: 43.5 vc1dsp.vc1_h_loop_filter4_worstcase_c: 184.5 vc1dsp.vc1_h_loop_filter4_worstcase_neon: 73.7 vc1dsp.vc1_h_loop_filter8_bestcase_c: 31.2 vc1dsp.vc1_h_loop_filter8_bestcase_neon: 62.2 vc1dsp.vc1_h_loop_filter8_worstcase_c: 358.2 vc1dsp.vc1_h_loop_filter8_worstcase_neon: 88.2 vc1dsp.vc1_h_loop_filter16_bestcase_c: 51.0 vc1dsp.vc1_h_loop_filter16_bestcase_neon: 107.7 vc1dsp.vc1_h_loop_filter16_worstcase_c: 722.7 vc1dsp.vc1_h_loop_filter16_worstcase_neon: 140.5 vc1dsp.vc1_v_loop_filter4_bestcase_c: 9.7 vc1dsp.vc1_v_loop_filter4_bestcase_neon: 43.0 vc1dsp.vc1_v_loop_filter4_worstcase_c: 178.7 vc1dsp.vc1_v_loop_filter4_worstcase_neon: 69.0 vc1dsp.vc1_v_loop_filter8_bestcase_c: 30.2 vc1dsp.vc1_v_loop_filter8_bestcase_neon: 50.7 vc1dsp.vc1_v_loop_filter8_worstcase_c: 353.0 vc1dsp.vc1_v_loop_filter8_worstcase_neon: 69.2 vc1dsp.vc1_v_loop_filter16_bestcase_c: 60.0 vc1dsp.vc1_v_loop_filter16_bestcase_neon: 90.0 vc1dsp.vc1_v_loop_filter16_worstcase_c: 714.2 vc1dsp.vc1_v_loop_filter16_worstcase_neon: 97.2 Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* avcodec/vc1: Introduce fast path for unescaping bitstream bufferBen Avison2022-04-01
| | | | | | | Includes a checkasm test. Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* checkasm: Add idctdsp add/put-pixels-clamped testsBen Avison2022-04-01
| | | | | Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* checkasm: Add vc1dsp inverse transform testsBen Avison2022-04-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This test deliberately doesn't exercise the full range of inputs described in the committee draft VC-1 standard. It says: input coefficients in frequency domain, D, satisfy -2048 <= D < 2047 intermediate coefficients, E, satisfy -4096 <= E < 4095 fully inverse-transformed coefficients, R, satisfy -512 <= R < 511 For one thing, the inequalities look odd. Did they mean them to go the other way round? That would make more sense because the equations generally both add and subtract coefficients multiplied by constants, including powers of 2. Requiring the most-negative values to be valid extends the number of bits to represent the intermediate values just for the sake of that one case! For another thing, the extreme values don't look to occur in real streams - both in my experience and supported by the following comment in the AArch32 decoder: tNhalf is half of the value of tN (as described in vc1_inv_trans_8x8_c). This is done because sometimes files have input that causes tN + tM to overflow. To avoid this overflow, we compute tNhalf, then compute tNhalf + tM (which doesn't overflow), and then we use vhadd to compute (tNhalf + (tNhalf + tM)) >> 1 which does not overflow because it is one instruction. My AArch64 decoder goes further than this. It calculates tNhalf and tM then does an SRA (essentially a fused halve and add) to compute (tN + tM) >> 1 without ever having to hold (tNhalf + tM) in a 16-bit element without overflowing. It only encounters difficulties if either tNhalf or tM overflow in isolation. I haven't had sight of the final standard, so it's possible that these issues were dealt with during finalisation, which could explain the lack of usage of extreme inputs in real streams. Or a preponderance of decoders that only support 16-bit intermediate values in their inverse transforms might have caused encoders to steer clear of such cases. I have effectively followed this approach in the test, and limited the scale of the coefficients sufficient that both the existing AArch32 decoder and my new AArch64 decoder both pass. Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* checkasm: Add vc1dsp in-loop deblocking filter testsBen Avison2022-04-01
| | | | | | | | | | | Note that the benchmarking results for these functions are highly dependent upon the input data. Therefore, each function is benchmarked twice, corresponding to the best and worst case complexity of the reference C implementation. The performance of a real stream decode will fall somewhere between these two extremes. Signed-off-by: Ben Avison <bavison@riscosopen.org> Signed-off-by: Martin Storsjö <martin@martin.st>
* MAINTAINERS: add myself as maintainer for libsrt protocolZhao Zhili2022-04-01
| | | | | | | Reviewed-by: Steven Liu <lq@chinaffmpeg.org> Reviewed-by: Marton Balint <cus@passwd.hu> Signed-off-by: Zhao Zhili <quinkblack@foxmail.com> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
* avfilter/vf_libplacebo: update for new tone mapping APINiklas Haas2022-03-31
| | | | | | | | | | | | | Upstream gained a new tone-mapping API, which we never switched to. We don't need a version bump for this because it was included as part of the v4.192 release we currently already depend on. Some of the old options can be moderately approximated with the new API, but specifically "desaturation_base" and "max_boost" cannot. Remove these entirely, rather than deprecating them. They have actually been non-functional for a while as a result of the upstream deprecation. Signed-off-by: Niklas Haas <git@haasn.dev>
* avcodec/vp9_superframe_split_bsf: Don't read inexistent dataAndreas Rheinhardt2022-03-31
| | | | | | | | | Fixes: Out of array read Fixes: 45137/clusterfuzz-testcase-minimized-ffmpeg_BSF_VP9_SUPERFRAME_SPLIT_fuzzer-4984270639202304 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/vp9_superframe_split_bsf: Discard invalid zero-sized framesAndreas Rheinhardt2022-03-31
| | | | | | | | They are invalid in VP9. If any of the frames inside a superframe had a size of zero, the code would either read into the next frame or into the superframe index; so check for the length to stop this. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/vp9_superframe_bsf: Check for existence of data before reading itAndreas Rheinhardt2022-03-31
| | | | | | | | | | | | | | | | | | | | | | Packets without data need to be handled specially in order to avoid undefined reads. Pass these packets through unchanged in case there are no cached packets* and error out in case there are cached packets: Returning the packet would mess with the order of the packets; if one returned the zero-sized packet before the superframe that will be created from the packets in the cache, the zero-sized packet would overtake the packets in the cache; if one returned the packet later, the packets that complete the superframe will overtake the zero-sized packet. *: This case e.g. encompasses the scenario of updated extradata side-data at the end. Fixes: Out of array read Fixes: 45722/clusterfuzz-testcase-minimized-ffmpeg_BSF_VP9_SUPERFRAME_fuzzer-5173378975137792 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avcodec/vp9_raw_reorder_bsf: Check for existence of data before reading itAndreas Rheinhardt2022-03-31
| | | | Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* avfilter/af_join: do not dereference possible null pointerPaul B Mahol2022-03-31
|
* doc/bitstream_filters: fix for the syntax of codeLimin Wang2022-03-30
| | | | | | Reviewed-by: Gyan Doshi <ffmpeg@gyani.pro> Reviewed-by: Michael Niedermayer <michael@niedermayer.cc> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>