diff options
Diffstat (limited to 'media/ffvpx/libavcodec')
95 files changed, 12054 insertions, 8876 deletions
diff --git a/media/ffvpx/libavcodec/allcodecs.c b/media/ffvpx/libavcodec/allcodecs.c index b592aa3b2..4f34312e6 100644 --- a/media/ffvpx/libavcodec/allcodecs.c +++ b/media/ffvpx/libavcodec/allcodecs.c @@ -25,6 +25,7 @@ */ #include "config.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "version.h" @@ -58,20 +59,14 @@ av_register_codec_parser(&ff_##x##_parser); \ } -void avcodec_register_all(void) +static void register_all(void) { - static int initialized; - - if (initialized) - return; - initialized = 1; - /* hardware accelerators */ - REGISTER_HWACCEL(H263_CUVID, h263_cuvid); REGISTER_HWACCEL(H263_VAAPI, h263_vaapi); REGISTER_HWACCEL(H263_VIDEOTOOLBOX, h263_videotoolbox); REGISTER_HWACCEL(H264_CUVID, h264_cuvid); REGISTER_HWACCEL(H264_D3D11VA, h264_d3d11va); + REGISTER_HWACCEL(H264_D3D11VA2, h264_d3d11va2); REGISTER_HWACCEL(H264_DXVA2, h264_dxva2); REGISTER_HWACCEL(H264_MEDIACODEC, h264_mediacodec); REGISTER_HWACCEL(H264_MMAL, h264_mmal); @@ -83,11 +78,13 @@ void avcodec_register_all(void) REGISTER_HWACCEL(H264_VIDEOTOOLBOX, h264_videotoolbox); REGISTER_HWACCEL(HEVC_CUVID, hevc_cuvid); REGISTER_HWACCEL(HEVC_D3D11VA, hevc_d3d11va); + REGISTER_HWACCEL(HEVC_D3D11VA2, hevc_d3d11va2); REGISTER_HWACCEL(HEVC_DXVA2, hevc_dxva2); REGISTER_HWACCEL(HEVC_MEDIACODEC, hevc_mediacodec); REGISTER_HWACCEL(HEVC_QSV, hevc_qsv); REGISTER_HWACCEL(HEVC_VAAPI, hevc_vaapi); REGISTER_HWACCEL(HEVC_VDPAU, hevc_vdpau); + REGISTER_HWACCEL(HEVC_VIDEOTOOLBOX, hevc_videotoolbox); REGISTER_HWACCEL(MJPEG_CUVID, mjpeg_cuvid); REGISTER_HWACCEL(MPEG1_CUVID, mpeg1_cuvid); REGISTER_HWACCEL(MPEG1_XVMC, mpeg1_xvmc); @@ -96,12 +93,14 @@ void avcodec_register_all(void) REGISTER_HWACCEL(MPEG2_CUVID, mpeg2_cuvid); REGISTER_HWACCEL(MPEG2_XVMC, mpeg2_xvmc); REGISTER_HWACCEL(MPEG2_D3D11VA, mpeg2_d3d11va); + REGISTER_HWACCEL(MPEG2_D3D11VA2, mpeg2_d3d11va2); REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL(MPEG2_MMAL, mpeg2_mmal); REGISTER_HWACCEL(MPEG2_QSV, mpeg2_qsv); REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau); REGISTER_HWACCEL(MPEG2_VIDEOTOOLBOX, mpeg2_videotoolbox); + REGISTER_HWACCEL(MPEG2_MEDIACODEC, mpeg2_mediacodec); REGISTER_HWACCEL(MPEG4_CUVID, mpeg4_cuvid); REGISTER_HWACCEL(MPEG4_MEDIACODEC, mpeg4_mediacodec); REGISTER_HWACCEL(MPEG4_MMAL, mpeg4_mmal); @@ -110,6 +109,7 @@ void avcodec_register_all(void) REGISTER_HWACCEL(MPEG4_VIDEOTOOLBOX, mpeg4_videotoolbox); REGISTER_HWACCEL(VC1_CUVID, vc1_cuvid); REGISTER_HWACCEL(VC1_D3D11VA, vc1_d3d11va); + REGISTER_HWACCEL(VC1_D3D11VA2, vc1_d3d11va2); REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2); REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); @@ -117,12 +117,15 @@ void avcodec_register_all(void) REGISTER_HWACCEL(VC1_QSV, vc1_qsv); REGISTER_HWACCEL(VP8_CUVID, vp8_cuvid); REGISTER_HWACCEL(VP8_MEDIACODEC, vp8_mediacodec); + REGISTER_HWACCEL(VP8_QSV, vp8_qsv); REGISTER_HWACCEL(VP9_CUVID, vp9_cuvid); REGISTER_HWACCEL(VP9_D3D11VA, vp9_d3d11va); + REGISTER_HWACCEL(VP9_D3D11VA2, vp9_d3d11va2); REGISTER_HWACCEL(VP9_DXVA2, vp9_dxva2); REGISTER_HWACCEL(VP9_MEDIACODEC, vp9_mediacodec); REGISTER_HWACCEL(VP9_VAAPI, vp9_vaapi); REGISTER_HWACCEL(WMV3_D3D11VA, wmv3_d3d11va); + REGISTER_HWACCEL(WMV3_D3D11VA2, wmv3_d3d11va2); REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi); REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau); @@ -158,6 +161,7 @@ void avcodec_register_all(void) REGISTER_DECODER(CDXL, cdxl); REGISTER_DECODER(CFHD, cfhd); REGISTER_ENCDEC (CINEPAK, cinepak); + REGISTER_DECODER(CLEARVIDEO, clearvideo); REGISTER_ENCDEC (CLJR, cljr); REGISTER_DECODER(CLLC, cllc); REGISTER_ENCDEC (COMFORTNOISE, comfortnoise); @@ -189,24 +193,30 @@ void avcodec_register_all(void) REGISTER_ENCDEC (FFV1, ffv1); REGISTER_ENCDEC (FFVHUFF, ffvhuff); REGISTER_DECODER(FIC, fic); + REGISTER_ENCDEC (FITS, fits); REGISTER_ENCDEC (FLASHSV, flashsv); REGISTER_ENCDEC (FLASHSV2, flashsv2); REGISTER_DECODER(FLIC, flic); REGISTER_ENCDEC (FLV, flv); + REGISTER_DECODER(FMVC, fmvc); REGISTER_DECODER(FOURXM, fourxm); REGISTER_DECODER(FRAPS, fraps); REGISTER_DECODER(FRWU, frwu); REGISTER_DECODER(G2M, g2m); + REGISTER_DECODER(GDV, gdv); REGISTER_ENCDEC (GIF, gif); REGISTER_ENCDEC (H261, h261); REGISTER_ENCDEC (H263, h263); REGISTER_DECODER(H263I, h263i); REGISTER_ENCDEC (H263P, h263p); + REGISTER_DECODER(H263_V4L2M2M, h263_v4l2m2m); REGISTER_DECODER(H264, h264); REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd); + REGISTER_DECODER(H264_V4L2M2M, h264_v4l2m2m); REGISTER_DECODER(H264_MEDIACODEC, h264_mediacodec); REGISTER_DECODER(H264_MMAL, h264_mmal); REGISTER_DECODER(H264_QSV, h264_qsv); + REGISTER_DECODER(H264_RKMPP, h264_rkmpp); REGISTER_DECODER(H264_VDA, h264_vda); #if FF_API_VDPAU REGISTER_DECODER(H264_VDPAU, h264_vdpau); @@ -214,6 +224,8 @@ void avcodec_register_all(void) REGISTER_ENCDEC (HAP, hap); REGISTER_DECODER(HEVC, hevc); REGISTER_DECODER(HEVC_QSV, hevc_qsv); + REGISTER_DECODER(HEVC_RKMPP, hevc_rkmpp); + REGISTER_DECODER(HEVC_V4L2M2M, hevc_v4l2m2m); REGISTER_DECODER(HNM4_VIDEO, hnm4_video); REGISTER_DECODER(HQ_HQA, hq_hqa); REGISTER_DECODER(HQX, hqx); @@ -248,6 +260,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); REGISTER_DECODER(MPEG4_CRYSTALHD, mpeg4_crystalhd); + REGISTER_DECODER(MPEG4_V4L2M2M, mpeg4_v4l2m2m); REGISTER_DECODER(MPEG4_MMAL, mpeg4_mmal); #if FF_API_VDPAU REGISTER_DECODER(MPEG4_VDPAU, mpeg4_vdpau); @@ -257,14 +270,18 @@ void avcodec_register_all(void) REGISTER_DECODER(MPEG_VDPAU, mpeg_vdpau); REGISTER_DECODER(MPEG1_VDPAU, mpeg1_vdpau); #endif + REGISTER_DECODER(MPEG1_V4L2M2M, mpeg1_v4l2m2m); REGISTER_DECODER(MPEG2_MMAL, mpeg2_mmal); REGISTER_DECODER(MPEG2_CRYSTALHD, mpeg2_crystalhd); + REGISTER_DECODER(MPEG2_V4L2M2M, mpeg2_v4l2m2m); REGISTER_DECODER(MPEG2_QSV, mpeg2_qsv); + REGISTER_DECODER(MPEG2_MEDIACODEC, mpeg2_mediacodec); REGISTER_DECODER(MSA1, msa1); - REGISTER_DECODER(MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); + REGISTER_DECODER(MSCC, mscc); REGISTER_DECODER(MSMPEG4V1, msmpeg4v1); REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); + REGISTER_DECODER(MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); REGISTER_DECODER(MSRLE, msrle); REGISTER_DECODER(MSS1, mss1); REGISTER_DECODER(MSS2, mss2); @@ -282,12 +299,14 @@ void avcodec_register_all(void) REGISTER_ENCDEC (PGM, pgm); REGISTER_ENCDEC (PGMYUV, pgmyuv); REGISTER_DECODER(PICTOR, pictor); + REGISTER_DECODER(PIXLET, pixlet); REGISTER_ENCDEC (PNG, png); REGISTER_ENCDEC (PPM, ppm); REGISTER_ENCDEC (PRORES, prores); REGISTER_ENCODER(PRORES_AW, prores_aw); REGISTER_ENCODER(PRORES_KS, prores_ks); REGISTER_DECODER(PRORES_LGPL, prores_lgpl); + REGISTER_DECODER(PSD, psd); REGISTER_DECODER(PTX, ptx); REGISTER_DECODER(QDRAW, qdraw); REGISTER_DECODER(QPEG, qpeg); @@ -305,6 +324,7 @@ void avcodec_register_all(void) REGISTER_DECODER(RV40, rv40); REGISTER_ENCDEC (S302M, s302m); REGISTER_DECODER(SANM, sanm); + REGISTER_DECODER(SCPR, scpr); REGISTER_DECODER(SCREENPRESSO, screenpresso); REGISTER_DECODER(SDX2_DPCM, sdx2_dpcm); REGISTER_ENCDEC (SGI, sgi); @@ -315,6 +335,8 @@ void avcodec_register_all(void) REGISTER_DECODER(SMVJPEG, smvjpeg); REGISTER_ENCDEC (SNOW, snow); REGISTER_DECODER(SP5X, sp5x); + REGISTER_DECODER(SPEEDHQ, speedhq); + REGISTER_DECODER(SRGC, srgc); REGISTER_ENCDEC (SUNRAST, sunrast); REGISTER_ENCDEC (SVQ1, svq1); REGISTER_DECODER(SVQ3, svq3); @@ -349,6 +371,7 @@ void avcodec_register_all(void) REGISTER_DECODER(VC1IMAGE, vc1image); REGISTER_DECODER(VC1_MMAL, vc1_mmal); REGISTER_DECODER(VC1_QSV, vc1_qsv); + REGISTER_DECODER(VC1_V4L2M2M, vc1_v4l2m2m); REGISTER_ENCODER(VC2, vc2); REGISTER_DECODER(VCR1, vcr1); REGISTER_DECODER(VMDVIDEO, vmdvideo); @@ -360,10 +383,15 @@ void avcodec_register_all(void) REGISTER_DECODER(VP6F, vp6f); REGISTER_DECODER(VP7, vp7); REGISTER_DECODER(VP8, vp8); + REGISTER_DECODER(VP8_RKMPP, vp8_rkmpp); + REGISTER_DECODER(VP8_V4L2M2M, vp8_v4l2m2m); REGISTER_DECODER(VP9, vp9); + REGISTER_DECODER(VP9_RKMPP, vp9_rkmpp); + REGISTER_DECODER(VP9_V4L2M2M, vp9_v4l2m2m); REGISTER_DECODER(VQA, vqa); + REGISTER_DECODER(BITPACKED, bitpacked); REGISTER_DECODER(WEBP, webp); - REGISTER_ENCODER(WRAPPED_AVFRAME, wrapped_avframe); + REGISTER_ENCDEC (WRAPPED_AVFRAME, wrapped_avframe); REGISTER_ENCDEC (WMV1, wmv1); REGISTER_ENCDEC (WMV2, wmv2); REGISTER_DECODER(WMV3, wmv3); @@ -378,6 +406,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (XBM, xbm); REGISTER_ENCDEC (XFACE, xface); REGISTER_DECODER(XL, xl); + REGISTER_DECODER(XPM, xpm); REGISTER_ENCDEC (XWD, xwd); REGISTER_ENCDEC (Y41P, y41p); REGISTER_DECODER(YLC, ylc); @@ -401,12 +430,15 @@ void avcodec_register_all(void) REGISTER_DECODER(APE, ape); REGISTER_DECODER(ATRAC1, atrac1); REGISTER_DECODER(ATRAC3, atrac3); + REGISTER_DECODER(ATRAC3AL, atrac3al); REGISTER_DECODER(ATRAC3P, atrac3p); + REGISTER_DECODER(ATRAC3PAL, atrac3pal); REGISTER_DECODER(BINKAUDIO_DCT, binkaudio_dct); REGISTER_DECODER(BINKAUDIO_RDFT, binkaudio_rdft); REGISTER_DECODER(BMV_AUDIO, bmv_audio); REGISTER_DECODER(COOK, cook); REGISTER_ENCDEC (DCA, dca); + REGISTER_DECODER(DOLBY_E, dolby_e); REGISTER_DECODER(DSD_LSBF, dsd_lsbf); REGISTER_DECODER(DSD_MSBF, dsd_msbf); REGISTER_DECODER(DSD_LSBF_PLANAR, dsd_lsbf_planar); @@ -444,10 +476,11 @@ void avcodec_register_all(void) REGISTER_DECODER(MPC8, mpc8); REGISTER_ENCDEC (NELLYMOSER, nellymoser); REGISTER_DECODER(ON2AVC, on2avc); - REGISTER_DECODER(OPUS, opus); + REGISTER_ENCDEC (OPUS, opus); REGISTER_DECODER(PAF_AUDIO, paf_audio); REGISTER_DECODER(QCELP, qcelp); REGISTER_DECODER(QDM2, qdm2); + REGISTER_DECODER(QDMC, qdmc); REGISTER_ENCDEC (RA_144, ra_144); REGISTER_DECODER(RA_288, ra_288); REGISTER_DECODER(RALF, ralf); @@ -477,6 +510,8 @@ void avcodec_register_all(void) REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); REGISTER_DECODER(PCM_BLURAY, pcm_bluray); REGISTER_DECODER(PCM_DVD, pcm_dvd); + REGISTER_DECODER(PCM_F16LE, pcm_f16le); + REGISTER_DECODER(PCM_F24LE, pcm_f24le); REGISTER_ENCDEC (PCM_F32BE, pcm_f32be); REGISTER_ENCDEC (PCM_F32LE, pcm_f32le); REGISTER_ENCDEC (PCM_F64BE, pcm_f64be); @@ -508,6 +543,7 @@ void avcodec_register_all(void) REGISTER_DECODER(PCM_ZORK, pcm_zork); /* DPCM codecs */ + REGISTER_DECODER(GREMLIN_DPCM, gremlin_dpcm); REGISTER_DECODER(INTERPLAY_DPCM, interplay_dpcm); REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm); REGISTER_DECODER(SOL_DPCM, sol_dpcm); @@ -528,7 +564,7 @@ void avcodec_register_all(void) REGISTER_DECODER(ADPCM_EA_XAS, adpcm_ea_xas); REGISTER_ENCDEC (ADPCM_G722, adpcm_g722); REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); - REGISTER_DECODER(ADPCM_G726LE, adpcm_g726le); + REGISTER_ENCDEC (ADPCM_G726LE, adpcm_g726le); REGISTER_DECODER(ADPCM_IMA_AMV, adpcm_ima_amv); REGISTER_DECODER(ADPCM_IMA_APC, adpcm_ima_apc); REGISTER_DECODER(ADPCM_IMA_DAT4, adpcm_ima_dat4); @@ -606,7 +642,7 @@ void avcodec_register_all(void) REGISTER_DECODER(LIBOPENCORE_AMRWB, libopencore_amrwb); REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); REGISTER_ENCDEC (LIBOPUS, libopus); - REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); + REGISTER_DECODER(LIBRSVG, librsvg); REGISTER_ENCODER(LIBSHINE, libshine); REGISTER_ENCDEC (LIBSPEEX, libspeex); REGISTER_ENCODER(LIBTHEORA, libtheora); @@ -633,12 +669,13 @@ void avcodec_register_all(void) /* external libraries, that shouldn't be used by default if one of the * above is available */ + REGISTER_ENCODER(H263_V4L2M2M, h263_v4l2m2m); REGISTER_ENCDEC (LIBOPENH264, libopenh264); - REGISTER_DECODER(H263_CUVID, h263_cuvid); REGISTER_DECODER(H264_CUVID, h264_cuvid); REGISTER_ENCODER(H264_NVENC, h264_nvenc); REGISTER_ENCODER(H264_OMX, h264_omx); REGISTER_ENCODER(H264_QSV, h264_qsv); + REGISTER_ENCODER(H264_V4L2M2M, h264_v4l2m2m); REGISTER_ENCODER(H264_VAAPI, h264_vaapi); REGISTER_ENCODER(H264_VIDEOTOOLBOX, h264_videotoolbox); #if FF_API_NVENC_OLD_NAME @@ -650,6 +687,7 @@ void avcodec_register_all(void) REGISTER_DECODER(HEVC_MEDIACODEC, hevc_mediacodec); REGISTER_ENCODER(HEVC_NVENC, hevc_nvenc); REGISTER_ENCODER(HEVC_QSV, hevc_qsv); + REGISTER_ENCODER(HEVC_V4L2M2M, hevc_v4l2m2m); REGISTER_ENCODER(HEVC_VAAPI, hevc_vaapi); REGISTER_ENCODER(LIBKVAZAAR, libkvazaar); REGISTER_DECODER(MJPEG_CUVID, mjpeg_cuvid); @@ -657,13 +695,19 @@ void avcodec_register_all(void) REGISTER_DECODER(MPEG1_CUVID, mpeg1_cuvid); REGISTER_DECODER(MPEG2_CUVID, mpeg2_cuvid); REGISTER_ENCODER(MPEG2_QSV, mpeg2_qsv); + REGISTER_ENCODER(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_DECODER(MPEG4_CUVID, mpeg4_cuvid); REGISTER_DECODER(MPEG4_MEDIACODEC, mpeg4_mediacodec); + REGISTER_ENCODER(MPEG4_V4L2M2M, mpeg4_v4l2m2m); REGISTER_DECODER(VC1_CUVID, vc1_cuvid); REGISTER_DECODER(VP8_CUVID, vp8_cuvid); REGISTER_DECODER(VP8_MEDIACODEC, vp8_mediacodec); + REGISTER_DECODER(VP8_QSV, vp8_qsv); + REGISTER_ENCODER(VP8_V4L2M2M, vp8_v4l2m2m); + REGISTER_ENCODER(VP8_VAAPI, vp8_vaapi); REGISTER_DECODER(VP9_CUVID, vp9_cuvid); REGISTER_DECODER(VP9_MEDIACODEC, vp9_mediacodec); + REGISTER_ENCODER(VP9_VAAPI, vp9_vaapi); /* parsers */ REGISTER_PARSER(AAC, aac); @@ -698,10 +742,19 @@ void avcodec_register_all(void) REGISTER_PARSER(PNM, pnm); REGISTER_PARSER(RV30, rv30); REGISTER_PARSER(RV40, rv40); + REGISTER_PARSER(SIPR, sipr); REGISTER_PARSER(TAK, tak); REGISTER_PARSER(VC1, vc1); REGISTER_PARSER(VORBIS, vorbis); REGISTER_PARSER(VP3, vp3); REGISTER_PARSER(VP8, vp8); REGISTER_PARSER(VP9, vp9); + REGISTER_PARSER(XMA, xma); +} + +void avcodec_register_all(void) +{ + static AVOnce control = AV_ONCE_INIT; + + ff_thread_once(&control, register_all); } diff --git a/media/ffvpx/libavcodec/avcodec.h b/media/ffvpx/libavcodec/avcodec.h index e5e7f4225..18c3e3ea1 100644 --- a/media/ffvpx/libavcodec/avcodec.h +++ b/media/ffvpx/libavcodec/avcodec.h @@ -89,7 +89,7 @@ * - Send valid input: * - For decoding, call avcodec_send_packet() to give the decoder raw * compressed data in an AVPacket. - * - For encoding, call avcodec_send_frame() to give the decoder an AVFrame + * - For encoding, call avcodec_send_frame() to give the encoder an AVFrame * containing uncompressed audio or video. * In both cases, it is recommended that AVPackets and AVFrames are * refcounted, or libavcodec might have to copy the input data. (libavformat @@ -112,6 +112,12 @@ * are filled. This situation is handled transparently if you follow the steps * outlined above. * + * In theory, sending input can result in EAGAIN - this should happen only if + * not all output was received. You can use this to structure alternative decode + * or encode loops other than the one suggested above. For example, you could + * try sending new input on each iteration, and try to receive output if that + * returns EAGAIN. + * * End of stream situations. These require "flushing" (aka draining) the codec, * as the codec might buffer multiple frames or packets internally for * performance or out of necessity (consider B-frames). @@ -136,8 +142,9 @@ * * Not all codecs will follow a rigid and predictable dataflow; the only * guarantee is that an AVERROR(EAGAIN) return value on a send/receive call on - * one end implies that a receive/send call on the other end will succeed. In - * general, no codec will permit unlimited buffering of input or output. + * one end implies that a receive/send call on the other end will succeed, or + * at least will not fail with AVERROR(EAGAIN). In general, no codec will + * permit unlimited buffering of input or output. * * This API replaces the following legacy functions: * - avcodec_decode_video2() and avcodec_decode_audio4(): @@ -146,7 +153,8 @@ * Unlike with the old video decoding API, multiple frames might result from * a packet. For audio, splitting the input packet into frames by partially * decoding packets becomes transparent to the API user. You never need to - * feed an AVPacket to the API twice. + * feed an AVPacket to the API twice (unless it is rejected with AVERROR(EAGAIN) - then + * no data was read from the packet). * Additionally, sending a flush/draining packet is required only once. * - avcodec_encode_video2()/avcodec_encode_audio2(): * Use avcodec_send_frame() to feed input to the encoder, then use @@ -159,7 +167,22 @@ * and will result in undefined behavior. * * Some codecs might require using the new API; using the old API will return - * an error when calling it. + * an error when calling it. All codecs support the new API. + * + * A codec is not allowed to return AVERROR(EAGAIN) for both sending and receiving. This + * would be an invalid state, which could put the codec user into an endless + * loop. The API has no concept of time either: it cannot happen that trying to + * do avcodec_send_packet() results in AVERROR(EAGAIN), but a repeated call 1 second + * later accepts the packet (with no other receive/flush API calls involved). + * The API is a strict state machine, and the passage of time is not supposed + * to influence it. Some timing-dependent behavior might still be deemed + * acceptable in certain cases. But it must never result in both send/receive + * returning EAGAIN at the same time at any point. It must also absolutely be + * avoided that the current state is "unstable" and can "flip-flop" between + * the send/receive APIs allowing progress. For example, it's not allowed that + * the codec randomly decides that it actually wants to consume a packet now + * instead of returning a frame, after it just returned AVERROR(EAGAIN) on an + * avcodec_send_packet() call. * @} */ @@ -411,6 +434,20 @@ enum AVCodecID { AV_CODEC_ID_MAGICYUV, AV_CODEC_ID_SHEERVIDEO, AV_CODEC_ID_YLC, + AV_CODEC_ID_PSD, + AV_CODEC_ID_PIXLET, + AV_CODEC_ID_SPEEDHQ, + AV_CODEC_ID_FMVC, + AV_CODEC_ID_SCPR, + AV_CODEC_ID_CLEARVIDEO, + AV_CODEC_ID_XPM, + AV_CODEC_ID_AV1, + AV_CODEC_ID_BITPACKED, + AV_CODEC_ID_MSCC, + AV_CODEC_ID_SRGC, + AV_CODEC_ID_SVG, + AV_CODEC_ID_GDV, + AV_CODEC_ID_FITS, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs @@ -448,6 +485,8 @@ enum AVCodecID { AV_CODEC_ID_PCM_S64LE = 0x10800, AV_CODEC_ID_PCM_S64BE, + AV_CODEC_ID_PCM_F16LE, + AV_CODEC_ID_PCM_F24LE, /* various ADPCM codecs */ AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, @@ -511,6 +550,7 @@ enum AVCodecID { AV_CODEC_ID_SOL_DPCM, AV_CODEC_ID_SDX2_DPCM = 0x14800, + AV_CODEC_ID_GREMLIN_DPCM, /* audio codecs */ AV_CODEC_ID_MP2 = 0x15000, @@ -598,6 +638,9 @@ enum AVCodecID { AV_CODEC_ID_XMA1, AV_CODEC_ID_XMA2, AV_CODEC_ID_DST, + AV_CODEC_ID_ATRAC3AL, + AV_CODEC_ID_ATRAC3PAL, + AV_CODEC_ID_DOLBY_E, /* subtitle codecs */ AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. @@ -689,7 +732,7 @@ typedef struct AVCodecDescriptor { /** * Codec uses only intra compression. - * Video codecs only. + * Video and audio codecs only. */ #define AV_CODEC_PROP_INTRA_ONLY (1 << 0) /** @@ -1360,6 +1403,11 @@ typedef struct AVCPBProperties { * @{ */ enum AVPacketSideDataType { + /** + * An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE + * bytes worth of palette. This side data signals that a new palette is + * present. + */ AV_PKT_DATA_PALETTE, /** @@ -1533,10 +1581,40 @@ enum AVPacketSideDataType { /** * Mastering display metadata (based on SMPTE-2086:2014). This metadata - * should be associated with a video stream and containts data in the form + * should be associated with a video stream and contains data in the form * of the AVMasteringDisplayMetadata struct. */ - AV_PKT_DATA_MASTERING_DISPLAY_METADATA + AV_PKT_DATA_MASTERING_DISPLAY_METADATA, + + /** + * This side data should be associated with a video stream and corresponds + * to the AVSphericalMapping structure. + */ + AV_PKT_DATA_SPHERICAL, + + /** + * Content light level (based on CTA-861.3). This metadata should be + * associated with a video stream and contains data in the form of the + * AVContentLightMetadata struct. + */ + AV_PKT_DATA_CONTENT_LIGHT_LEVEL, + + /** + * ATSC A53 Part 4 Closed Captions. This metadata should be associated with + * a video stream. A53 CC bitstream is stored as uint8_t in AVPacketSideData.data. + * The number of bytes of CC data is AVPacketSideData.size. + */ + AV_PKT_DATA_A53_CC, + + /** + * 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 @@ -1638,6 +1716,13 @@ typedef struct AVPacket { * after decoding. **/ #define AV_PKT_FLAG_DISCARD 0x0004 +/** + * The packet comes from a trusted source. + * + * Otherwise-unsafe constructs such as arbitrary pointers to data + * outside the packet may be followed. + */ +#define AV_PKT_FLAG_TRUSTED 0x0008 enum AVSideDataParamChangeFlags { AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, @@ -1665,7 +1750,7 @@ enum AVFieldOrder { * 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 + * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user * applications. * The name string for AVOptions options matches the associated command line * parameter name and can be found in libavcodec/options_table.h @@ -2605,6 +2690,7 @@ typedef struct AVCodecContext { * - encoding: unused * - decoding: set by the caller before avcodec_open2(). */ + attribute_deprecated int refcounted_frames; /* - encoding parameters */ @@ -2936,8 +3022,8 @@ typedef struct AVCodecContext { #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 +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 #endif #define FF_DEBUG_BUFFERS 0x00008000 #define FF_DEBUG_THREADS 0x00010000 @@ -2947,7 +3033,6 @@ typedef struct AVCodecContext { #if FF_API_DEBUG_MV /** * debug - * Code outside libavcodec should access this field using AVOptions * - encoding: Set by user. * - decoding: Set by user. */ @@ -3061,6 +3146,7 @@ typedef struct AVCodecContext { #if FF_API_ARCH_ALPHA #define FF_IDCT_SIMPLEALPHA 23 #endif +#define FF_IDCT_NONE 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */ #define FF_IDCT_SIMPLEAUTO 128 /** @@ -3082,8 +3168,6 @@ typedef struct AVCodecContext { * 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 @@ -3384,8 +3468,6 @@ typedef struct AVCodecContext { /** * 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. */ @@ -3393,8 +3475,6 @@ typedef struct AVCodecContext { /** * AVCodecDescriptor - * Code outside libavcodec should access this field using: - * av_codec_{get,set}_codec_descriptor(avctx) * - encoding: unused. * - decoding: set by libavcodec. */ @@ -3405,8 +3485,6 @@ typedef struct AVCodecContext { * 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 @@ -3447,7 +3525,6 @@ typedef struct AVCodecContext { * 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 @@ -3464,7 +3541,6 @@ typedef struct AVCodecContext { #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. */ @@ -3476,7 +3552,6 @@ typedef struct AVCodecContext { /** * 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. */ @@ -3485,8 +3560,6 @@ typedef struct AVCodecContext { /** * 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. */ @@ -3496,13 +3569,12 @@ typedef struct AVCodecContext { * ',' separated list of allowed decoders. * If NULL then all are allowed * - encoding: unused - * - decoding: set by user through AVOPtions (NO direct access) + * - decoding: set by user */ 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 */ @@ -3522,7 +3594,8 @@ typedef struct AVCodecContext { /** * A reference to the AVHWFramesContext describing the input (for encoding) * or output (decoding) frames. The reference is set by the caller and - * afterwards owned (and freed) by libavcodec. + * afterwards owned (and freed) by libavcodec - it should never be read by + * the caller after being set. * * - decoding: This field should be set by the caller from the get_format() * callback. The previous reference (if any) will always be @@ -3564,6 +3637,71 @@ typedef struct AVCodecContext { */ int trailing_padding; + /** + * The number of pixels per image to maximally accept. + * + * - decoding: set by user + * - encoding: set by user + */ + int64_t max_pixels; + + /** + * A reference to the AVHWDeviceContext describing the device which will + * be used by a hardware encoder/decoder. The reference is set by the + * caller and afterwards owned (and freed) by libavcodec. + * + * This should be used if either the codec device does not require + * hardware frames or any that are used are to be allocated internally by + * libavcodec. If the user wishes to supply any of the frames used as + * encoder input or decoder output then hw_frames_ctx should be used + * instead. When hw_frames_ctx is set in get_format() for a decoder, this + * field will be ignored while decoding the associated stream segment, but + * may again be used on a following one after another get_format() call. + * + * For both encoders and decoders this field should be set before + * avcodec_open2() is called and must not be written to thereafter. + * + * Note that some decoders may require this field to be set initially in + * order to support hw_frames_ctx at all - in that case, all frames + * contexts used must be created on the same device. + */ + AVBufferRef *hw_device_ctx; + + /** + * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated + * decoding (if active). + * - encoding: unused + * - decoding: Set by user (either before avcodec_open2(), or in the + * AVCodecContext.get_format callback) + */ + int hwaccel_flags; + + /** + * Video decoding only. Certain video codecs support cropping, meaning that + * only a sub-rectangle of the decoded frame is intended for display. This + * option controls how cropping is handled by libavcodec. + * + * When set to 1 (the default), libavcodec will apply cropping internally. + * I.e. it will modify the output frame width/height fields and offset the + * data pointers (only by as much as possible while preserving alignment, or + * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that + * the frames output by the decoder refer only to the cropped area. The + * crop_* fields of the output frames will be zero. + * + * When set to 0, the width/height fields of the output frames will be set + * to the coded dimensions and the crop_* fields will describe the cropping + * rectangle. Applying the cropping is left to the caller. + * + * @warning When hardware acceleration with opaque output frames is used, + * libavcodec is unable to apply cropping from the top/left border. + * + * @note when this option is set to zero, the width/height fields of the + * AVCodecContext and output AVFrames have different meanings. The codec + * context fields store display dimensions (with the coded dimensions in + * coded_width/height), while the frame fields store the coded dimensions + * (with the display dimensions being determined by the crop_* fields). + */ + int apply_cropping; } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); @@ -3623,7 +3761,7 @@ typedef struct AVCodec { const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 - uint8_t max_lowres; ///< maximum value for lowres supported by the decoder, no direct access, use av_codec_get_max_lowres() + uint8_t max_lowres; ///< maximum value for lowres supported by the decoder 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} @@ -3684,20 +3822,22 @@ typedef struct AVCodec { int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); int (*close)(AVCodecContext *); /** - * Decode/encode API with decoupled packet/frame dataflow. The API is the + * Encode API with decoupled packet/frame dataflow. The API is the * same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except * that: * - never called if the codec is closed or the wrong type, - * - AVPacket parameter change side data is applied right before calling - * AVCodec->send_packet, - * - if AV_CODEC_CAP_DELAY is not set, drain packets or frames are never sent, - * - only one drain packet is ever passed down (until the next flush()), - * - a drain AVPacket is always NULL (no need to check for avpkt->size). + * - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent, + * - only one drain frame is ever passed down, */ int (*send_frame)(AVCodecContext *avctx, const AVFrame *frame); - int (*send_packet)(AVCodecContext *avctx, const AVPacket *avpkt); - int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame); int (*receive_packet)(AVCodecContext *avctx, AVPacket *avpkt); + + /** + * Decode API with decoupled packet/frame dataflow. This function is called + * to get one output frame. It should call ff_decode_get_packet() to obtain + * input data. + */ + int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame); /** * Flush buffers. * Will be called when seeking @@ -3708,6 +3848,12 @@ typedef struct AVCodec { * See FF_CODEC_CAP_* in internal.h */ int caps_internal; + + /** + * Decoding only, a comma-separated list of bitstream filters to apply to + * packets before decoding. + */ + const char *bsfs; } AVCodec; int av_codec_get_max_lowres(const AVCodec *codec); @@ -3749,7 +3895,7 @@ typedef struct AVHWAccel { /** * Hardware accelerated codec capabilities. - * see HWACCEL_CODEC_CAP_* + * see AV_HWACCEL_CODEC_CAP_* */ int capabilities; @@ -3820,7 +3966,7 @@ typedef struct AVHWAccel { /** * Called for every Macroblock in a slice. * - * XvMC uses it to replace the ff_mpv_decode_mb(). + * XvMC uses it to replace the ff_mpv_reconstruct_mb(). * Instead of decoding to raw picture, MB parameters are * stored in an array provided by the video driver. * @@ -3850,9 +3996,20 @@ typedef struct AVHWAccel { * AVCodecInternal.hwaccel_priv_data. */ int priv_data_size; + + /** + * Internal hwaccel capabilities. + */ + int caps_internal; } AVHWAccel; /** + * HWAccel is experimental and is thus avoided in favor of non experimental + * codecs + */ +#define AV_HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200 + +/** * 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. @@ -3869,6 +4026,20 @@ typedef struct AVHWAccel { #define AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH (1 << 1) /** + * Hardware acceleration should still be attempted for decoding when the + * codec profile does not match the reported capabilities of the hardware. + * + * For example, this can be used to try to decode baseline profile H.264 + * streams in hardware - it will often succeed, because many streams marked + * as baseline profile actually conform to constrained baseline profile. + * + * @warning If the stream is actually not supported then the behaviour is + * undefined, and may include returning entirely incorrect output + * while indicating success. + */ +#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH (1 << 2) + +/** * @} */ @@ -4377,13 +4548,13 @@ AVPacket *av_packet_alloc(void); * @see av_packet_alloc * @see av_packet_ref */ -AVPacket *av_packet_clone(AVPacket *src); +AVPacket *av_packet_clone(const AVPacket *src); /** * Free the packet, if the packet is reference counted, it will be * unreferenced first. * - * @param packet packet to be freed. The pointer will be set to NULL. + * @param pkt packet to be freed. The pointer will be set to NULL. * @note passing NULL is a no-op. */ void av_packet_free(AVPacket **pkt); @@ -4452,14 +4623,20 @@ int av_dup_packet(AVPacket *pkt); * Copy packet, including contents * * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_ref */ +attribute_deprecated int av_copy_packet(AVPacket *dst, const AVPacket *src); /** * Copy packet side data * * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_copy_props */ +attribute_deprecated int av_copy_packet_side_data(AVPacket *dst, const AVPacket *src); /** @@ -4518,12 +4695,16 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType 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, +uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size); +#if FF_API_MERGE_SD_API +attribute_deprecated int av_packet_merge_side_data(AVPacket *pkt); +attribute_deprecated int av_packet_split_side_data(AVPacket *pkt); +#endif const char *av_packet_side_data_name(enum AVPacketSideDataType type); @@ -4823,13 +5004,13 @@ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, * and reusing a get_buffer written for video codecs would probably perform badly * due to a potentially very different allocation pattern. * - * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input + * 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 subtitles. It is safe to flush even those decoders that are not - * marked with CODEC_CAP_DELAY, then no subtitles will be returned. + * marked with AV_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. @@ -4883,8 +5064,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, * a flush packet. * * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted right now - the packet must be - * resent after trying to read output + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_frame() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). * AVERROR_EOF: the decoder has been flushed, and no new packets can * be sent to it (also returned if more than 1 flush * packet is sent) @@ -4905,7 +5088,7 @@ int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); * * @return * 0: success, a frame was returned - * AVERROR(EAGAIN): output is not available right now - user must try + * AVERROR(EAGAIN): output is not available in this state - user must try * to send new input * AVERROR_EOF: the decoder has been fully flushed, and there will be * no more output frames @@ -4938,8 +5121,10 @@ int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); * avctx->frame_size for all frames except the last. * The final frame may be smaller than avctx->frame_size. * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): input is not accepted right now - the frame must be - * resent after trying to read output packets + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_packet() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). * AVERROR_EOF: the encoder has been flushed, and no new frames can * be sent to it * AVERROR(EINVAL): codec not opened, refcounted_frames not set, it is a @@ -4957,8 +5142,8 @@ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); * encoder. Note that the function will always call * av_frame_unref(frame) before doing anything else. * @return 0 on success, otherwise negative error code: - * AVERROR(EAGAIN): output is not available right now - user must try - * to send input + * AVERROR(EAGAIN): output is not available in the current state - user + * must try to send input * AVERROR_EOF: the encoder has been fully flushed, and there will be * no more output packets * AVERROR(EINVAL): codec not opened, or it is an encoder @@ -5509,22 +5694,14 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, * @{ */ +#if FF_API_GETCHROMA /** - * 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 + * @deprecated Use av_pix_fmt_get_chroma_sub_sample */ +attribute_deprecated void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift); +#endif /** * Return a value representing the fourCC code associated to the @@ -5584,6 +5761,7 @@ attribute_deprecated void avcodec_set_dimensions(AVCodecContext *s, int width, int height); #endif +#if FF_API_TAG_STRING /** * Put a string representing the codec tag codec_tag in buf. * @@ -5592,8 +5770,12 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height); * @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 + * + * @deprecated see av_fourcc_make_string() and av_fourcc2str(). */ +attribute_deprecated size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag); +#endif void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); @@ -5706,7 +5888,7 @@ int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes); #if FF_API_OLD_BSF typedef struct AVBitStreamFilterContext { void *priv_data; - struct AVBitStreamFilter *filter; + const struct AVBitStreamFilter *filter; AVCodecParserContext *parser; struct AVBitStreamFilterContext *next; /** @@ -5753,12 +5935,15 @@ typedef struct AVBSFContext { void *priv_data; /** - * Parameters of the input stream. Set by the caller before av_bsf_init(). + * Parameters of the input stream. This field is allocated in + * av_bsf_alloc(), it needs to be filled by the caller before + * av_bsf_init(). */ AVCodecParameters *par_in; /** - * Parameters of the output stream. Set by the filter in av_bsf_init(). + * Parameters of the output stream. This field is allocated in + * av_bsf_alloc(), it is set by the filter in av_bsf_init(). */ AVCodecParameters *par_out; @@ -5936,8 +6121,7 @@ int av_bsf_init(AVBSFContext *ctx); * av_bsf_receive_packet() repeatedly until it returns AVERROR(EAGAIN) or * AVERROR_EOF. * - * @param pkt the packet to filter. pkt must contain some payload (i.e data or - * side data must be present in pkt). The bitstream filter will take ownership of + * @param pkt the packet to filter. The bitstream filter will take ownership of * the packet and reset the contents of pkt. pkt is not touched if an error occurs. * This parameter may be NULL, which signals the end of the stream (i.e. no more * packets will be sent). That will cause the filter to output any packets it diff --git a/media/ffvpx/libavcodec/avdct.h b/media/ffvpx/libavcodec/avdct.h deleted file mode 100644 index 272422e44..000000000 --- a/media/ffvpx/libavcodec/avdct.h +++ /dev/null @@ -1,84 +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 - */ - -#ifndef AVCODEC_AVDCT_H -#define AVCODEC_AVDCT_H - -#include "libavutil/opt.h" - -/** - * AVDCT context. - * @note function pointers can be NULL if the specific features have been - * disabled at build time. - */ -typedef struct AVDCT { - const AVClass *av_class; - - void (*idct)(int16_t *block /* align 16 */); - - /** - * IDCT input permutation. - * Several optimized IDCTs need a permutated input (relative to the - * normal order of the reference IDCT). - * This permutation must be performed before the idct_put/add. - * Note, normally this can be merged with the zigzag/alternate scan<br> - * An example to avoid confusion: - * - (->decode coeffs -> zigzag reorder -> dequant -> reference IDCT -> ...) - * - (x -> reference DCT -> reference IDCT -> x) - * - (x -> reference DCT -> simple_mmx_perm = idct_permutation - * -> simple_idct_mmx -> x) - * - (-> decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant - * -> simple_idct_mmx -> ...) - */ - uint8_t idct_permutation[64]; - - void (*fdct)(int16_t *block /* align 16 */); - - - /** - * DCT algorithm. - * must use AVOptions to set this field. - */ - int dct_algo; - - /** - * IDCT algorithm. - * must use AVOptions to set this field. - */ - int idct_algo; - - void (*get_pixels)(int16_t *block /* align 16 */, - const uint8_t *pixels /* align 8 */, - ptrdiff_t line_size); - - int bits_per_sample; -} AVDCT; - -/** - * Allocates a AVDCT context. - * This needs to be initialized with avcodec_dct_init() after optionally - * configuring it with AVOptions. - * - * To free it use av_free() - */ -AVDCT *avcodec_dct_alloc(void); -int avcodec_dct_init(AVDCT *); - -const AVClass *avcodec_dct_get_class(void); - -#endif /* AVCODEC_AVDCT_H */ diff --git a/media/ffvpx/libavcodec/avpacket.c b/media/ffvpx/libavcodec/avpacket.c index e5a8bdbe4..d1f4ea9eb 100644 --- a/media/ffvpx/libavcodec/avpacket.c +++ b/media/ffvpx/libavcodec/avpacket.c @@ -247,8 +247,6 @@ failed_alloc: av_packet_unref(pkt); return AVERROR(ENOMEM); } -FF_ENABLE_DEPRECATION_WARNINGS -#endif int av_dup_packet(AVPacket *pkt) { @@ -266,6 +264,8 @@ int av_copy_packet(AVPacket *dst, const AVPacket *src) *dst = *src; return copy_packet_data(dst, src, 0); } +FF_ENABLE_DEPRECATION_WARNINGS +#endif void av_packet_free_side_data(AVPacket *pkt) { @@ -296,9 +296,20 @@ int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size) { AVPacketSideData *tmp; - int elems = pkt->side_data_elems; + int i, elems = pkt->side_data_elems; + + for (i = 0; i < elems; i++) { + AVPacketSideData *sd = &pkt->side_data[i]; + + if (sd->type == type) { + av_free(sd->data); + sd->data = data; + sd->size = size; + return 0; + } + } - if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data)) + if ((unsigned)elems + 1 > AV_PKT_DATA_NB) return AVERROR(ERANGE); tmp = av_realloc(pkt->side_data, (elems + 1) * sizeof(*tmp)); @@ -336,7 +347,7 @@ uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, return data; } -uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, +uint8_t *av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size) { int i; @@ -348,6 +359,8 @@ uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, return pkt->side_data[i].data; } } + if (size) + *size = 0; return NULL; } @@ -372,10 +385,15 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_METADATA_UPDATE: return "Metadata Update"; case AV_PKT_DATA_MPEGTS_STREAM_ID: return "MPEGTS Stream ID"; case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; + case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; + case AV_PKT_DATA_SPHERICAL: return "Spherical Mapping"; + case AV_PKT_DATA_A53_CC: return "A53 Closed Captions"; } return NULL; } +#if FF_API_MERGE_SD_API + #define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL int av_packet_merge_side_data(AVPacket *pkt){ @@ -431,6 +449,9 @@ int av_packet_split_side_data(AVPacket *pkt){ 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); @@ -456,6 +477,35 @@ int av_packet_split_side_data(AVPacket *pkt){ } return 0; } +#endif + +#if FF_API_MERGE_SD +int ff_packet_split_and_drop_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 0; + } + pkt->size = p - pkt->data - size; + av_assert0(pkt->size >= 0); + return 1; + } + return 0; +} +#endif uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size) { @@ -505,7 +555,7 @@ int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **di const uint8_t *key = data; const uint8_t *val = data + strlen(key) + 1; - if (val >= end) + if (val >= end || !*key) return AVERROR_INVALIDDATA; ret = av_dict_set(dict, key, val, 0); @@ -607,7 +657,7 @@ fail: return ret; } -AVPacket *av_packet_clone(AVPacket *src) +AVPacket *av_packet_clone(const AVPacket *src) { AVPacket *ret = av_packet_alloc(); diff --git a/media/ffvpx/libavcodec/bitstream.c b/media/ffvpx/libavcodec/bitstream.c index 562ca1cb8..ed528fe4a 100644 --- a/media/ffvpx/libavcodec/bitstream.c +++ b/media/ffvpx/libavcodec/bitstream.c @@ -28,7 +28,6 @@ * bitstream api. */ -#include "libavutil/atomic.h" #include "libavutil/avassert.h" #include "libavutil/qsort.h" #include "avcodec.h" @@ -99,9 +98,11 @@ void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) case 2: \ v = *(const uint16_t *)ptr; \ break; \ - default: \ + case 4: \ v = *(const uint32_t *)ptr; \ break; \ + default: \ + av_assert1(0); \ } \ } @@ -126,14 +127,6 @@ static int alloc_table(VLC *vlc, int size, int use_static) return index; } -static av_always_inline uint32_t bitswap_32(uint32_t x) -{ - return (uint32_t)ff_reverse[ x & 0xFF] << 24 | - (uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 | - (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 | - (uint32_t)ff_reverse[ x >> 24]; -} - typedef struct VLCcode { uint8_t bits; uint16_t symbol; @@ -183,7 +176,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, n = codes[i].bits; code = codes[i].code; symbol = codes[i].symbol; - ff_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code); + ff_dlog(NULL, "i=%d n=%d code=0x%"PRIx32"\n", i, n, code); if (n <= table_nb_bits) { /* no need to add another table */ j = code >> (32 - table_nb_bits); @@ -264,7 +257,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, 'bits' or 'codes' tables. 'xxx_size' : gives the number of bytes of each entry of the 'bits' - or 'codes' tables. + or 'codes' tables. Currently 1,2 and 4 are supported. 'wrap' and 'size' make it possible to use any memory configuration and types (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables. @@ -317,7 +310,8 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, } \ GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \ if (buf[j].code >= (1LL<<buf[j].bits)) { \ - av_log(NULL, AV_LOG_ERROR, "Invalid code %x for %d in init_vlc\n", buf[j].code, i);\ + av_log(NULL, AV_LOG_ERROR, "Invalid code %"PRIx32" for %d in " \ + "init_vlc\n", buf[j].code, i); \ if (!(flags & INIT_VLC_USE_NEW_STATIC)) \ av_free(buf); \ return -1; \ diff --git a/media/ffvpx/libavcodec/bitstream_filter.c b/media/ffvpx/libavcodec/bitstream_filter.c new file mode 100644 index 000000000..8599b90d4 --- /dev/null +++ b/media/ffvpx/libavcodec/bitstream_filter.c @@ -0,0 +1,185 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@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 "avcodec.h" +#include "libavutil/internal.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" + +#if FF_API_OLD_BSF +FF_DISABLE_DEPRECATION_WARNINGS + +AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f) +{ + const AVBitStreamFilter *filter = NULL; + void *opaque = NULL; + + while (filter != f) + filter = av_bsf_next(&opaque); + + return av_bsf_next(&opaque); +} + +void av_register_bitstream_filter(AVBitStreamFilter *bsf) +{ +} + +typedef struct BSFCompatContext { + AVBSFContext *ctx; + int extradata_updated; +} BSFCompatContext; + +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) +{ + AVBitStreamFilterContext *ctx = NULL; + BSFCompatContext *priv = NULL; + const AVBitStreamFilter *bsf; + + bsf = av_bsf_get_by_name(name); + if (!bsf) + return NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + goto fail; + + + ctx->filter = bsf; + ctx->priv_data = priv; + + return ctx; + +fail: + if (priv) + av_bsf_free(&priv->ctx); + av_freep(&priv); + av_freep(&ctx); + return NULL; +} + +void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) +{ + BSFCompatContext *priv; + + if (!bsfc) + return; + + priv = bsfc->priv_data; + + av_bsf_free(&priv->ctx); + av_freep(&bsfc->priv_data); + av_free(bsfc); +} + +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe) +{ + BSFCompatContext *priv = bsfc->priv_data; + AVPacket pkt = { 0 }; + int ret; + + if (!priv->ctx) { + ret = av_bsf_alloc(bsfc->filter, &priv->ctx); + if (ret < 0) + return ret; + + ret = avcodec_parameters_from_context(priv->ctx->par_in, avctx); + if (ret < 0) + return ret; + + priv->ctx->time_base_in = avctx->time_base; + + if (bsfc->args && bsfc->filter->priv_class) { + const AVOption *opt = av_opt_next(priv->ctx->priv_data, NULL); + const char * shorthand[2] = {NULL}; + + if (opt) + shorthand[0] = opt->name; + + ret = av_opt_set_from_string(priv->ctx->priv_data, bsfc->args, shorthand, "=", ":"); + if (ret < 0) + return ret; + } + + ret = av_bsf_init(priv->ctx); + if (ret < 0) + return ret; + } + + pkt.data = buf; + pkt.size = buf_size; + + ret = av_bsf_send_packet(priv->ctx, &pkt); + if (ret < 0) + return ret; + + *poutbuf = NULL; + *poutbuf_size = 0; + + ret = av_bsf_receive_packet(priv->ctx, &pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return 0; + else if (ret < 0) + return ret; + + *poutbuf = av_malloc(pkt.size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*poutbuf) { + av_packet_unref(&pkt); + return AVERROR(ENOMEM); + } + + *poutbuf_size = pkt.size; + memcpy(*poutbuf, pkt.data, pkt.size); + + av_packet_unref(&pkt); + + /* drain all the remaining packets we cannot return */ + while (ret >= 0) { + ret = av_bsf_receive_packet(priv->ctx, &pkt); + av_packet_unref(&pkt); + } + + if (!priv->extradata_updated) { + /* update extradata in avctx from the output codec parameters */ + if (priv->ctx->par_out->extradata_size && (!args || !strstr(args, "private_spspps_buf"))) { + av_freep(&avctx->extradata); + avctx->extradata_size = 0; + avctx->extradata = av_mallocz(priv->ctx->par_out->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + memcpy(avctx->extradata, priv->ctx->par_out->extradata, priv->ctx->par_out->extradata_size); + avctx->extradata_size = priv->ctx->par_out->extradata_size; + } + + priv->extradata_updated = 1; + } + + return 1; +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif diff --git a/media/ffvpx/libavcodec/bitstream_filters.c b/media/ffvpx/libavcodec/bitstream_filters.c new file mode 100644 index 000000000..ce34de640 --- /dev/null +++ b/media/ffvpx/libavcodec/bitstream_filters.c @@ -0,0 +1,91 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General 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/common.h" +#include "libavutil/log.h" + +#include "avcodec.h" +#include "bsf.h" + +extern const AVBitStreamFilter ff_aac_adtstoasc_bsf; +extern const AVBitStreamFilter ff_chomp_bsf; +extern const AVBitStreamFilter ff_dump_extradata_bsf; +extern const AVBitStreamFilter ff_dca_core_bsf; +extern const AVBitStreamFilter ff_extract_extradata_bsf; +extern const AVBitStreamFilter ff_h264_mp4toannexb_bsf; +extern const AVBitStreamFilter ff_hevc_mp4toannexb_bsf; +extern const AVBitStreamFilter ff_imx_dump_header_bsf; +extern const AVBitStreamFilter ff_mjpeg2jpeg_bsf; +extern const AVBitStreamFilter ff_mjpega_dump_header_bsf; +extern const AVBitStreamFilter ff_mp3_header_decompress_bsf; +extern const AVBitStreamFilter ff_mpeg4_unpack_bframes_bsf; +extern const AVBitStreamFilter ff_mov2textsub_bsf; +extern const AVBitStreamFilter ff_noise_bsf; +extern const AVBitStreamFilter ff_null_bsf; +extern const AVBitStreamFilter ff_remove_extradata_bsf; +extern const AVBitStreamFilter ff_text2movsub_bsf; +extern const AVBitStreamFilter ff_vp9_raw_reorder_bsf; +extern const AVBitStreamFilter ff_vp9_superframe_bsf; +extern const AVBitStreamFilter ff_vp9_superframe_split_bsf; + +#include "libavcodec/bsf_list.c" + +const AVBitStreamFilter *av_bsf_next(void **opaque) +{ + uintptr_t i = (uintptr_t)*opaque; + const AVBitStreamFilter *f = bitstream_filters[i]; + + if (f) + *opaque = (void*)(i + 1); + + return f; +} + +const AVBitStreamFilter *av_bsf_get_by_name(const char *name) +{ + int i; + + for (i = 0; bitstream_filters[i]; i++) { + const AVBitStreamFilter *f = bitstream_filters[i]; + if (!strcmp(f->name, name)) + return f; + } + + return NULL; +} + +const AVClass *ff_bsf_child_class_next(const AVClass *prev) +{ + int i; + + /* find the filter that corresponds to prev */ + for (i = 0; prev && bitstream_filters[i]; i++) { + if (bitstream_filters[i]->priv_class == prev) { + i++; + break; + } + } + + /* find next filter with priv options */ + for (; bitstream_filters[i]; i++) + if (bitstream_filters[i]->priv_class) + return bitstream_filters[i]->priv_class; + return NULL; +} diff --git a/media/ffvpx/libavcodec/blockdsp.h b/media/ffvpx/libavcodec/blockdsp.h index 95e1d0f32..6e27a02ba 100644 --- a/media/ffvpx/libavcodec/blockdsp.h +++ b/media/ffvpx/libavcodec/blockdsp.h @@ -19,6 +19,7 @@ #ifndef AVCODEC_BLOCKDSP_H #define AVCODEC_BLOCKDSP_H +#include <stddef.h> #include <stdint.h> #include "avcodec.h" @@ -29,7 +30,7 @@ * h for op_pixels_func is limited to { width / 2, width }, * but never larger than 16 and never smaller than 4. */ typedef void (*op_fill_func)(uint8_t *block /* align width (8 or 16) */, - uint8_t value, int line_size, int h); + uint8_t value, ptrdiff_t line_size, int h); typedef struct BlockDSPContext { void (*clear_block)(int16_t *block /* align 16 */); diff --git a/media/ffvpx/libavcodec/bsf.c b/media/ffvpx/libavcodec/bsf.c new file mode 100644 index 000000000..38b423101 --- /dev/null +++ b/media/ffvpx/libavcodec/bsf.c @@ -0,0 +1,542 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General 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/log.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" + +#include "avcodec.h" +#include "bsf.h" + +struct AVBSFInternal { + AVPacket *buffer_pkt; + int eof; +}; + +void av_bsf_free(AVBSFContext **pctx) +{ + AVBSFContext *ctx; + + if (!pctx || !*pctx) + return; + ctx = *pctx; + + if (ctx->filter->close) + ctx->filter->close(ctx); + if (ctx->filter->priv_class && ctx->priv_data) + av_opt_free(ctx->priv_data); + + av_opt_free(ctx); + + av_packet_free(&ctx->internal->buffer_pkt); + av_freep(&ctx->internal); + av_freep(&ctx->priv_data); + + avcodec_parameters_free(&ctx->par_in); + avcodec_parameters_free(&ctx->par_out); + + av_freep(pctx); +} + +static void *bsf_child_next(void *obj, void *prev) +{ + AVBSFContext *ctx = obj; + if (!prev && ctx->filter->priv_class) + return ctx->priv_data; + return NULL; +} + +static const AVClass bsf_class = { + .class_name = "AVBSFContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, + .child_next = bsf_child_next, + .child_class_next = ff_bsf_child_class_next, +}; + +const AVClass *av_bsf_get_class(void) +{ + return &bsf_class; +} + +int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx) +{ + AVBSFContext *ctx; + int ret; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return AVERROR(ENOMEM); + + ctx->av_class = &bsf_class; + ctx->filter = filter; + + ctx->par_in = avcodec_parameters_alloc(); + ctx->par_out = avcodec_parameters_alloc(); + if (!ctx->par_in || !ctx->par_out) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ctx->internal->buffer_pkt = av_packet_alloc(); + if (!ctx->internal->buffer_pkt) { + ret = AVERROR(ENOMEM); + goto fail; + } + + av_opt_set_defaults(ctx); + + /* allocate priv data and init private options */ + if (filter->priv_data_size) { + ctx->priv_data = av_mallocz(filter->priv_data_size); + if (!ctx->priv_data) { + ret = AVERROR(ENOMEM); + goto fail; + } + if (filter->priv_class) { + *(const AVClass **)ctx->priv_data = filter->priv_class; + av_opt_set_defaults(ctx->priv_data); + } + } + + *pctx = ctx; + return 0; +fail: + av_bsf_free(&ctx); + return ret; +} + +int av_bsf_init(AVBSFContext *ctx) +{ + int ret, i; + + /* check that the codec is supported */ + if (ctx->filter->codec_ids) { + for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) + if (ctx->par_in->codec_id == ctx->filter->codec_ids[i]) + break; + if (ctx->filter->codec_ids[i] == AV_CODEC_ID_NONE) { + const AVCodecDescriptor *desc = avcodec_descriptor_get(ctx->par_in->codec_id); + av_log(ctx, AV_LOG_ERROR, "Codec '%s' (%d) is not supported by the " + "bitstream filter '%s'. Supported codecs are: ", + desc ? desc->name : "unknown", ctx->par_in->codec_id, ctx->filter->name); + for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) { + desc = avcodec_descriptor_get(ctx->filter->codec_ids[i]); + av_log(ctx, AV_LOG_ERROR, "%s (%d) ", + desc ? desc->name : "unknown", ctx->filter->codec_ids[i]); + } + av_log(ctx, AV_LOG_ERROR, "\n"); + return AVERROR(EINVAL); + } + } + + /* initialize output parameters to be the same as input + * init below might overwrite that */ + ret = avcodec_parameters_copy(ctx->par_out, ctx->par_in); + if (ret < 0) + return ret; + + ctx->time_base_out = ctx->time_base_in; + + if (ctx->filter->init) { + ret = ctx->filter->init(ctx); + if (ret < 0) + return ret; + } + + return 0; +} + +int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt) +{ + if (!pkt || (!pkt->data && !pkt->side_data_elems)) { + ctx->internal->eof = 1; + return 0; + } + + if (ctx->internal->eof) { + av_log(ctx, AV_LOG_ERROR, "A non-NULL packet sent after an EOF.\n"); + return AVERROR(EINVAL); + } + + if (ctx->internal->buffer_pkt->data || + ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + av_packet_move_ref(ctx->internal->buffer_pkt, pkt); + + return 0; +} + +int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt) +{ + return ctx->filter->filter(ctx, pkt); +} + +int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt) +{ + AVBSFInternal *in = ctx->internal; + AVPacket *tmp_pkt; + + if (in->eof) + return AVERROR_EOF; + + if (!ctx->internal->buffer_pkt->data && + !ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + tmp_pkt = av_packet_alloc(); + if (!tmp_pkt) + return AVERROR(ENOMEM); + + *pkt = ctx->internal->buffer_pkt; + ctx->internal->buffer_pkt = tmp_pkt; + + return 0; +} + +int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt) +{ + AVBSFInternal *in = ctx->internal; + + if (in->eof) + return AVERROR_EOF; + + if (!ctx->internal->buffer_pkt->data && + !ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + av_packet_move_ref(pkt, ctx->internal->buffer_pkt); + + return 0; +} + +typedef struct BSFListContext { + const AVClass *class; + + AVBSFContext **bsfs; + int nb_bsfs; + + unsigned idx; // index of currently processed BSF + unsigned flushed_idx; // index of BSF being flushed + + char * item_name; +} BSFListContext; + + +static int bsf_list_init(AVBSFContext *bsf) +{ + BSFListContext *lst = bsf->priv_data; + int ret, i; + const AVCodecParameters *cod_par = bsf->par_in; + AVRational tb = bsf->time_base_in; + + for (i = 0; i < lst->nb_bsfs; ++i) { + ret = avcodec_parameters_copy(lst->bsfs[i]->par_in, cod_par); + if (ret < 0) + goto fail; + + lst->bsfs[i]->time_base_in = tb; + + ret = av_bsf_init(lst->bsfs[i]); + if (ret < 0) + goto fail; + + cod_par = lst->bsfs[i]->par_out; + tb = lst->bsfs[i]->time_base_out; + } + + bsf->time_base_out = tb; + ret = avcodec_parameters_copy(bsf->par_out, cod_par); + +fail: + return ret; +} + +static int bsf_list_filter(AVBSFContext *bsf, AVPacket *out) +{ + BSFListContext *lst = bsf->priv_data; + int ret; + + if (!lst->nb_bsfs) + return ff_bsf_get_packet_ref(bsf, out); + + while (1) { + if (lst->idx > lst->flushed_idx) { + ret = av_bsf_receive_packet(lst->bsfs[lst->idx-1], out); + if (ret == AVERROR(EAGAIN)) { + /* no more packets from idx-1, try with previous */ + ret = 0; + lst->idx--; + continue; + } else if (ret == AVERROR_EOF) { + /* filter idx-1 is done, continue with idx...nb_bsfs */ + lst->flushed_idx = lst->idx; + continue; + }else if (ret < 0) { + /* filtering error */ + break; + } + } else { + ret = ff_bsf_get_packet_ref(bsf, out); + if (ret == AVERROR_EOF) { + lst->idx = lst->flushed_idx; + } else if (ret < 0) + break; + } + + if (lst->idx < lst->nb_bsfs) { + AVPacket *pkt; + if (ret == AVERROR_EOF && lst->idx == lst->flushed_idx) { + /* ff_bsf_get_packet_ref returned EOF and idx is first + * filter of yet not flushed filter chain */ + pkt = NULL; + } else { + pkt = out; + } + ret = av_bsf_send_packet(lst->bsfs[lst->idx], pkt); + if (ret < 0) + break; + lst->idx++; + } else { + /* The end of filter chain, break to return result */ + break; + } + } + + if (ret < 0) + av_packet_unref(out); + + return ret; +} + +static void bsf_list_close(AVBSFContext *bsf) +{ + BSFListContext *lst = bsf->priv_data; + int i; + + for (i = 0; i < lst->nb_bsfs; ++i) + av_bsf_free(&lst->bsfs[i]); + av_freep(&lst->bsfs); + av_freep(&lst->item_name); +} + +static const char *bsf_list_item_name(void *ctx) +{ + static const char *null_filter_name = "null"; + AVBSFContext *bsf_ctx = ctx; + BSFListContext *lst = bsf_ctx->priv_data; + + if (!lst->nb_bsfs) + return null_filter_name; + + if (!lst->item_name) { + int i; + AVBPrint bp; + av_bprint_init(&bp, 16, 128); + + av_bprintf(&bp, "bsf_list("); + for (i = 0; i < lst->nb_bsfs; i++) + av_bprintf(&bp, i ? ",%s" : "%s", lst->bsfs[i]->filter->name); + av_bprintf(&bp, ")"); + + av_bprint_finalize(&bp, &lst->item_name); + } + + return lst->item_name; +} + +static const AVClass bsf_list_class = { + .class_name = "bsf_list", + .item_name = bsf_list_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVBitStreamFilter ff_list_bsf = { + .name = "bsf_list", + .priv_data_size = sizeof(BSFListContext), + .priv_class = &bsf_list_class, + .init = bsf_list_init, + .filter = bsf_list_filter, + .close = bsf_list_close, +}; + +struct AVBSFList { + AVBSFContext **bsfs; + int nb_bsfs; +}; + +AVBSFList *av_bsf_list_alloc(void) +{ + return av_mallocz(sizeof(AVBSFList)); +} + +void av_bsf_list_free(AVBSFList **lst) +{ + int i; + + if (!*lst) + return; + + for (i = 0; i < (*lst)->nb_bsfs; ++i) + av_bsf_free(&(*lst)->bsfs[i]); + av_free((*lst)->bsfs); + av_freep(lst); +} + +int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf) +{ + return av_dynarray_add_nofree(&lst->bsfs, &lst->nb_bsfs, bsf); +} + +int av_bsf_list_append2(AVBSFList *lst, const char *bsf_name, AVDictionary ** options) +{ + int ret; + const AVBitStreamFilter *filter; + AVBSFContext *bsf; + + filter = av_bsf_get_by_name(bsf_name); + if (!filter) + return AVERROR_BSF_NOT_FOUND; + + ret = av_bsf_alloc(filter, &bsf); + if (ret < 0) + return ret; + + if (options) { + ret = av_opt_set_dict2(bsf, options, AV_OPT_SEARCH_CHILDREN); + if (ret < 0) + goto end; + } + + ret = av_bsf_list_append(lst, bsf); + +end: + if (ret < 0) + av_bsf_free(&bsf); + + return ret; +} + +int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf) +{ + int ret = 0; + BSFListContext *ctx; + + if ((*lst)->nb_bsfs == 1) { + *bsf = (*lst)->bsfs[0]; + av_freep(&(*lst)->bsfs); + (*lst)->nb_bsfs = 0; + goto end; + } + + ret = av_bsf_alloc(&ff_list_bsf, bsf); + if (ret < 0) + return ret; + + ctx = (*bsf)->priv_data; + + ctx->bsfs = (*lst)->bsfs; + ctx->nb_bsfs = (*lst)->nb_bsfs; + +end: + av_freep(lst); + return ret; +} + +static int bsf_parse_single(const char *str, AVBSFList *bsf_lst) +{ + char *bsf_name, *bsf_options_str, *buf; + AVDictionary *bsf_options = NULL; + int ret = 0; + + if (!(buf = av_strdup(str))) + return AVERROR(ENOMEM); + + bsf_name = av_strtok(buf, "=", &bsf_options_str); + if (!bsf_name) { + ret = AVERROR(EINVAL); + goto end; + } + + if (bsf_options_str) { + ret = av_dict_parse_string(&bsf_options, bsf_options_str, "=", ":", 0); + if (ret < 0) + goto end; + } + + ret = av_bsf_list_append2(bsf_lst, bsf_name, &bsf_options); + + av_dict_free(&bsf_options); +end: + av_free(buf); + return ret; +} + +int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf_lst) +{ + AVBSFList *lst; + char *bsf_str, *buf, *dup, *saveptr; + int ret; + + if (!str) + return av_bsf_get_null_filter(bsf_lst); + + lst = av_bsf_list_alloc(); + if (!lst) + return AVERROR(ENOMEM); + + if (!(dup = buf = av_strdup(str))) { + ret = AVERROR(ENOMEM); + goto end; + } + + while (1) { + bsf_str = av_strtok(buf, ",", &saveptr); + if (!bsf_str) + break; + + ret = bsf_parse_single(bsf_str, lst); + if (ret < 0) + goto end; + + buf = NULL; + } + + ret = av_bsf_list_finalize(&lst, bsf_lst); +end: + if (ret < 0) + av_bsf_list_free(&lst); + av_free(dup); + return ret; +} + +int av_bsf_get_null_filter(AVBSFContext **bsf) +{ + return av_bsf_alloc(&ff_list_bsf, bsf); +} diff --git a/media/ffvpx/libavcodec/bsf_list.c b/media/ffvpx/libavcodec/bsf_list.c new file mode 100644 index 000000000..d31ece942 --- /dev/null +++ b/media/ffvpx/libavcodec/bsf_list.c @@ -0,0 +1,3 @@ +static const AVBitStreamFilter * const bitstream_filters[] = { + &ff_null_bsf, + NULL }; diff --git a/media/ffvpx/libavcodec/bytestream.h b/media/ffvpx/libavcodec/bytestream.h index 7c05ea6cf..7be7fc22f 100644 --- a/media/ffvpx/libavcodec/bytestream.h +++ b/media/ffvpx/libavcodec/bytestream.h @@ -94,7 +94,7 @@ DEF(unsigned int, be24, 3, AV_RB24, AV_WB24) DEF(unsigned int, be16, 2, AV_RB16, AV_WB16) DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8) -#if HAVE_BIGENDIAN +#if AV_HAVE_BIGENDIAN # define bytestream2_get_ne16 bytestream2_get_be16 # define bytestream2_get_ne24 bytestream2_get_be24 # define bytestream2_get_ne32 bytestream2_get_be32 diff --git a/media/ffvpx/libavcodec/codec_desc.c b/media/ffvpx/libavcodec/codec_desc.c index d862cc8f6..6a13bbbf0 100644 --- a/media/ffvpx/libavcodec/codec_desc.c +++ b/media/ffvpx/libavcodec/codec_desc.c @@ -170,6 +170,14 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_LOSSY, }, { + .id = AV_CODEC_ID_SVG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "svg", + .long_name = NULL_IF_CONFIG_SMALL("Scalable Vector Graphics"), + .props = AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/svg+xml"), + }, + { .id = AV_CODEC_ID_SVQ1, .type = AVMEDIA_TYPE_VIDEO, .name = "svq1", @@ -520,7 +528,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_VIDEO, .name = "fraps", .long_name = NULL_IF_CONFIG_SMALL("Fraps"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_TRUEMOTION2, @@ -665,6 +673,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "dnxhd", .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + .profiles = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles), }, { .id = AV_CODEC_ID_THP, @@ -1106,7 +1115,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_VIDEO, .name = "y41p", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_ESCAPE130, @@ -1120,56 +1129,56 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_VIDEO, .name = "avrp", .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_012V, .type = AVMEDIA_TYPE_VIDEO, .name = "012v", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_AVUI, .type = AVMEDIA_TYPE_VIDEO, .name = "avui", .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_AYUV, .type = AVMEDIA_TYPE_VIDEO, .name = "ayuv", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_TARGA_Y216, .type = AVMEDIA_TYPE_VIDEO, .name = "targa_y216", .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_V308, .type = AVMEDIA_TYPE_VIDEO, .name = "v308", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_V408, .type = AVMEDIA_TYPE_VIDEO, .name = "v408", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_YUV4, .type = AVMEDIA_TYPE_VIDEO, .name = "yuv4", .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), - .props = AV_CODEC_PROP_INTRA_ONLY, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_AVRN, @@ -1272,7 +1281,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_HAP, .type = AVMEDIA_TYPE_VIDEO, .name = "hap", - .long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap decoder"), + .long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, }, { @@ -1290,6 +1299,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_LOSSLESS, }, { + .id = AV_CODEC_ID_SPEEDHQ, + .type = AVMEDIA_TYPE_VIDEO, + .name = "speedhq", + .long_name = NULL_IF_CONFIG_SMALL("NewTek SpeedHQ"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { .id = AV_CODEC_ID_WRAPPED_AVFRAME, .type = AVMEDIA_TYPE_VIDEO, .name = "wrapped_avframe", @@ -1303,6 +1319,104 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("innoHeim/Rsupport Screen Capture Codec"), .props = AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_MAGICYUV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "magicyuv", + .long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_TRUEMOTION2RT, + .type = AVMEDIA_TYPE_VIDEO, + .name = "truemotion2rt", + .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CFHD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cfhd", + .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SHEERVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sheervideo", + .long_name = NULL_IF_CONFIG_SMALL("BitJazz SheerVideo"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_YLC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ylc", + .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PIXLET, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pixlet", + .long_name = NULL_IF_CONFIG_SMALL("Apple Pixlet"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FMVC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fmvc", + .long_name = NULL_IF_CONFIG_SMALL("FM Screen Capture Codec"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SCPR, + .type = AVMEDIA_TYPE_VIDEO, + .name = "scpr", + .long_name = NULL_IF_CONFIG_SMALL("ScreenPressor"), + .props = AV_CODEC_PROP_LOSSLESS | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CLEARVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "clearvideo", + .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "av1", + .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_BITPACKED, + .type = AVMEDIA_TYPE_VIDEO, + .name = "bitpacked", + .long_name = NULL_IF_CONFIG_SMALL("Bitpacked"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MSCC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mscc", + .long_name = NULL_IF_CONFIG_SMALL("Mandsoft Screen Capture Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SRGC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "srgc", + .long_name = NULL_IF_CONFIG_SMALL("Screen Recorder Gold Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_GDV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "gdv", + .long_name = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"), + .props = AV_CODEC_PROP_LOSSY, + }, /* image codecs */ { @@ -1350,6 +1464,13 @@ static const AVCodecDescriptor codec_descriptors[] = { AV_CODEC_PROP_LOSSLESS, }, { + .id = AV_CODEC_ID_FITS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fits", + .long_name = NULL_IF_CONFIG_SMALL("FITS (Flexible Image Transport System)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { .id = AV_CODEC_ID_GIF, .type = AVMEDIA_TYPE_VIDEO, .name = "gif", @@ -1425,6 +1546,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { + .id = AV_CODEC_ID_PSD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "psd", + .long_name = NULL_IF_CONFIG_SMALL("Photoshop PSD file"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { .id = AV_CODEC_ID_PTX, .type = AVMEDIA_TYPE_VIDEO, .name = "ptx", @@ -1511,6 +1639,15 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "xbm", .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xbitmap"), + }, + { + .id = AV_CODEC_ID_XPM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xpm", + .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xpixmap"), }, { .id = AV_CODEC_ID_XWD, @@ -1528,41 +1665,6 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_LOSSLESS, .mime_types= MT("image/png"), }, - { - .id = AV_CODEC_ID_CFHD, - .type = AVMEDIA_TYPE_VIDEO, - .name = "cfhd", - .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), - .props = AV_CODEC_PROP_LOSSY, - }, - { - .id = AV_CODEC_ID_TRUEMOTION2RT, - .type = AVMEDIA_TYPE_VIDEO, - .name = "truemotion2rt", - .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"), - .props = AV_CODEC_PROP_LOSSY, - }, - { - .id = AV_CODEC_ID_MAGICYUV, - .type = AVMEDIA_TYPE_VIDEO, - .name = "magicyuv", - .long_name = NULL_IF_CONFIG_SMALL("MagicYUV Lossless Video"), - .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, - }, - { - .id = AV_CODEC_ID_SHEERVIDEO, - .type = AVMEDIA_TYPE_VIDEO, - .name = "sheervideo", - .long_name = NULL_IF_CONFIG_SMALL("BitJazz SheerVideo"), - .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, - }, - { - .id = AV_CODEC_ID_YLC, - .type = AVMEDIA_TYPE_VIDEO, - .name = "ylc", - .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"), - .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, - }, /* various PCM "codecs" */ { @@ -1636,6 +1738,20 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_LOSSLESS, }, { + .id = AV_CODEC_ID_PCM_S64LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s64le", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 64-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S64BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s64be", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 64-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { .id = AV_CODEC_ID_PCM_U32LE, .type = AVMEDIA_TYPE_AUDIO, .name = "pcm_u32le", @@ -1727,6 +1843,20 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_LOSSLESS, }, { + .id = AV_CODEC_ID_PCM_F16LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f16le", + .long_name = NULL_IF_CONFIG_SMALL("PCM 16.8 floating point little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_F24LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f24le", + .long_name = NULL_IF_CONFIG_SMALL("PCM 24.0 floating point little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { .id = AV_CODEC_ID_PCM_F32BE, .type = AVMEDIA_TYPE_AUDIO, .name = "pcm_f32be", @@ -2133,6 +2263,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("DPCM Squareroot-Delta-Exact"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_GREMLIN_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "gremlin_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Gremlin"), + .props = AV_CODEC_PROP_LOSSY, + }, /* audio codecs */ { @@ -2226,7 +2363,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "flac", .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_MP3ADU, @@ -2254,7 +2391,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "alac", .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_WESTWOOD_SND1, @@ -2281,7 +2418,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .id = AV_CODEC_ID_COOK, .type = AVMEDIA_TYPE_AUDIO, .name = "cook", - .long_name = NULL_IF_CONFIG_SMALL("Cook / Cooker / Goanna (RealAudio G2)"), + .long_name = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"), .props = AV_CODEC_PROP_LOSSY, }, { @@ -2296,7 +2433,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "tta", .long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_SMACKAUDIO, @@ -2317,7 +2454,8 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "wavpack", .long_name = NULL_IF_CONFIG_SMALL("WavPack"), - .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | + AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_DSICINAUDIO, @@ -2427,6 +2565,20 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_LOSSY, }, { + .id = AV_CODEC_ID_ATRAC3PAL, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac3pal", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ AL (Adaptive TRansform Acoustic Coding 3+ Advanced Lossless)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ATRAC3AL, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac3al", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 AL (Adaptive TRansform Acoustic Coding 3 Advanced Lossless)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { .id = AV_CODEC_ID_EAC3, .type = AVMEDIA_TYPE_AUDIO, .name = "eac3", @@ -2526,6 +2678,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_LOSSY, }, { + .id = AV_CODEC_ID_DOLBY_E, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dolby_e", + .long_name = NULL_IF_CONFIG_SMALL("Dolby E"), + .props = AV_CODEC_PROP_LOSSY, + }, + { .id = AV_CODEC_ID_G729, .type = AVMEDIA_TYPE_AUDIO, .name = "g729", @@ -2611,7 +2770,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "tak", .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), - .props = AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_METASOUND, @@ -2949,6 +3108,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, + { + .id = AV_CODEC_ID_SCTE_35, + .type = AVMEDIA_TYPE_DATA, + .name = "scte_35", + .long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), + }, /* deprecated codec ids */ }; diff --git a/media/ffvpx/libavcodec/dct.h b/media/ffvpx/libavcodec/dct.h deleted file mode 100644 index 05297ba9d..000000000 --- a/media/ffvpx/libavcodec/dct.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (I)DCT Transforms - * Copyright (c) 2009 Peter Ross <pross@xvid.org> - * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> - * Copyright (c) 2010 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if !defined(AVCODEC_DCT_H) && (!defined(FFT_FLOAT) || FFT_FLOAT) -#define AVCODEC_DCT_H - -#include <stdint.h> - -#include "rdft.h" - -struct DCTContext { - int nbits; - int inverse; - RDFTContext rdft; - const float *costab; - FFTSample *csc2; - void (*dct_calc)(struct DCTContext *s, FFTSample *data); - void (*dct32)(FFTSample *out, const FFTSample *in); -}; - -/** - * Set up DCT. - * @param nbits size of the input array: - * (1 << nbits) for DCT-II, DCT-III and DST-I - * (1 << nbits) + 1 for DCT-I - * - * @note the first element of the input of DST-I is ignored - */ -int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType type); -void ff_dct_end (DCTContext *s); - -void ff_dct_init_x86(DCTContext *s); - -void ff_fdct_ifast(int16_t *data); -void ff_fdct_ifast248(int16_t *data); -void ff_jpeg_fdct_islow_8(int16_t *data); -void ff_jpeg_fdct_islow_10(int16_t *data); -void ff_fdct248_islow_8(int16_t *data); -void ff_fdct248_islow_10(int16_t *data); - -void ff_j_rev_dct(int16_t *data); -void ff_j_rev_dct4(int16_t *data); -void ff_j_rev_dct2(int16_t *data); -void ff_j_rev_dct1(int16_t *data); -void ff_jref_idct_put(uint8_t *dest, int line_size, int16_t *block); -void ff_jref_idct_add(uint8_t *dest, int line_size, int16_t *block); - -#endif /* AVCODEC_DCT_H */ diff --git a/media/ffvpx/libavcodec/decode.c b/media/ffvpx/libavcodec/decode.c new file mode 100644 index 000000000..fb1824be1 --- /dev/null +++ b/media/ffvpx/libavcodec/decode.c @@ -0,0 +1,1761 @@ +/* + * generic decoding-related code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> +#include <string.h> + +#include "config.h" + +#if CONFIG_ICONV +# include <iconv.h> +#endif + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/intmath.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "decode.h" +#include "internal.h" +#include "thread.h" + +static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt) +{ + int size = 0, ret; + const uint8_t *data; + uint32_t flags; + int64_t val; + + data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); + if (!data) + return 0; + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { + av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " + "changes, but PARAM_CHANGE side data was sent to it.\n"); + ret = AVERROR(EINVAL); + goto fail2; + } + + if (size < 4) + goto fail; + + flags = bytestream_get_le32(&data); + size -= 4; + + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { + if (size < 4) + goto fail; + val = bytestream_get_le32(&data); + if (val <= 0 || val > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Invalid channel count"); + ret = AVERROR_INVALIDDATA; + goto fail2; + } + avctx->channels = val; + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { + if (size < 8) + goto fail; + avctx->channel_layout = bytestream_get_le64(&data); + size -= 8; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + if (size < 4) + goto fail; + val = bytestream_get_le32(&data); + if (val <= 0 || val > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); + ret = AVERROR_INVALIDDATA; + goto fail2; + } + avctx->sample_rate = val; + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { + if (size < 8) + goto fail; + avctx->width = bytestream_get_le32(&data); + avctx->height = bytestream_get_le32(&data); + size -= 8; + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + goto fail2; + } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); + ret = AVERROR_INVALIDDATA; +fail2: + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } + return 0; +} + +static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) +{ + int ret = 0; + + av_packet_unref(avci->last_pkt_props); + if (pkt) { + ret = av_packet_copy_props(avci->last_pkt_props, pkt); + if (!ret) + avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_init_buffer_info(). + } + return ret; +} + +static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) +{ + int ret; + + /* move the original frame to our backup */ + av_frame_unref(avci->to_free); + av_frame_move_ref(avci->to_free, frame); + + /* now copy everything except the AVBufferRefs back + * note that we make a COPY of the side data, so calling av_frame_free() on + * the caller's frame will work properly */ + ret = av_frame_copy_props(frame, avci->to_free); + if (ret < 0) + return ret; + + memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); + memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); + if (avci->to_free->extended_data != avci->to_free->data) { + int planes = avci->to_free->channels; + int size = planes * sizeof(*frame->extended_data); + + if (!size) { + av_frame_unref(frame); + return AVERROR_BUG; + } + + frame->extended_data = av_malloc(size); + if (!frame->extended_data) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + memcpy(frame->extended_data, avci->to_free->extended_data, + size); + } else + frame->extended_data = frame->data; + + frame->format = avci->to_free->format; + frame->width = avci->to_free->width; + frame->height = avci->to_free->height; + frame->channel_layout = avci->to_free->channel_layout; + frame->nb_samples = avci->to_free->nb_samples; + frame->channels = avci->to_free->channels; + + return 0; +} + +static int bsfs_init(AVCodecContext *avctx) +{ + AVCodecInternal *avci = avctx->internal; + DecodeFilterContext *s = &avci->filter; + const char *bsfs_str; + int ret; + + if (s->nb_bsfs) + return 0; + + bsfs_str = avctx->codec->bsfs ? avctx->codec->bsfs : "null"; + while (bsfs_str && *bsfs_str) { + AVBSFContext **tmp; + const AVBitStreamFilter *filter; + char *bsf; + + bsf = av_get_token(&bsfs_str, ","); + if (!bsf) { + ret = AVERROR(ENOMEM); + goto fail; + } + + filter = av_bsf_get_by_name(bsf); + if (!filter) { + av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s " + "requested by a decoder. This is a bug, please report it.\n", + bsf); + ret = AVERROR_BUG; + av_freep(&bsf); + goto fail; + } + av_freep(&bsf); + + tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs)); + if (!tmp) { + ret = AVERROR(ENOMEM); + goto fail; + } + s->bsfs = tmp; + s->nb_bsfs++; + + ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]); + if (ret < 0) + goto fail; + + if (s->nb_bsfs == 1) { + /* We do not currently have an API for passing the input timebase into decoders, + * but no filters used here should actually need it. + * So we make up some plausible-looking number (the MPEG 90kHz timebase) */ + s->bsfs[s->nb_bsfs - 1]->time_base_in = (AVRational){ 1, 90000 }; + ret = avcodec_parameters_from_context(s->bsfs[s->nb_bsfs - 1]->par_in, + avctx); + } else { + s->bsfs[s->nb_bsfs - 1]->time_base_in = s->bsfs[s->nb_bsfs - 2]->time_base_out; + ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in, + s->bsfs[s->nb_bsfs - 2]->par_out); + } + if (ret < 0) + goto fail; + + ret = av_bsf_init(s->bsfs[s->nb_bsfs - 1]); + if (ret < 0) + goto fail; + } + + return 0; +fail: + ff_decode_bsfs_uninit(avctx); + return ret; +} + +/* try to get one output packet from the filter chain */ +static int bsfs_poll(AVCodecContext *avctx, AVPacket *pkt) +{ + DecodeFilterContext *s = &avctx->internal->filter; + int idx, ret; + + /* start with the last filter in the chain */ + idx = s->nb_bsfs - 1; + while (idx >= 0) { + /* request a packet from the currently selected filter */ + ret = av_bsf_receive_packet(s->bsfs[idx], pkt); + if (ret == AVERROR(EAGAIN)) { + /* no packets available, try the next filter up the chain */ + ret = 0; + idx--; + continue; + } else if (ret < 0 && ret != AVERROR_EOF) { + return ret; + } + + /* got a packet or EOF -- pass it to the caller or to the next filter + * down the chain */ + if (idx == s->nb_bsfs - 1) { + return ret; + } else { + idx++; + ret = av_bsf_send_packet(s->bsfs[idx], ret < 0 ? NULL : pkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Error pre-processing a packet before decoding\n"); + av_packet_unref(pkt); + return ret; + } + } + } + + return AVERROR(EAGAIN); +} + +int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + if (avci->draining) + return AVERROR_EOF; + + ret = bsfs_poll(avctx, pkt); + if (ret == AVERROR_EOF) + avci->draining = 1; + if (ret < 0) + return ret; + + ret = extract_packet_props(avctx->internal, pkt); + if (ret < 0) + goto finish; + + ret = apply_param_change(avctx, pkt); + if (ret < 0) + goto finish; + + if (avctx->codec->receive_frame) + avci->compat_decode_consumed += pkt->size; + + return 0; +finish: + av_packet_unref(pkt); + return ret; +} + +/** + * Attempt to guess proper monotonic timestamps for decoded video frames + * which might have incorrect times. Input timestamps may wrap around, in + * which case the output will as well. + * + * @param pts the pts field of the decoded AVPacket, as passed through + * AVFrame.pts + * @param dts the dts field of the decoded AVPacket + * @return one of the input values, may be AV_NOPTS_VALUE + */ +static int64_t guess_correct_pts(AVCodecContext *ctx, + int64_t reordered_pts, int64_t dts) +{ + int64_t pts = AV_NOPTS_VALUE; + + if (dts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; + ctx->pts_correction_last_dts = dts; + } else if (reordered_pts != AV_NOPTS_VALUE) + ctx->pts_correction_last_dts = reordered_pts; + + if (reordered_pts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; + ctx->pts_correction_last_pts = reordered_pts; + } else if(dts != AV_NOPTS_VALUE) + ctx->pts_correction_last_pts = dts; + + if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) + && reordered_pts != AV_NOPTS_VALUE) + pts = reordered_pts; + else + pts = dts; + + return pts; +} + +/* + * The core of the receive_frame_wrapper for the decoders implementing + * the simple API. Certain decoders might consume partial packets without + * returning any output, so this function needs to be called in a loop until it + * returns EAGAIN. + **/ +static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + DecodeSimpleContext *ds = &avci->ds; + AVPacket *pkt = ds->in_pkt; + // copy to ensure we do not change pkt + AVPacket tmp; + int got_frame, actual_got_frame, did_split; + int ret; + + if (!pkt->data && !avci->draining) { + av_packet_unref(pkt); + ret = ff_decode_get_packet(avctx, pkt); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + // Some codecs (at least wma lossless) will crash when feeding drain packets + // after EOF was signaled. + if (avci->draining_done) + return AVERROR_EOF; + + if (!pkt->data && + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || + avctx->active_thread_type & FF_THREAD_FRAME)) + return AVERROR_EOF; + + tmp = *pkt; +#if FF_API_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS + did_split = avci->compat_decode_partial_size ? + ff_packet_split_and_drop_side_data(&tmp) : + av_packet_split_side_data(&tmp); + + if (did_split) { + ret = extract_packet_props(avctx->internal, &tmp); + if (ret < 0) + return ret; + + ret = apply_param_change(avctx, &tmp); + if (ret < 0) + return ret; + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + got_frame = 0; + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) { + ret = ff_thread_decode_frame(avctx, frame, &got_frame, &tmp); + } else { + ret = avctx->codec->decode(avctx, frame, &got_frame, &tmp); + + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) + frame->pkt_dts = pkt->dts; + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if(!avctx->has_b_frames) + frame->pkt_pos = pkt->pos; + //FIXME these should be under if(!avctx->has_b_frames) + /* get_buffer is supposed to set frame parameters */ + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { + if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + if (!frame->width) frame->width = avctx->width; + if (!frame->height) frame->height = avctx->height; + if (frame->format == AV_PIX_FMT_NONE) frame->format = avctx->pix_fmt; + } + } + } + emms_c(); + actual_got_frame = got_frame; + + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if (frame->flags & AV_FRAME_FLAG_DISCARD) + got_frame = 0; + if (got_frame) + frame->best_effort_timestamp = guess_correct_pts(avctx, + frame->pts, + frame->pkt_dts); + } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + uint8_t *side; + int side_size; + uint32_t discard_padding = 0; + uint8_t skip_reason = 0; + uint8_t discard_reason = 0; + + if (ret >= 0 && got_frame) { + frame->best_effort_timestamp = guess_correct_pts(avctx, + frame->pts, + frame->pkt_dts); + if (frame->format == AV_SAMPLE_FMT_NONE) + frame->format = avctx->sample_fmt; + if (!frame->channel_layout) + frame->channel_layout = avctx->channel_layout; + if (!frame->channels) + frame->channels = avctx->channels; + if (!frame->sample_rate) + frame->sample_rate = avctx->sample_rate; + } + + side= av_packet_get_side_data(avci->last_pkt_props, AV_PKT_DATA_SKIP_SAMPLES, &side_size); + if(side && side_size>=10) { + avctx->internal->skip_samples = AV_RL32(side) * avctx->internal->skip_samples_multiplier; + discard_padding = AV_RL32(side + 4); + av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n", + avctx->internal->skip_samples, (int)discard_padding); + skip_reason = AV_RL8(side + 8); + discard_reason = AV_RL8(side + 9); + } + + if ((frame->flags & AV_FRAME_FLAG_DISCARD) && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + avctx->internal->skip_samples = FFMAX(0, avctx->internal->skip_samples - frame->nb_samples); + got_frame = 0; + } + + if (avctx->internal->skip_samples > 0 && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + if(frame->nb_samples <= avctx->internal->skip_samples){ + got_frame = 0; + avctx->internal->skip_samples -= frame->nb_samples; + av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", + avctx->internal->skip_samples); + } else { + av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples, + frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format); + if(avctx->pkt_timebase.num && avctx->sample_rate) { + int64_t diff_ts = av_rescale_q(avctx->internal->skip_samples, + (AVRational){1, avctx->sample_rate}, + avctx->pkt_timebase); + if(frame->pts!=AV_NOPTS_VALUE) + frame->pts += diff_ts; +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + if(frame->pkt_pts!=AV_NOPTS_VALUE) + frame->pkt_pts += diff_ts; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if(frame->pkt_dts!=AV_NOPTS_VALUE) + frame->pkt_dts += diff_ts; + if (frame->pkt_duration >= diff_ts) + frame->pkt_duration -= diff_ts; + } else { + av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n"); + } + av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n", + avctx->internal->skip_samples, frame->nb_samples); + frame->nb_samples -= avctx->internal->skip_samples; + avctx->internal->skip_samples = 0; + } + } + + if (discard_padding > 0 && discard_padding <= frame->nb_samples && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + if (discard_padding == frame->nb_samples) { + got_frame = 0; + } else { + if(avctx->pkt_timebase.num && avctx->sample_rate) { + int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, + (AVRational){1, avctx->sample_rate}, + avctx->pkt_timebase); + frame->pkt_duration = diff_ts; + } else { + av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n"); + } + av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n", + (int)discard_padding, frame->nb_samples); + frame->nb_samples -= discard_padding; + } + } + + if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL) && got_frame) { + AVFrameSideData *fside = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10); + if (fside) { + AV_WL32(fside->data, avctx->internal->skip_samples); + AV_WL32(fside->data + 4, discard_padding); + AV_WL8(fside->data + 8, skip_reason); + AV_WL8(fside->data + 9, discard_reason); + avctx->internal->skip_samples = 0; + } + } + } +#if FF_API_MERGE_SD + if (did_split) { + av_packet_free_side_data(&tmp); + if(ret == tmp.size) + ret = pkt->size; + } +#endif + + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO && + !avci->showed_multi_packet_warning && + ret >= 0 && ret != pkt->size && !(avctx->codec->capabilities & AV_CODEC_CAP_SUBFRAMES)) { + av_log(avctx, AV_LOG_WARNING, "Multiple frames in a packet.\n"); + avci->showed_multi_packet_warning = 1; + } + + if (!got_frame) + av_frame_unref(frame); + + if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO && !(avctx->flags & AV_CODEC_FLAG_TRUNCATED)) + ret = pkt->size; + +#if FF_API_AVCTX_TIMEBASE + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); +#endif + + /* do not stop draining when actual_got_frame != 0 or ret < 0 */ + /* got_frame == 0 but actual_got_frame != 0 when frame is discarded */ + if (avctx->internal->draining && !actual_got_frame) { + if (ret < 0) { + /* prevent infinite loop if a decoder wrongly always return error on draining */ + /* reasonable nb_errors_max = maximum b frames + thread count */ + int nb_errors_max = 20 + (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME ? + avctx->thread_count : 1); + + if (avci->nb_draining_errors++ >= nb_errors_max) { + av_log(avctx, AV_LOG_ERROR, "Too many errors when draining, this is a bug. " + "Stop draining and force EOF.\n"); + avci->draining_done = 1; + ret = AVERROR_BUG; + } + } else { + avci->draining_done = 1; + } + } + + avci->compat_decode_consumed += ret; + + if (ret >= pkt->size || ret < 0) { + av_packet_unref(pkt); + } else { + int consumed = ret; + + pkt->data += consumed; + pkt->size -= consumed; + avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment. + pkt->pts = AV_NOPTS_VALUE; + pkt->dts = AV_NOPTS_VALUE; + avci->last_pkt_props->pts = AV_NOPTS_VALUE; + avci->last_pkt_props->dts = AV_NOPTS_VALUE; + } + + if (got_frame) + av_assert0(frame->buf[0]); + + return ret < 0 ? ret : 0; +} + +static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + int ret; + + while (!frame->buf[0]) { + ret = decode_simple_internal(avctx, frame); + if (ret < 0) + return ret; + } + + return 0; +} + +static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + av_assert0(!frame->buf[0]); + + if (avctx->codec->receive_frame) + ret = avctx->codec->receive_frame(avctx, frame); + else + ret = decode_simple_receive_frame(avctx, frame); + + if (ret == AVERROR_EOF) + avci->draining_done = 1; + + return ret; +} + +int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->internal->draining) + return AVERROR_EOF; + + if (avpkt && !avpkt->size && avpkt->data) + return AVERROR(EINVAL); + + ret = bsfs_init(avctx); + if (ret < 0) + return ret; + + av_packet_unref(avci->buffer_pkt); + if (avpkt && (avpkt->data || avpkt->side_data_elems)) { + ret = av_packet_ref(avci->buffer_pkt, avpkt); + if (ret < 0) + return ret; + } + + ret = av_bsf_send_packet(avci->filter.bsfs[0], avci->buffer_pkt); + if (ret < 0) { + av_packet_unref(avci->buffer_pkt); + return ret; + } + + if (!avci->buffer_frame->buf[0]) { + ret = decode_receive_frame_internal(avctx, avci->buffer_frame); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + } + + return 0; +} + +static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) +{ + /* make sure we are noisy about decoders returning invalid cropping data */ + if (frame->crop_left >= INT_MAX - frame->crop_right || + frame->crop_top >= INT_MAX - frame->crop_bottom || + (frame->crop_left + frame->crop_right) >= frame->width || + (frame->crop_top + frame->crop_bottom) >= frame->height) { + av_log(avctx, AV_LOG_WARNING, + "Invalid cropping information set by a decoder: " + "%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER" " + "(frame size %dx%d). This is a bug, please report it\n", + frame->crop_left, frame->crop_right, frame->crop_top, frame->crop_bottom, + frame->width, frame->height); + frame->crop_left = 0; + frame->crop_right = 0; + frame->crop_top = 0; + frame->crop_bottom = 0; + return 0; + } + + if (!avctx->apply_cropping) + return 0; + + return av_frame_apply_cropping(frame, avctx->flags & AV_CODEC_FLAG_UNALIGNED ? + AV_FRAME_CROP_UNALIGNED : 0); +} + +int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + av_frame_unref(frame); + + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) + return AVERROR(EINVAL); + + ret = bsfs_init(avctx); + if (ret < 0) + return ret; + + if (avci->buffer_frame->buf[0]) { + av_frame_move_ref(frame, avci->buffer_frame); + } else { + ret = decode_receive_frame_internal(avctx, frame); + if (ret < 0) + return ret; + } + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + ret = apply_cropping(avctx, frame); + if (ret < 0) { + av_frame_unref(frame); + return ret; + } + } + + avctx->frame_number++; + + return 0; +} + +static int compat_decode(AVCodecContext *avctx, AVFrame *frame, + int *got_frame, const AVPacket *pkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret = 0; + + av_assert0(avci->compat_decode_consumed == 0); + + if (avci->draining_done && pkt && pkt->size != 0) { + av_log(avctx, AV_LOG_WARNING, "Got unexpected packet after EOF\n"); + avcodec_flush_buffers(avctx); + } + + *got_frame = 0; + avci->compat_decode = 1; + + if (avci->compat_decode_partial_size > 0 && + avci->compat_decode_partial_size != pkt->size) { + av_log(avctx, AV_LOG_ERROR, + "Got unexpected packet size after a partial decode\n"); + ret = AVERROR(EINVAL); + goto finish; + } + + if (!avci->compat_decode_partial_size) { + ret = avcodec_send_packet(avctx, pkt); + if (ret == AVERROR_EOF) + ret = 0; + else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each decode call, so this should not + * ever happen */ + ret = AVERROR_BUG; + goto finish; + } else if (ret < 0) + goto finish; + } + + while (ret >= 0) { + ret = avcodec_receive_frame(avctx, frame); + if (ret < 0) { + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + goto finish; + } + + if (frame != avci->compat_decode_frame) { + if (!avctx->refcounted_frames) { + ret = unrefcount_frame(avci, frame); + if (ret < 0) + goto finish; + } + + *got_frame = 1; + frame = avci->compat_decode_frame; + } else { + if (!avci->compat_decode_warned) { + av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_decode_* " + "API cannot return all the frames for this decoder. " + "Some frames will be dropped. Update your code to the " + "new decoding API to fix this.\n"); + avci->compat_decode_warned = 1; + } + } + + if (avci->draining || (!avctx->codec->bsfs && avci->compat_decode_consumed < pkt->size)) + break; + } + +finish: + if (ret == 0) { + /* if there are any bsfs then assume full packet is always consumed */ + if (avctx->codec->bsfs) + ret = pkt->size; + else + ret = FFMIN(avci->compat_decode_consumed, pkt->size); + } + avci->compat_decode_consumed = 0; + avci->compat_decode_partial_size = (ret >= 0) ? pkt->size - ret : 0; + + return ret; +} + +int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const AVPacket *avpkt) +{ + return compat_decode(avctx, picture, got_picture_ptr, avpkt); +} + +int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, + AVFrame *frame, + int *got_frame_ptr, + const AVPacket *avpkt) +{ + return compat_decode(avctx, frame, got_frame_ptr, avpkt); +} + +static void get_subtitle_defaults(AVSubtitle *sub) +{ + memset(sub, 0, sizeof(*sub)); + sub->pts = AV_NOPTS_VALUE; +} + +#define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */ +static int recode_subtitle(AVCodecContext *avctx, + AVPacket *outpkt, const AVPacket *inpkt) +{ +#if CONFIG_ICONV + iconv_t cd = (iconv_t)-1; + int ret = 0; + char *inb, *outb; + size_t inl, outl; + AVPacket tmp; +#endif + + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) + return 0; + +#if CONFIG_ICONV + cd = iconv_open("UTF-8", avctx->sub_charenc); + av_assert0(cd != (iconv_t)-1); + + inb = inpkt->data; + inl = inpkt->size; + + if (inl >= INT_MAX / UTF8_MAX_BYTES - AV_INPUT_BUFFER_PADDING_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Subtitles packet is too big for recoding\n"); + ret = AVERROR(ENOMEM); + goto end; + } + + ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES); + if (ret < 0) + goto end; + outpkt->buf = tmp.buf; + outpkt->data = tmp.data; + outpkt->size = tmp.size; + outb = outpkt->data; + outl = outpkt->size; + + if (iconv(cd, &inb, &inl, &outb, &outl) == (size_t)-1 || + iconv(cd, NULL, NULL, &outb, &outl) == (size_t)-1 || + outl >= outpkt->size || inl != 0) { + ret = FFMIN(AVERROR(errno), -1); + av_log(avctx, AV_LOG_ERROR, "Unable to recode subtitle event \"%s\" " + "from %s to UTF-8\n", inpkt->data, avctx->sub_charenc); + av_packet_unref(&tmp); + goto end; + } + outpkt->size -= outl; + memset(outpkt->data + outpkt->size, 0, outl); + +end: + if (cd != (iconv_t)-1) + iconv_close(cd); + return ret; +#else + av_log(avctx, AV_LOG_ERROR, "requesting subtitles recoding without iconv"); + return AVERROR(EINVAL); +#endif +} + +static int utf8_check(const uint8_t *str) +{ + const uint8_t *byte; + uint32_t codepoint, min; + + while (*str) { + byte = str; + GET_UTF8(codepoint, *(byte++), return 0;); + min = byte - str == 1 ? 0 : byte - str == 2 ? 0x80 : + 1 << (5 * (byte - str) - 4); + if (codepoint < min || codepoint >= 0x110000 || + codepoint == 0xFFFE /* BOM */ || + codepoint >= 0xD800 && codepoint <= 0xDFFF /* surrogates */) + return 0; + str = byte; + } + return 1; +} + +#if FF_API_ASS_TIMING +static void insert_ts(AVBPrint *buf, int ts) +{ + if (ts == -1) { + av_bprintf(buf, "9:59:59.99,"); + } else { + int h, m, s; + + h = ts/360000; ts -= 360000*h; + m = ts/ 6000; ts -= 6000*m; + s = ts/ 100; ts -= 100*s; + av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts); + } +} + +static int convert_sub_to_old_ass_form(AVSubtitle *sub, const AVPacket *pkt, AVRational tb) +{ + int i; + AVBPrint buf; + + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); + + for (i = 0; i < sub->num_rects; i++) { + char *final_dialog; + const char *dialog; + AVSubtitleRect *rect = sub->rects[i]; + int ts_start, ts_duration = -1; + long int layer; + + if (rect->type != SUBTITLE_ASS || !strncmp(rect->ass, "Dialogue: ", 10)) + continue; + + av_bprint_clear(&buf); + + /* skip ReadOrder */ + dialog = strchr(rect->ass, ','); + if (!dialog) + continue; + dialog++; + + /* extract Layer or Marked */ + layer = strtol(dialog, (char**)&dialog, 10); + if (*dialog != ',') + continue; + dialog++; + + /* rescale timing to ASS time base (ms) */ + ts_start = av_rescale_q(pkt->pts, tb, av_make_q(1, 100)); + if (pkt->duration != -1) + ts_duration = av_rescale_q(pkt->duration, tb, av_make_q(1, 100)); + sub->end_display_time = FFMAX(sub->end_display_time, 10 * ts_duration); + + /* construct ASS (standalone file form with timestamps) string */ + av_bprintf(&buf, "Dialogue: %ld,", layer); + insert_ts(&buf, ts_start); + insert_ts(&buf, ts_duration == -1 ? -1 : ts_start + ts_duration); + av_bprintf(&buf, "%s\r\n", dialog); + + final_dialog = av_strdup(buf.str); + if (!av_bprint_is_complete(&buf) || !final_dialog) { + av_freep(&final_dialog); + av_bprint_finalize(&buf, NULL); + return AVERROR(ENOMEM); + } + av_freep(&rect->ass); + rect->ass = final_dialog; + } + + av_bprint_finalize(&buf, NULL); + return 0; +} +#endif + +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt) +{ + int i, ret = 0; + AVCodecInternal *avci = avctx->internal; + + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + if (!avctx->codec) + return AVERROR(EINVAL); + if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) { + av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n"); + return AVERROR(EINVAL); + } + + *got_sub_ptr = 0; + get_subtitle_defaults(sub); + + if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { + AVPacket pkt_recoded; + AVPacket tmp = *avpkt; +#if FF_API_MERGE_SD +FF_DISABLE_DEPRECATION_WARNINGS + int did_split = avci->compat_decode_partial_size ? + ff_packet_split_and_drop_side_data(&tmp) : + av_packet_split_side_data(&tmp); + //apply_param_change(avctx, &tmp); + + if (did_split) { + /* FFMIN() prevents overflow in case the packet wasn't allocated with + * proper padding. + * If the side data is smaller than the buffer padding size, the + * remaining bytes should have already been filled with zeros by the + * original packet allocation anyway. */ + memset(tmp.data + tmp.size, 0, + FFMIN(avpkt->size - tmp.size, AV_INPUT_BUFFER_PADDING_SIZE)); + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + pkt_recoded = tmp; + ret = recode_subtitle(avctx, &pkt_recoded, &tmp); + if (ret < 0) { + *got_sub_ptr = 0; + } else { + ret = extract_packet_props(avctx->internal, &pkt_recoded); + if (ret < 0) + return ret; + + if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) + sub->pts = av_rescale_q(avpkt->pts, + avctx->pkt_timebase, AV_TIME_BASE_Q); + ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded); + av_assert1((ret >= 0) >= !!*got_sub_ptr && + !!*got_sub_ptr >= !!sub->num_rects); + +#if FF_API_ASS_TIMING + if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS + && *got_sub_ptr && sub->num_rects) { + const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase + : avctx->time_base; + int err = convert_sub_to_old_ass_form(sub, avpkt, tb); + if (err < 0) + ret = err; + } +#endif + + if (sub->num_rects && !sub->end_display_time && avpkt->duration && + avctx->pkt_timebase.num) { + AVRational ms = { 1, 1000 }; + sub->end_display_time = av_rescale_q(avpkt->duration, + avctx->pkt_timebase, ms); + } + + if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) + sub->format = 0; + else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) + sub->format = 1; + + for (i = 0; i < sub->num_rects; i++) { + if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { + av_log(avctx, AV_LOG_ERROR, + "Invalid UTF-8 in decoded subtitles text; " + "maybe missing -sub_charenc option\n"); + avsubtitle_free(sub); + ret = AVERROR_INVALIDDATA; + break; + } + } + + if (tmp.data != pkt_recoded.data) { // did we recode? + /* prevent from destroying side data from original packet */ + pkt_recoded.side_data = NULL; + pkt_recoded.side_data_elems = 0; + + av_packet_unref(&pkt_recoded); + } + } + +#if FF_API_MERGE_SD + if (did_split) { + av_packet_free_side_data(&tmp); + if(ret == tmp.size) + ret = avpkt->size; + } +#endif + + if (*got_sub_ptr) + avctx->frame_number++; + } + + return ret; +} + +static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; +} + +enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) +{ + while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt)) + ++fmt; + return fmt[0]; +} + +static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, + enum AVPixelFormat pix_fmt) +{ + AVHWAccel *hwaccel = NULL; + + while ((hwaccel = av_hwaccel_next(hwaccel))) + if (hwaccel->id == codec_id + && hwaccel->pix_fmt == pix_fmt) + return hwaccel; + return NULL; +} + +static int setup_hwaccel(AVCodecContext *avctx, + const enum AVPixelFormat fmt, + const char *name) +{ + AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt); + int ret = 0; + + if (!hwa) { + av_log(avctx, AV_LOG_ERROR, + "Could not find an AVHWAccel for the pixel format: %s", + name); + return AVERROR(ENOENT); + } + + if (hwa->capabilities & AV_HWACCEL_CODEC_CAP_EXPERIMENTAL && + avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + av_log(avctx, AV_LOG_WARNING, "Ignoring experimental hwaccel: %s\n", + hwa->name); + return AVERROR_PATCHWELCOME; + } + + if (hwa->priv_data_size) { + avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size); + if (!avctx->internal->hwaccel_priv_data) + return AVERROR(ENOMEM); + } + + avctx->hwaccel = hwa; + if (hwa->init) { + ret = hwa->init(avctx); + if (ret < 0) { + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; + return ret; + } + } + + return 0; +} + +int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) +{ + const AVPixFmtDescriptor *desc; + enum AVPixelFormat *choices; + enum AVPixelFormat ret; + unsigned n = 0; + + while (fmt[n] != AV_PIX_FMT_NONE) + ++n; + + av_assert0(n >= 1); + avctx->sw_pix_fmt = fmt[n - 1]; + av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); + + choices = av_malloc_array(n + 1, sizeof(*choices)); + if (!choices) + return AV_PIX_FMT_NONE; + + memcpy(choices, fmt, (n + 1) * sizeof(*choices)); + + for (;;) { + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; + + av_buffer_unref(&avctx->hw_frames_ctx); + + ret = avctx->get_format(avctx, choices); + + desc = av_pix_fmt_desc_get(ret); + if (!desc) { + ret = AV_PIX_FMT_NONE; + break; + } + + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + break; +#if FF_API_CAP_VDPAU + if (avctx->codec->capabilities&AV_CODEC_CAP_HWACCEL_VDPAU) + break; +#endif + + if (avctx->hw_frames_ctx) { + AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (hw_frames_ctx->format != ret) { + av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " + "does not match the format of provided AVHWFramesContext\n"); + ret = AV_PIX_FMT_NONE; + break; + } + } + + if (!setup_hwaccel(avctx, ret, desc->name)) + break; + + /* Remove failed hwaccel from choices */ + for (n = 0; choices[n] != ret; n++) + av_assert0(choices[n] != AV_PIX_FMT_NONE); + + do + choices[n] = choices[n + 1]; + while (choices[n++] != AV_PIX_FMT_NONE); + } + + av_freep(&choices); + return ret; +} + +static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) +{ + FramePool *pool = avctx->internal->pool; + int i, ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: { + uint8_t *data[4]; + int linesize[4]; + int size[4] = { 0 }; + int w = frame->width; + int h = frame->height; + int tmpsize, unaligned; + + if (pool->format == frame->format && + pool->width == frame->width && pool->height == frame->height) + return 0; + + avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); + + do { + // NOTE: do not align linesizes individually, this breaks e.g. assumptions + // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 + ret = av_image_fill_linesizes(linesize, avctx->pix_fmt, w); + if (ret < 0) + return ret; + // increase alignment of w for next try (rhs gives the lowest bit set in w) + w += w & ~(w - 1); + + unaligned = 0; + for (i = 0; i < 4; i++) + unaligned |= linesize[i] % pool->stride_align[i]; + } while (unaligned); + + tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, + NULL, linesize); + if (tmpsize < 0) + return -1; + + for (i = 0; i < 3 && data[i + 1]; i++) + size[i] = data[i + 1] - data[i]; + size[i] = tmpsize - (data[i] - data[0]); + + for (i = 0; i < 4; i++) { + av_buffer_pool_uninit(&pool->pools[i]); + pool->linesize[i] = linesize[i]; + if (size[i]) { + pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, + CONFIG_MEMORY_POISONING ? + NULL : + av_buffer_allocz); + if (!pool->pools[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + } + pool->format = frame->format; + pool->width = frame->width; + pool->height = frame->height; + + break; + } + case AVMEDIA_TYPE_AUDIO: { + int ch = frame->channels; //av_get_channel_layout_nb_channels(frame->channel_layout); + int planar = av_sample_fmt_is_planar(frame->format); + int planes = planar ? ch : 1; + + if (pool->format == frame->format && pool->planes == planes && + pool->channels == ch && frame->nb_samples == pool->samples) + return 0; + + av_buffer_pool_uninit(&pool->pools[0]); + ret = av_samples_get_buffer_size(&pool->linesize[0], ch, + frame->nb_samples, frame->format, 0); + if (ret < 0) + goto fail; + + pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); + if (!pool->pools[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + pool->format = frame->format; + pool->planes = planes; + pool->channels = ch; + pool->samples = frame->nb_samples; + break; + } + default: av_assert0(0); + } + return 0; +fail: + for (i = 0; i < 4; i++) + av_buffer_pool_uninit(&pool->pools[i]); + pool->format = -1; + pool->planes = pool->channels = pool->samples = 0; + pool->width = pool->height = 0; + return ret; +} + +static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + FramePool *pool = avctx->internal->pool; + int planes = pool->planes; + int i; + + frame->linesize[0] = pool->linesize[0]; + + if (planes > AV_NUM_DATA_POINTERS) { + frame->extended_data = av_mallocz_array(planes, sizeof(*frame->extended_data)); + frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; + frame->extended_buf = av_mallocz_array(frame->nb_extended_buf, + sizeof(*frame->extended_buf)); + if (!frame->extended_data || !frame->extended_buf) { + av_freep(&frame->extended_data); + av_freep(&frame->extended_buf); + return AVERROR(ENOMEM); + } + } else { + frame->extended_data = frame->data; + av_assert0(frame->nb_extended_buf == 0); + } + + for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { + frame->buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->buf[i]) + goto fail; + frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; + } + for (i = 0; i < frame->nb_extended_buf; i++) { + frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->extended_buf[i]) + goto fail; + frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; + } + + if (avctx->debug & FF_DEBUG_BUFFERS) + av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); + + return 0; +fail: + av_frame_unref(frame); + return AVERROR(ENOMEM); +} + +static int video_get_buffer(AVCodecContext *s, AVFrame *pic) +{ + FramePool *pool = s->internal->pool; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); + int i; + + if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) { + av_log(s, AV_LOG_ERROR, "pic->data[*]!=NULL in avcodec_default_get_buffer\n"); + return -1; + } + + if (!desc) { + av_log(s, AV_LOG_ERROR, + "Unable to get pixel format descriptor for format %s\n", + av_get_pix_fmt_name(pic->format)); + return AVERROR(EINVAL); + } + + memset(pic->data, 0, sizeof(pic->data)); + pic->extended_data = pic->data; + + for (i = 0; i < 4 && pool->pools[i]; i++) { + pic->linesize[i] = pool->linesize[i]; + + pic->buf[i] = av_buffer_pool_get(pool->pools[i]); + if (!pic->buf[i]) + goto fail; + + pic->data[i] = pic->buf[i]->data; + } + for (; i < AV_NUM_DATA_POINTERS; i++) { + pic->data[i] = NULL; + pic->linesize[i] = 0; + } + if (desc->flags & AV_PIX_FMT_FLAG_PAL || + desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) + avpriv_set_systematic_pal2((uint32_t *)pic->data[1], pic->format); + + if (s->debug & FF_DEBUG_BUFFERS) + av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); + + return 0; +fail: + av_frame_unref(pic); + return AVERROR(ENOMEM); +} + +int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret; + + if (avctx->hw_frames_ctx) { + ret = av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); + frame->width = avctx->coded_width; + frame->height = avctx->coded_height; + return ret; + } + + if ((ret = update_frame_pool(avctx, frame)) < 0) + return ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + return video_get_buffer(avctx, frame); + case AVMEDIA_TYPE_AUDIO: + return audio_get_buffer(avctx, frame); + default: + return -1; + } +} + +static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) +{ + int size; + const uint8_t *side_metadata; + + AVDictionary **frame_md = &frame->metadata; + + side_metadata = av_packet_get_side_data(avpkt, + AV_PKT_DATA_STRINGS_METADATA, &size); + return av_packet_unpack_dictionary(side_metadata, size, frame_md); +} + +int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) +{ + const AVPacket *pkt = avctx->internal->last_pkt_props; + int i; + static const struct { + enum AVPacketSideDataType packet; + enum AVFrameSideDataType frame; + } sd[] = { + { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN }, + { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, + { AV_PKT_DATA_SPHERICAL, AV_FRAME_DATA_SPHERICAL }, + { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, + { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, + { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, + { AV_PKT_DATA_CONTENT_LIGHT_LEVEL, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL }, + { AV_PKT_DATA_A53_CC, AV_FRAME_DATA_A53_CC }, + }; + + if (pkt) { + frame->pts = pkt->pts; +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_pts = pkt->pts; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + frame->pkt_pos = pkt->pos; + frame->pkt_duration = pkt->duration; + frame->pkt_size = pkt->size; + + for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) { + int size; + uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); + if (packet_sd) { + AVFrameSideData *frame_sd = av_frame_new_side_data(frame, + sd[i].frame, + size); + if (!frame_sd) + return AVERROR(ENOMEM); + + memcpy(frame_sd->data, packet_sd, size); + } + } + add_metadata_from_side_data(pkt, frame); + + if (pkt->flags & AV_PKT_FLAG_DISCARD) { + frame->flags |= AV_FRAME_FLAG_DISCARD; + } else { + frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); + } + } + frame->reordered_opaque = avctx->reordered_opaque; + + if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED) + frame->color_primaries = avctx->color_primaries; + if (frame->color_trc == AVCOL_TRC_UNSPECIFIED) + frame->color_trc = avctx->color_trc; + if (frame->colorspace == AVCOL_SPC_UNSPECIFIED) + frame->colorspace = avctx->colorspace; + if (frame->color_range == AVCOL_RANGE_UNSPECIFIED) + frame->color_range = avctx->color_range; + if (frame->chroma_location == AVCHROMA_LOC_UNSPECIFIED) + frame->chroma_location = avctx->chroma_sample_location; + + switch (avctx->codec->type) { + case AVMEDIA_TYPE_VIDEO: + frame->format = avctx->pix_fmt; + if (!frame->sample_aspect_ratio.num) + frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + + if (frame->width && frame->height && + av_image_check_sar(frame->width, frame->height, + frame->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + frame->sample_aspect_ratio.num, + frame->sample_aspect_ratio.den); + frame->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + + break; + case AVMEDIA_TYPE_AUDIO: + if (!frame->sample_rate) + frame->sample_rate = avctx->sample_rate; + if (frame->format < 0) + frame->format = avctx->sample_fmt; + if (!frame->channel_layout) { + if (avctx->channel_layout) { + if (av_get_channel_layout_nb_channels(avctx->channel_layout) != + avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "Inconsistent channel " + "configuration.\n"); + return AVERROR(EINVAL); + } + + frame->channel_layout = avctx->channel_layout; + } else { + if (avctx->channels > FF_SANE_NB_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n", + avctx->channels); + return AVERROR(ENOSYS); + } + } + } + frame->channels = avctx->channels; + break; + } + return 0; +} + +int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) +{ + return ff_init_buffer_info(avctx, frame); +} + +static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame) +{ + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + int i; + int num_planes = av_pix_fmt_count_planes(frame->format); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + int flags = desc ? desc->flags : 0; + if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL)) + num_planes = 2; + for (i = 0; i < num_planes; i++) { + av_assert0(frame->data[i]); + } + // For now do not enforce anything for palette of pseudopal formats + if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) + num_planes = 2; + // For formats without data like hwaccel allow unused pointers to be non-NULL. + for (i = num_planes; num_planes > 0 && i < FF_ARRAY_ELEMS(frame->data); i++) { + if (frame->data[i]) + av_log(avctx, AV_LOG_ERROR, "Buffer returned by get_buffer2() did not zero unused plane pointers\n"); + frame->data[i] = NULL; + } + } +} + +static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + const AVHWAccel *hwaccel = avctx->hwaccel; + int override_dimensions = 1; + int ret; + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + if ((ret = av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) { + av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); + return AVERROR(EINVAL); + } + + if (frame->width <= 0 || frame->height <= 0) { + frame->width = FFMAX(avctx->width, AV_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); + frame->height = FFMAX(avctx->height, AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); + override_dimensions = 0; + } + + if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) { + av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n"); + return AVERROR(EINVAL); + } + } + ret = ff_decode_frame_props(avctx, frame); + if (ret < 0) + return ret; + + if (hwaccel) { + if (hwaccel->alloc_frame) { + ret = hwaccel->alloc_frame(avctx, frame); + goto end; + } + } else + avctx->sw_pix_fmt = avctx->pix_fmt; + + ret = avctx->get_buffer2(avctx, frame, flags); + if (ret >= 0) + validate_avframe_allocation(avctx, frame); + +end: + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions && + !(avctx->codec->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) { + frame->width = avctx->width; + frame->height = avctx->height; + } + + return ret; +} + +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret = get_buffer_internal(avctx, frame, flags); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + frame->width = frame->height = 0; + } + return ret; +} + +static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVFrame *tmp; + int ret; + + av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); + + if (frame->data[0] && (frame->width != avctx->width || frame->height != avctx->height || frame->format != avctx->pix_fmt)) { + av_log(avctx, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n", + frame->width, frame->height, av_get_pix_fmt_name(frame->format), avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt)); + av_frame_unref(frame); + } + + ff_init_buffer_info(avctx, frame); + + if (!frame->data[0]) + return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + + if (av_frame_is_writable(frame)) + return ff_decode_frame_props(avctx, frame); + + tmp = av_frame_alloc(); + if (!tmp) + return AVERROR(ENOMEM); + + av_frame_move_ref(tmp, frame); + + ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) { + av_frame_free(&tmp); + return ret; + } + + av_frame_copy(frame, tmp); + av_frame_free(&tmp); + + return 0; +} + +int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + int ret = reget_buffer_internal(avctx, frame); + if (ret < 0) + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return ret; +} + +void avcodec_flush_buffers(AVCodecContext *avctx) +{ + avctx->internal->draining = 0; + avctx->internal->draining_done = 0; + avctx->internal->nb_draining_errors = 0; + av_frame_unref(avctx->internal->buffer_frame); + av_frame_unref(avctx->internal->compat_decode_frame); + av_packet_unref(avctx->internal->buffer_pkt); + avctx->internal->buffer_pkt_valid = 0; + + av_packet_unref(avctx->internal->ds.in_pkt); + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) + ff_thread_flush(avctx); + else if (avctx->codec->flush) + avctx->codec->flush(avctx); + + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + + ff_decode_bsfs_uninit(avctx); + + if (!avctx->refcounted_frames) + av_frame_unref(avctx->internal->to_free); +} + +void ff_decode_bsfs_uninit(AVCodecContext *avctx) +{ + DecodeFilterContext *s = &avctx->internal->filter; + int i; + + for (i = 0; i < s->nb_bsfs; i++) + av_bsf_free(&s->bsfs[i]); + av_freep(&s->bsfs); + s->nb_bsfs = 0; +} diff --git a/media/ffvpx/libavcodec/decode.h b/media/ffvpx/libavcodec/decode.h new file mode 100644 index 000000000..c9630228d --- /dev/null +++ b/media/ffvpx/libavcodec/decode.h @@ -0,0 +1,39 @@ +/* + * generic decoding-related code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DECODE_H +#define AVCODEC_DECODE_H + +#include "avcodec.h" + +/** + * Called by decoders to get the next packet for decoding. + * + * @param pkt An empty packet to be filled with data. + * @return 0 if a new reference has been successfully written to pkt + * AVERROR(EAGAIN) if no data is currently available + * AVERROR_EOF if and end of stream has been reached, so no more data + * will be available + */ +int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); + +void ff_decode_bsfs_uninit(AVCodecContext *avctx); + +#endif /* AVCODEC_DECODE_H */ diff --git a/media/ffvpx/libavcodec/dummy_funcs.c b/media/ffvpx/libavcodec/dummy_funcs.c index 200e1d266..21b469f7e 100644 --- a/media/ffvpx/libavcodec/dummy_funcs.c +++ b/media/ffvpx/libavcodec/dummy_funcs.c @@ -73,6 +73,16 @@ AVHWAccel ff_hevc_mediacodec_hwaccel; AVHWAccel ff_mpeg4_mediacodec_hwaccel; AVHWAccel ff_vp8_mediacodec_hwaccel; AVHWAccel ff_vp9_mediacodec_hwaccel; +/* Added by FFmpeg 3.4 */ +AVHWAccel ff_h264_d3d11va2_hwaccel; +AVHWAccel ff_hevc_d3d11va2_hwaccel; +AVHWAccel ff_hevc_videotoolbox_hwaccel; +AVHWAccel ff_mpeg2_d3d11va2_hwaccel; +AVHWAccel ff_mpeg2_mediacodec_hwaccel; +AVHWAccel ff_vc1_d3d11va2_hwaccel; +AVHWAccel ff_vp8_qsv_hwaccel; +AVHWAccel ff_vp9_d3d11va2_hwaccel; +AVHWAccel ff_wmv3_d3d11va2_hwaccel; AVCodec ff_a64multi_encoder; AVCodec ff_a64multi5_encoder; @@ -741,6 +751,54 @@ AVCodec ff_pcm_s64be_decoder; AVCodec ff_pcm_s64be_encoder; AVCodec ff_truehd_encoder; AVCodec ff_mlp_encoder; +/* Added by FFmpeg 3.4 */ +AVCodec ff_clearvideo_decoder; +AVCodec ff_fits_encoder; +AVCodec ff_fits_decoder; +AVCodec ff_fmvc_decoder; +AVCodec ff_gdv_decoder; +AVCodec ff_h263_v4l2m2m_decoder; +AVCodec ff_h264_v4l2m2m_decoder; +AVCodec ff_h264_rkmpp_decoder; +AVCodec ff_hevc_rkmpp_decoder; +AVCodec ff_hevc_v4l2m2m_decoder; +AVCodec ff_mpeg4_v4l2m2m_decoder; +AVCodec ff_mpeg1_v4l2m2m_decoder; +AVCodec ff_mpeg2_v4l2m2m_decoder; +AVCodec ff_mpeg2_mediacodec_decoder; +AVCodec ff_mscc_decoder; +AVCodec ff_pixlet_decoder; +AVCodec ff_psd_decoder; +AVCodec ff_scpr_decoder; +AVCodec ff_speedhq_decoder; +AVCodec ff_srgc_decoder; +AVCodec ff_vc1_v4l2m2m_decoder; +AVCodec ff_vp8_rkmpp_decoder; +AVCodec ff_vp8_v4l2m2m_decoder; +AVCodec ff_vp9_rkmpp_decoder; +AVCodec ff_vp9_v4l2m2m_decoder; +AVCodec ff_bitpacked_decoder; +AVCodec ff_wrapped_avframe_decoder; +AVCodec ff_xpm_decoder; +AVCodec ff_atrac3al_decoder; +AVCodec ff_atrac3pal_decoder; +AVCodec ff_dolby_e_decoder; +AVCodec ff_opus_encoder; +AVCodec ff_qdmc_decoder; +AVCodec ff_pcm_f16le_decoder; +AVCodec ff_pcm_f24le_decoder; +AVCodec ff_gremlin_dpcm_decoder; +AVCodec ff_adpcm_g726le_encoder; +AVCodec ff_librsvg_decoder; +AVCodec ff_h263_v4l2m2m_encoder; +AVCodec ff_h264_v4l2m2m_encoder; +AVCodec ff_hevc_v4l2m2m_encoder; +AVCodec ff_mpeg2_vaapi_encoder; +AVCodec ff_mpeg4_v4l2m2m_encoder; +AVCodec ff_vp8_qsv_decoder; +AVCodec ff_vp8_v4l2m2m_encoder; +AVCodec ff_vp8_vaapi_encoder; +AVCodec ff_vp9_vaapi_encoder; AVCodecParser ff_aac_parser; AVCodecParser ff_aac_latm_parser; @@ -777,6 +835,10 @@ AVCodecParser ff_tak_parser; AVCodecParser ff_vc1_parser; AVCodecParser ff_vorbis_parser; AVCodecParser ff_vp3_parser; +/* Added by FFmpeg 3.4 */ +AVCodecParser ff_sipr_parser; +AVCodecParser ff_xma_parser; + AVBitStreamFilter ff_aac_adtstoasc_bsf; AVBitStreamFilter ff_chomp_bsf; AVBitStreamFilter ff_dump_extradata_bsf; @@ -806,12 +868,15 @@ int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVF void ff_videodsp_init_aarch64(VideoDSPContext *ctx, int bpc) {} void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc) {} void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc) {} +void ff_videodsp_init_mips(VideoDSPContext *ctx, int bpc) {} void ff_vp7dsp_init(VP8DSPContext *c) {} void ff_vp78dsp_init_arm(VP8DSPContext *c) {} void ff_vp78dsp_init_ppc(VP8DSPContext *c) {} void ff_vp8dsp_init_arm(VP8DSPContext *c) {} void ff_vp8dsp_init_mips(VP8DSPContext *c) {} void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp) {} +void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp) {} +void ff_vp9dsp_init_arm(VP9DSPContext *dsp, int bpp) {} void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps) {} #if !defined(HAVE_64BIT_BUILD) void ff_flac_decorrelate_indep8_16_sse2(uint8_t **out, int32_t **in, int channels, int len, int shift) {} @@ -819,11 +884,3 @@ void ff_flac_decorrelate_indep8_32_avx(uint8_t **out, int32_t **in, int channels void ff_flac_decorrelate_indep8_16_avx(uint8_t **out, int32_t **in, int channels, int len, int shift) {} void ff_flac_decorrelate_indep8_32_sse2(uint8_t **out, int32_t **in, int channels, int len, int shift) {} #endif -void av_bitstream_filter_close(AVBitStreamFilterContext *bsf) {} -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) { return 0; } -AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) { return NULL;} -AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f) { return NULL; } -void av_register_bitstream_filter(AVBitStreamFilter *bsf) {} diff --git a/media/ffvpx/libavcodec/error_resilience.h b/media/ffvpx/libavcodec/error_resilience.h index d444ec3a3..27c200869 100644 --- a/media/ffvpx/libavcodec/error_resilience.h +++ b/media/ffvpx/libavcodec/error_resilience.h @@ -57,8 +57,8 @@ typedef struct ERContext { int *mb_index2xy; int mb_num; int mb_width, mb_height; - int mb_stride; - int b8_stride; + ptrdiff_t mb_stride; + ptrdiff_t b8_stride; volatile int error_count; int error_occurred; diff --git a/media/ffvpx/libavcodec/flac.c b/media/ffvpx/libavcodec/flac.c index f5154b914..5ffbf9319 100644 --- a/media/ffvpx/libavcodec/flac.c +++ b/media/ffvpx/libavcodec/flac.c @@ -201,7 +201,7 @@ void ff_flac_set_channel_layout(AVCodecContext *avctx) avctx->channel_layout = 0; } -void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, +int ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, const uint8_t *buffer) { GetBitContext gb; @@ -213,6 +213,7 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, av_log(avctx, AV_LOG_WARNING, "invalid max blocksize: %d\n", s->max_blocksize); s->max_blocksize = 16; + return AVERROR_INVALIDDATA; } skip_bits(&gb, 24); /* skip min frame size */ @@ -222,6 +223,12 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, s->channels = get_bits(&gb, 3) + 1; s->bps = get_bits(&gb, 5) + 1; + if (s->bps < 4) { + av_log(avctx, AV_LOG_ERROR, "invalid bps: %d\n", s->bps); + s->bps = 16; + return AVERROR_INVALIDDATA; + } + avctx->channels = s->channels; avctx->sample_rate = s->samplerate; avctx->bits_per_raw_sample = s->bps; @@ -234,4 +241,6 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, skip_bits_long(&gb, 64); /* md5 sum */ skip_bits_long(&gb, 64); /* md5 sum */ + + return 0; } diff --git a/media/ffvpx/libavcodec/flac.h b/media/ffvpx/libavcodec/flac.h index 96d971c9d..991ab43f3 100644 --- a/media/ffvpx/libavcodec/flac.h +++ b/media/ffvpx/libavcodec/flac.h @@ -95,8 +95,10 @@ typedef struct FLACFrameInfo { * @param[out] avctx codec context to set basic stream parameters * @param[out] s where parsed information is stored * @param[in] buffer pointer to start of 34-byte streaminfo data + * + * @return negative error code on faiure or >= 0 on success */ -void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, +int ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, const uint8_t *buffer); /** diff --git a/media/ffvpx/libavcodec/flac_parser.c b/media/ffvpx/libavcodec/flac_parser.c index f5cc35a4f..84da23f32 100644 --- a/media/ffvpx/libavcodec/flac_parser.c +++ b/media/ffvpx/libavcodec/flac_parser.c @@ -586,10 +586,12 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, temp = curr->next; av_freep(&curr->link_penalty); av_free(curr); + fpc->nb_headers_buffered--; } fpc->headers = fpc->best_header->next; av_freep(&fpc->best_header->link_penalty); av_freep(&fpc->best_header); + fpc->nb_headers_buffered--; } /* Find and score new headers. */ @@ -638,7 +640,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, read_end - read_start, NULL); } else { int8_t pad[MAX_FRAME_HEADER_SIZE] = { 0 }; - av_fifo_generic_write(fpc->fifo_buf, (void*) pad, sizeof(pad), NULL); + av_fifo_generic_write(fpc->fifo_buf, pad, sizeof(pad), NULL); } /* Tag headers and update sequences. */ diff --git a/media/ffvpx/libavcodec/flacdec.c b/media/ffvpx/libavcodec/flacdec.c index b7237e18f..3d41a1af7 100644 --- a/media/ffvpx/libavcodec/flacdec.c +++ b/media/ffvpx/libavcodec/flacdec.c @@ -109,7 +109,9 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; /* initialize based on the demuxer-supplied streamdata header */ - ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo); + ret = ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo); + if (ret < 0) + return ret; ret = allocate_buffers(s); if (ret < 0) return ret; @@ -175,7 +177,9 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) metadata_size != FLAC_STREAMINFO_SIZE) { return AVERROR_INVALIDDATA; } - ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]); + ret = ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]); + if (ret < 0) + return ret; ret = allocate_buffers(s); if (ret < 0) return ret; @@ -201,12 +205,12 @@ static int get_metadata_size(const uint8_t *buf, int buf_size) buf += 4; do { if (buf_end - buf < 4) - return 0; + 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 0; + return AVERROR_INVALIDDATA; } buf += metadata_size; } while (!metadata_last); @@ -254,8 +258,15 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) for (; i < samples; i++) *decoded++ = get_sbits_long(&s->gb, tmp); } else { + int real_limit = tmp ? (INT_MAX >> tmp) + 2 : INT_MAX; for (; i < samples; i++) { - *decoded++ = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0); + int v = get_sr_golomb_flac(&s->gb, tmp, real_limit, 0); + if (v == 0x80000000){ + av_log(s->avctx, AV_LOG_ERROR, "invalid residual\n"); + return AVERROR_INVALIDDATA; + } + + *decoded++ = v; } } i= 0; @@ -268,7 +279,8 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, int pred_order, int bps) { const int blocksize = s->blocksize; - int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i; + unsigned av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d); + int i; int ret; /* warm up samples */ @@ -286,7 +298,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, 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]; + d = c - decoded[pred_order-2] + 2U*decoded[pred_order-3] - decoded[pred_order-4]; switch (pred_order) { case 0: @@ -315,7 +327,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, return 0; } -static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32], +static void lpc_analyze_remodulate(SUINT32 *decoded, const int coeffs[32], int order, int qlevel, int len, int bps) { int i, j; @@ -331,7 +343,7 @@ static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32], 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]; + p += coeffs[j] * (int64_t)(int32_t)decoded[i-order+j]; decoded[i] -= p >> qlevel; } for (i = order; i < len; i++, decoded++) { @@ -444,10 +456,10 @@ static inline int decode_subframe(FLACContext *s, int channel) return AVERROR_INVALIDDATA; } - if (wasted) { + if (wasted && wasted < 32) { int i; for (i = 0; i < s->blocksize; i++) - decoded[i] <<= wasted; + decoded[i] = (unsigned)decoded[i] << wasted; } return 0; diff --git a/media/ffvpx/libavcodec/flacdsp.c b/media/ffvpx/libavcodec/flacdsp.c index 30b66484e..bc9a5dbed 100644 --- a/media/ffvpx/libavcodec/flacdsp.c +++ b/media/ffvpx/libavcodec/flacdsp.c @@ -49,8 +49,8 @@ static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32], int i, j; for (i = pred_order; i < len - 1; i += 2, decoded += 2) { - int c = coeffs[0]; - int d = decoded[0]; + SUINT c = coeffs[0]; + SUINT d = decoded[0]; int s0 = 0, s1 = 0; for (j = 1; j < pred_order; j++) { s0 += c*d; @@ -59,15 +59,15 @@ static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32], c = coeffs[j]; } s0 += c*d; - d = decoded[j] += s0 >> qlevel; + d = decoded[j] += (SUINT)(s0 >> qlevel); s1 += c*d; - decoded[j + 1] += s1 >> qlevel; + decoded[j + 1] += (SUINT)(s1 >> qlevel); } if (i < len) { int sum = 0; for (j = 0; j < pred_order; j++) - sum += coeffs[j] * decoded[j]; - decoded[j] += sum >> qlevel; + sum += coeffs[j] * (SUINT)decoded[j]; + decoded[j] = decoded[j] + (unsigned)(sum >> qlevel); } } diff --git a/media/ffvpx/libavcodec/flacdsp.h b/media/ffvpx/libavcodec/flacdsp.h index f5cbd9472..7bb0dd0e9 100644 --- a/media/ffvpx/libavcodec/flacdsp.h +++ b/media/ffvpx/libavcodec/flacdsp.h @@ -20,6 +20,7 @@ #define AVCODEC_FLACDSP_H #include <stdint.h> +#include "libavutil/internal.h" #include "libavutil/samplefmt.h" typedef struct FLACDSPContext { diff --git a/media/ffvpx/libavcodec/flacdsp_template.c b/media/ffvpx/libavcodec/flacdsp_template.c index 62c0a15ff..776c78da7 100644 --- a/media/ffvpx/libavcodec/flacdsp_template.c +++ b/media/ffvpx/libavcodec/flacdsp_template.c @@ -56,7 +56,7 @@ static void FUNC(flac_decorrelate_indep_c)(uint8_t **out, int32_t **in, for (j = 0; j < len; j++) for (i = 0; i < channels; i++) - S(samples, i, j) = in[i][j] << shift; + S(samples, i, j) = (int)((unsigned)in[i][j] << shift); } static void FUNC(flac_decorrelate_ls_c)(uint8_t **out, int32_t **in, diff --git a/media/ffvpx/libavcodec/get_bits.h b/media/ffvpx/libavcodec/get_bits.h index 0f183e035..0c7f5ff0c 100644 --- a/media/ffvpx/libavcodec/get_bits.h +++ b/media/ffvpx/libavcodec/get_bits.h @@ -229,6 +229,20 @@ static inline int get_xbits(GetBitContext *s, int n) return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; } +static inline int get_xbits_le(GetBitContext *s, int n) +{ + register int sign; + register int32_t cache; + OPEN_READER(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE_LE(re, s); + cache = GET_CACHE(re, s); + sign = sign_extend(~cache, n) >> 31; + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); + return (zero_extend(sign ^ cache, n) ^ sign) - sign; +} + static inline int get_sbits(GetBitContext *s, int n) { register int tmp; @@ -331,6 +345,7 @@ static inline void skip_bits1(GetBitContext *s) */ static inline unsigned int get_bits_long(GetBitContext *s, int n) { + av_assert2(n>=0 && n<=32); if (!n) { return 0; } else if (n <= MIN_CACHE_BITS) { @@ -369,6 +384,10 @@ static inline uint64_t get_bits64(GetBitContext *s, int n) */ static inline int get_sbits_long(GetBitContext *s, int n) { + // sign_extend(x, 0) is undefined + if (!n) + return 0; + return sign_extend(get_bits_long(s, n), n); } @@ -531,6 +550,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) * @param max_depth is the number of times bits bits must be read to completely * read the longest vlc code * = (max_vlc_length + bits - 1) / bits + * @returns the code parsed or -1 if no vlc matches */ static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth) diff --git a/media/ffvpx/libavcodec/golomb.h b/media/ffvpx/libavcodec/golomb.h index 917ea54e1..efb1eff8a 100644 --- a/media/ffvpx/libavcodec/golomb.h +++ b/media/ffvpx/libavcodec/golomb.h @@ -314,6 +314,8 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, log = av_log2(buf); + av_assert2(k <= 31); + if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) && 32 - log < limit) { buf >>= log - k; @@ -325,8 +327,10 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, } else { int i; for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) { - if (gb->size_in_bits <= re_index) + if (gb->size_in_bits <= re_index) { + CLOSE_READER(re, gb); return -1; + } LAST_SKIP_BITS(re, gb, 1); UPDATE_CACHE(re, gb); } @@ -348,16 +352,17 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, buf = 0; } - CLOSE_READER(re, gb); - return buf + (i << k); + buf += ((SUINT)i << k); } else if (i == limit - 1) { buf = SHOW_UBITS(re, gb, esc_len); LAST_SKIP_BITS(re, gb, esc_len); - CLOSE_READER(re, gb); - return buf + 1; - } else - return -1; + buf ++; + } else { + buf = -1; + } + CLOSE_READER(re, gb); + return buf; } } @@ -445,19 +450,20 @@ static inline int get_te(GetBitContext *s, int r, char *file, const char *func, return i; } -#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_ue_golomb(a) get_ue(a, __FILE__, __func__, __LINE__) +#define get_se_golomb(a) get_se(a, __FILE__, __func__, __LINE__) +#define get_te_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) +#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) #endif /* TRACE */ /** - * write unsigned exp golomb code. + * write unsigned exp golomb code. 2^16 - 2 at most */ static inline void set_ue_golomb(PutBitContext *pb, int i) { av_assert2(i >= 0); + av_assert2(i <= 0xFFFE); if (i < 256) put_bits(pb, ff_ue_golomb_len[i], i + 1); @@ -468,6 +474,21 @@ static inline void set_ue_golomb(PutBitContext *pb, int i) } /** + * write unsigned exp golomb code. 2^32-2 at most. + */ +static inline void set_ue_golomb_long(PutBitContext *pb, uint32_t i) +{ + av_assert2(i <= (UINT32_MAX - 1)); + + if (i < 256) + put_bits(pb, ff_ue_golomb_len[i], i + 1); + else { + int e = av_log2(i + 1); + put_bits64(pb, 2 * e + 1, i + 1); + } +} + +/** * write truncated unsigned exp golomb code. */ static inline void set_te_golomb(PutBitContext *pb, int i, int range) @@ -486,19 +507,9 @@ static inline void set_te_golomb(PutBitContext *pb, int i, int range) */ static inline void set_se_golomb(PutBitContext *pb, int i) { -#if 0 - if (i <= 0) - i = -2 * i; - else - i = 2 * i - 1; -#elif 1 i = 2 * i - 1; if (i < 0) i ^= -1; //FIXME check if gcc does the right thing -#else - i = 2 * i - 1; - i ^= (i >> 31); -#endif set_ue_golomb(pb, i); } diff --git a/media/ffvpx/libavcodec/h264chroma.h b/media/ffvpx/libavcodec/h264chroma.h index e0f45ad13..5c89fd12d 100644 --- a/media/ffvpx/libavcodec/h264chroma.h +++ b/media/ffvpx/libavcodec/h264chroma.h @@ -19,9 +19,10 @@ #ifndef AVCODEC_H264CHROMA_H #define AVCODEC_H264CHROMA_H +#include <stddef.h> #include <stdint.h> -typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); +typedef void (*h264_chroma_mc_func)(uint8_t *dst /*align 8*/, uint8_t *src /*align 1*/, ptrdiff_t srcStride, int h, int x, int y); typedef struct H264ChromaContext { h264_chroma_mc_func put_h264_chroma_pixels_tab[4]; diff --git a/media/ffvpx/libavcodec/hpeldsp.h b/media/ffvpx/libavcodec/hpeldsp.h index 1a3cea54b..768139bfc 100644 --- a/media/ffvpx/libavcodec/hpeldsp.h +++ b/media/ffvpx/libavcodec/hpeldsp.h @@ -76,6 +76,8 @@ typedef struct HpelDSPContext { * @param pixels source * @param line_size number of bytes in a horizontal line of block * @param h height + * @note The size is kept at [4][4] to match the above pixel_tabs and avoid + * out of bounds reads in the motion estimation code. */ op_pixels_func put_no_rnd_pixels_tab[4][4]; diff --git a/media/ffvpx/libavcodec/ff_options_table.h b/media/ffvpx/libavcodec/hwaccel.h index ee01275d3..124fbbf1f 100644 --- a/media/ffvpx/libavcodec/ff_options_table.h +++ b/media/ffvpx/libavcodec/hwaccel.h @@ -1,7 +1,4 @@ /* - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> - * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -19,12 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVCODEC_OPTIONS_TABLE_H -#define AVCODEC_OPTIONS_TABLE_H +#ifndef AVCODEC_HWACCEL_H +#define AVCODEC_HWACCEL_H -#include "libavutil/opt.h" -static const AVOption avcodec_options[] = { -{NULL}, -}; +#define HWACCEL_CAP_ASYNC_SAFE (1 << 0) -#endif /* AVCODEC_OPTIONS_TABLE_H */ +#endif /* AVCODEC_HWACCEL_H */ diff --git a/media/ffvpx/libavcodec/idctdsp.h b/media/ffvpx/libavcodec/idctdsp.h index b180a6762..26221f6a9 100644 --- a/media/ffvpx/libavcodec/idctdsp.h +++ b/media/ffvpx/libavcodec/idctdsp.h @@ -21,6 +21,8 @@ #include <stdint.h> +#include "config.h" + #include "avcodec.h" /** @@ -51,13 +53,13 @@ int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, typedef struct IDCTDSPContext { /* pixel ops : interface with DCT */ void (*put_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*add_pixels_clamped)(const int16_t *block /* align 16 */, - uint8_t *pixels /* align 8 */, + uint8_t *av_restrict pixels /* align 8 */, ptrdiff_t line_size); void (*idct)(int16_t *block /* align 16 */); @@ -68,14 +70,14 @@ typedef struct IDCTDSPContext { * @param line_size size in bytes of a horizontal line of dest */ void (*idct_put)(uint8_t *dest /* align 8 */, - int line_size, int16_t *block /* align 16 */); + ptrdiff_t line_size, int16_t *block /* align 16 */); /** * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. * @param line_size size in bytes of a horizontal line of dest */ void (*idct_add)(uint8_t *dest /* align 8 */, - int line_size, int16_t *block /* align 16 */); + ptrdiff_t line_size, int16_t *block /* align 16 */); /** * IDCT input permutation. @@ -95,11 +97,15 @@ typedef struct IDCTDSPContext { enum idct_permutation_type perm_type; } IDCTDSPContext; -extern void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size); -extern void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size); +void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, + ptrdiff_t line_size); +void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, + ptrdiff_t line_size); void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx); +void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); void ff_idctdsp_init_alpha(IDCTDSPContext *c, AVCodecContext *avctx, unsigned high_bit_depth); void ff_idctdsp_init_arm(IDCTDSPContext *c, AVCodecContext *avctx, diff --git a/media/ffvpx/libavcodec/internal.h b/media/ffvpx/libavcodec/internal.h index 35b9630b5..faa923c11 100644 --- a/media/ffvpx/libavcodec/internal.h +++ b/media/ffvpx/libavcodec/internal.h @@ -48,8 +48,8 @@ #define FF_CODEC_CAP_INIT_CLEANUP (1 << 1) /** * Decoders marked with FF_CODEC_CAP_SETS_PKT_DTS want to set - * AVFrame.pkt_dts manually. If the flag is set, utils.c won't overwrite - * this field. If it's unset, utils.c tries to guess the pkt_dts field + * AVFrame.pkt_dts manually. If the flag is set, decode.c won't overwrite + * this field. If it's unset, decode.c tries to guess the pkt_dts field * from the input AVPacket. */ #define FF_CODEC_CAP_SETS_PKT_DTS (1 << 2) @@ -58,6 +58,16 @@ * skipped due to the skip_frame setting. */ #define FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM (1 << 3) +/** + * The decoder sets the cropping fields in the output frames manually. + * If this cap is set, the generic code will initialize output frame + * dimensions to coded rather than display values. + */ +#define FF_CODEC_CAP_EXPORTS_CROPPING (1 << 4) +/** + * Codec initializes slice-based threading with a main function + */ +#define FF_CODEC_CAP_SLICE_THREAD_HAS_MF (1 << 5) #ifdef TRACE # define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__) @@ -70,11 +80,18 @@ #define FF_DEFAULT_QUANT_BIAS 999999 #endif +#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 + #define FF_SANE_NB_CHANNELS 64U #define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1) -#if HAVE_AVX +#if HAVE_SIMD_ALIGN_32 # define STRIDE_ALIGN 32 #elif HAVE_SIMD_ALIGN_16 # define STRIDE_ALIGN 16 @@ -101,6 +118,16 @@ typedef struct FramePool { int samples; } FramePool; +typedef struct DecodeSimpleContext { + AVPacket *in_pkt; + AVFrame *out_frame; +} DecodeSimpleContext; + +typedef struct DecodeFilterContext { + AVBSFContext **bsfs; + int nb_bsfs; +} DecodeFilterContext; + typedef struct AVCodecInternal { /** * Whether the parent AVCodecContext is a copy of the context which had @@ -137,11 +164,14 @@ typedef struct AVCodecInternal { void *thread_ctx; + DecodeSimpleContext ds; + DecodeFilterContext filter; + /** - * Current packet as passed into the decoder, to avoid having to pass the - * packet into every function. + * Properties (timestamps+side data) extracted from the last packet passed + * for decoding. */ - AVPacket *pkt; + AVPacket *last_pkt_props; /** * temporary buffer used for encoders to store their bitstream @@ -173,7 +203,23 @@ typedef struct AVCodecInternal { int buffer_pkt_valid; // encoding: packet without data can be valid AVFrame *buffer_frame; int draining_done; + /* set to 1 when the caller is using the old decoding API */ + int compat_decode; + int compat_decode_warned; + /* this variable is set by the decoder internals to signal to the old + * API compat wrappers the amount of data consumed from the last packet */ + size_t compat_decode_consumed; + /* when a partial packet has been consumed, this stores the remaining size + * of the packet (that should be submitted in the next decode call */ + size_t compat_decode_partial_size; + AVFrame *compat_decode_frame; + int showed_multi_packet_warning; + + int skip_samples_multiplier; + + /* to prevent infinite loop on errors when draining */ + int nb_draining_errors; } AVCodecInternal; struct AVCodecDefault { @@ -262,7 +308,7 @@ static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx, static av_always_inline float ff_exp2fi(int x) { /* Normal range */ if (-126 <= x && x <= 128) - return av_int2float(x+127 << 23); + return av_int2float((x+127) << 23); /* Too large */ else if (x > 128) return INFINITY; @@ -327,6 +373,10 @@ int ff_set_sar(AVCodecContext *avctx, AVRational sar); int ff_side_data_update_matrix_encoding(AVFrame *frame, enum AVMatrixEncoding matrix_encoding); +#if FF_API_MERGE_SD +int ff_packet_split_and_drop_side_data(AVPacket *pkt); +#endif + /** * Select the (possibly hardware accelerated) pixel format. * This is a wrapper around AVCodecContext.get_format() and should be used @@ -361,4 +411,10 @@ int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, i int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size); +/** + * Get an estimated video bitrate based on frame size, frame rate and coded + * bits per pixel. + */ +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx); + #endif /* AVCODEC_INTERNAL_H */ diff --git a/media/ffvpx/libavcodec/mathops.h b/media/ffvpx/libavcodec/mathops.h index 5168dc2ce..1c3566431 100644 --- a/media/ffvpx/libavcodec/mathops.h +++ b/media/ffvpx/libavcodec/mathops.h @@ -25,6 +25,7 @@ #include <stdint.h> #include "libavutil/common.h" +#include "libavutil/reverse.h" #include "config.h" #define MAX_NEG_CROP 1024 @@ -96,15 +97,6 @@ static av_always_inline unsigned UMULH(unsigned a, unsigned b){ #define mid_pred mid_pred static inline av_const int mid_pred(int a, int b, int c) { -#if 0 - int t= (a-b)&((a-b)>>31); - a-=t; - b+=t; - b-= (b-c)&((b-c)>>31); - b+= (a-b)&((a-b)>>31); - - return b; -#else if(a>b){ if(c>b){ if(c>a) b=a; @@ -117,7 +109,6 @@ static inline av_const int mid_pred(int a, int b, int c) } } return b; -#endif } #endif @@ -249,4 +240,12 @@ static inline int8_t ff_u8_to_s8(uint8_t a) return b.s8; } +static av_always_inline uint32_t bitswap_32(uint32_t x) +{ + return (uint32_t)ff_reverse[ x & 0xFF] << 24 | + (uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 | + (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 | + (uint32_t)ff_reverse[ x >> 24]; +} + #endif /* AVCODEC_MATHOPS_H */ diff --git a/media/ffvpx/libavcodec/me_cmp.h b/media/ffvpx/libavcodec/me_cmp.h index 5666f59ad..0dbbcbb1d 100644 --- a/media/ffvpx/libavcodec/me_cmp.h +++ b/media/ffvpx/libavcodec/me_cmp.h @@ -76,7 +76,7 @@ typedef struct MECmpContext { me_cmp_func frame_skip_cmp[6]; // only width 8 used me_cmp_func pix_abs[2][4]; - me_cmp_func median_sad[2]; + me_cmp_func median_sad[6]; } MECmpContext; void ff_me_cmp_init_static(void); diff --git a/media/ffvpx/libavcodec/moz.build b/media/ffvpx/libavcodec/moz.build index 443bbe978..9980e1556 100644 --- a/media/ffvpx/libavcodec/moz.build +++ b/media/ffvpx/libavcodec/moz.build @@ -16,7 +16,11 @@ SOURCES += [ 'avpacket.c', 'avpicture.c', 'bitstream.c', + 'bitstream_filter.c', + 'bitstream_filters.c', + 'bsf.c', 'codec_desc.c', + 'decode.c', 'dummy_funcs.c', 'flac.c', 'flac_parser.c', @@ -28,6 +32,7 @@ SOURCES += [ 'imgconvert.c', 'log2_tab.c', 'mathtables.c', + 'null_bsf.c', 'options.c', 'parser.c', 'profiles.c', @@ -48,10 +53,16 @@ SOURCES += [ 'vp8dsp.c', 'vp9.c', 'vp9_parser.c', + 'vp9block.c', + 'vp9data.c', 'vp9dsp.c', 'vp9dsp_10bpp.c', 'vp9dsp_12bpp.c', 'vp9dsp_8bpp.c', + 'vp9lpf.c', + 'vp9mvs.c', + 'vp9prob.c', + 'vp9recon.c', 'xiph.c' ] diff --git a/media/ffvpx/libavcodec/mpegvideo.h b/media/ffvpx/libavcodec/mpegvideo.h index c82fa3e1a..e9eb633d1 100644 --- a/media/ffvpx/libavcodec/mpegvideo.h +++ b/media/ffvpx/libavcodec/mpegvideo.h @@ -422,6 +422,7 @@ typedef struct MpegEncContext { struct MJpegContext *mjpeg_ctx; int esc_pos; int pred; + int huffman; /* MSMPEG4 specific */ int mv_table_index; @@ -679,7 +680,7 @@ void ff_mpv_common_end(MpegEncContext *s); void ff_mpv_decode_defaults(MpegEncContext *s); void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx); -void ff_mpv_decode_mb(MpegEncContext *s, int16_t block[12][64]); +void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]); void ff_mpv_report_decode_progress(MpegEncContext *s); int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx); diff --git a/media/ffvpx/libavcodec/null_bsf.c b/media/ffvpx/libavcodec/null_bsf.c new file mode 100644 index 000000000..feb71248a --- /dev/null +++ b/media/ffvpx/libavcodec/null_bsf.c @@ -0,0 +1,43 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General 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 + * Null bitstream filter -- pass the input through unchanged. + */ + +#include "avcodec.h" +#include "bsf.h" + +static int null_filter(AVBSFContext *ctx, AVPacket *out) +{ + AVPacket *in; + int ret; + + ret = ff_bsf_get_packet(ctx, &in); + if (ret < 0) + return ret; + av_packet_move_ref(out, in); + av_packet_free(&in); + return 0; +} + +const AVBitStreamFilter ff_null_bsf = { + .name = "null", + .filter = null_filter, +}; diff --git a/media/ffvpx/libavcodec/options.c b/media/ffvpx/libavcodec/options.c index f25df2ab3..82e12179a 100644 --- a/media/ffvpx/libavcodec/options.c +++ b/media/ffvpx/libavcodec/options.c @@ -34,7 +34,7 @@ #include <string.h> FF_DISABLE_DEPRECATION_WARNINGS -#include "ff_options_table.h" +#include "options_table.h" FF_ENABLE_DEPRECATION_WARNINGS static const char* context_to_name(void* ptr) { @@ -119,6 +119,7 @@ static int init_context_defaults(AVCodecContext *s, const AVCodec *codec) s->execute2 = avcodec_default_execute2; s->sample_aspect_ratio = (AVRational){0,1}; s->pix_fmt = AV_PIX_FMT_NONE; + s->sw_pix_fmt = AV_PIX_FMT_NONE; s->sample_fmt = AV_SAMPLE_FMT_NONE; s->reordered_opaque = AV_NOPTS_VALUE; @@ -187,6 +188,31 @@ void avcodec_free_context(AVCodecContext **pavctx) } #if FF_API_COPY_CONTEXT +static void copy_context_reset(AVCodecContext *avctx) +{ + int i; + + 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); + av_buffer_unref(&avctx->hw_frames_ctx); + av_buffer_unref(&avctx->hw_device_ctx); + for (i = 0; i < avctx->nb_coded_side_data; i++) + av_freep(&avctx->coded_side_data[i].data); + av_freep(&avctx->coded_side_data); + avctx->subtitle_header_size = 0; + avctx->nb_coded_side_data = 0; + avctx->extradata_size = 0; +} + int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) { const AVCodec *orig_codec = dest->codec; @@ -199,12 +225,7 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) 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); + copy_context_reset(dest); memcpy(dest, src, sizeof(*dest)); av_opt_copy(dest, src); @@ -229,11 +250,14 @@ FF_ENABLE_DEPRECATION_WARNINGS /* reallocate values that should be allocated separately */ dest->extradata = NULL; + dest->coded_side_data = NULL; dest->intra_matrix = NULL; dest->inter_matrix = NULL; dest->rc_override = NULL; dest->subtitle_header = NULL; dest->hw_frames_ctx = NULL; + dest->hw_device_ctx = NULL; + dest->nb_coded_side_data = 0; #define alloc_and_copy_or_fail(obj, size, pad) \ if (src->obj && size > 0) { \ @@ -263,15 +287,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; fail: - av_freep(&dest->subtitle_header); - av_freep(&dest->rc_override); - av_freep(&dest->intra_matrix); - av_freep(&dest->inter_matrix); - av_freep(&dest->extradata); - av_buffer_unref(&dest->hw_frames_ctx); - dest->subtitle_header_size = 0; - dest->extradata_size = 0; - av_opt_free(dest); + copy_context_reset(dest); return AVERROR(ENOMEM); } #endif diff --git a/media/ffvpx/libavcodec/options_table.h b/media/ffvpx/libavcodec/options_table.h new file mode 100644 index 000000000..2ac37c3ff --- /dev/null +++ b/media/ffvpx/libavcodec/options_table.h @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@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 AVCODEC_OPTIONS_TABLE_H +#define AVCODEC_OPTIONS_TABLE_H + +#include <float.h> +#include <limits.h> +#include <stdint.h> + +#include "libavutil/opt.h" +#include "avcodec.h" +#include "version.h" + +#define OFFSET(x) offsetof(AVCodecContext,x) +#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C +//these names are too long to be readable +#define V AV_OPT_FLAG_VIDEO_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM +#define S AV_OPT_FLAG_SUBTITLE_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM +#define D AV_OPT_FLAG_DECODING_PARAM + +#define AV_CODEC_DEFAULT_BITRATE 200*1000 + +static const AVOption avcodec_options[] = { +{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E}, +{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = 128*1000 }, 0, INT_MAX, A|E}, +{"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far " + "ratecontrol is willing to deviate from the target average bitrate value. This is not related " + "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", + OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, +{"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"}, +{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" }, +{"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"}, +{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"}, +{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, +{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"}, +#if FF_API_GMC +{"gmc", "use gmc", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_GMC }, INT_MIN, INT_MAX, V|E, "flags"}, +#endif +#if FF_API_MV0 +{"mv0", "always try a mb with mv=<0,0>", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_MV0 }, INT_MIN, INT_MAX, V|E, "flags"}, +#endif +#if FF_API_INPUT_PRESERVED +{"input_preserved", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INPUT_PRESERVED }, INT_MIN, INT_MAX, 0, "flags"}, +#endif +{"pass1", "use internal 2-pass ratecontrol in first pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"}, +{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"}, +{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"}, +#if FF_API_EMU_EDGE +{"emu_edge", "do not draw edges", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_EMU_EDGE }, INT_MIN, INT_MAX, 0, "flags"}, +#endif +{"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"}, +{"truncated", "Input bitstream might be randomly truncated", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, V|D, "flags"}, +#if FF_API_NORMALIZE_AQP +{"naq", "normalize adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_NORMALIZE_AQP }, INT_MIN, INT_MAX, V|E, "flags"}, +#endif +{"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"}, +{"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"}, +{"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"}, +{"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"}, +{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"}, +{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"}, +{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"}, +{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"}, +{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"export_mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, "flags2"}, +{"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, V|D, "flags2"}, +{"ass_ro_flush_noop", "do not reset ASS ReadOrder field on flush", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_RO_FLUSH_NOOP}, INT_MIN, INT_MAX, S|D, "flags2"}, +#if FF_API_MOTION_EST +{"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"}, +{"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"epzs", "EPZS motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"esa", "esa motion estimation (alias for full)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"tesa", "tesa motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_TESA }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"dia", "diamond motion estimation (alias for EPZS)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"log", "log motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_LOG }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"phods", "phods motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_PHODS }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"x1", "X1 motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_X1 }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"hex", "hex motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" }, +{"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" }, +#endif +{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, INT_MAX}, +{"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E}, +{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, +{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, +{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E}, +{"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|E}, +{"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"qcomp", "video quantizer scale compression (VBR). Constant of ratecontrol equation. " + "Recommended range for default rc_eq: 0.0-1.0", + OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E}, +{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E}, +{"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E}, +{"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E}, +{"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E}, +{"bf", "set maximum number of B-frames between non-B-frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, V|E}, +{"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, +#if FF_API_RC_STRATEGY +{"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#if FF_API_PRIVATE_OPT +{"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E}, +{"ps", "RTP payload size in bytes", OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#if FF_API_STAT_BITS +{"mv_bits", NULL, OFFSET(mv_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"header_bits", NULL, OFFSET(header_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"i_tex_bits", NULL, OFFSET(i_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"p_tex_bits", NULL, OFFSET(p_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"i_count", NULL, OFFSET(i_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"p_count", NULL, OFFSET(p_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"skip_count", NULL, OFFSET(skip_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"misc_bits", NULL, OFFSET(misc_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"frame_bits", NULL, OFFSET(frame_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif +{"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"}, +{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"}, +#if FF_API_OLD_MSMPEG4 +{"old_msmpeg4", "some old lavc-generated MSMPEG4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"}, +#endif +{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"}, +{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"}, +{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"}, +#if FF_API_AC_VLC +{"ac_vlc", "illegal VLC bug (autodetected per FOURCC)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"}, +#endif +{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"}, +{"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"}, +{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"}, +{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"}, +{"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"}, +{"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"}, +{"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"}, +{"iedge", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_IEDGE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, +{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"careful", "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +#if FF_API_PRIVATE_OPT +{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#if FF_API_MPV_OPT +{"qsquish", "deprecated, use encoder private options instead", OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E}, +{"rc_qmod_amp", "deprecated, use encoder private options instead", OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E}, +{"rc_qmod_freq", "deprecated, use encoder private options instead", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#if FF_API_MPV_OPT +{"rc_eq", "deprecated, use encoder private options instead", OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E}, +#endif +{"maxrate", "maximum bitrate (in bits/s). Used for VBV together with bufsize.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT_MAX, V|A|E}, +{"minrate", "minimum bitrate (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.", + OFFSET(rc_min_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|E}, +#if FF_API_MPV_OPT +{"rc_buf_aggressivity", "deprecated, use encoder private options instead", OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, V|E}, +#endif +{"i_qfactor", "QP factor between P- and I-frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E}, +{"i_qoffset", "QP offset between P- and I-frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E}, +#if FF_API_MPV_OPT +{"rc_init_cplx", "deprecated, use encoder private options instead", OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E}, +#endif +{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"}, +{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"}, +{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"}, +{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"}, +{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"}, +{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"p_mask", "inter masking", OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"}, +{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_SH4 +{"sh4", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif +{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_ALPHA +{"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif +#if FF_API_UNUSED_MEMBERS +{"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif /* FF_API_UNUSED_MEMBERS */ +{"xvid", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvidmmx", "deprecated, for compatibility only", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"}, +{"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"slice_count", NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 = 3 }, INT_MIN, INT_MAX, V|D, "ec"}, +{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"}, +{"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"}, +{"favor_inter", "favor predicting from the previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, "ec"}, +{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +#if FF_API_PRIVATE_OPT +{"pred", "prediction method", OFFSET(prediction_method), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"}, +{"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"}, +{"plane", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_PLANE }, INT_MIN, INT_MAX, V|E, "pred"}, +{"median", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_MEDIAN }, INT_MIN, INT_MAX, V|E, "pred"}, +#endif +{"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E}, +{"sar", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E}, +{"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"}, +{"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"}, +{"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"}, +{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"}, +{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, +{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_DEBUG_MV +{"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif +{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"}, +{"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, "debug"}, +{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"}, +{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_UNUSED_MEMBERS +{"pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PTS }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif /* FF_API_UNUSED_MEMBERS */ +{"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"}, +{"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"}, +{"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_DEBUG_MV +{"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"}, +{"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif +{"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"}, +{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"}, +{"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"}, +#if FF_API_VISMV +{"vismv", "visualize motion vectors (MVs) (deprecated)", OFFSET(debug_mv), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"}, +{"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"}, +{"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"}, +{"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_BACK }, INT_MIN, INT_MAX, V|D, "debug_mv"}, +#endif +{"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"preme", "pre motion estimation", OFFSET(pre_me), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"sad", "sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"bit", "number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"zero", "0", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +#if CONFIG_SNOW_ENCODER +{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +#endif +{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"msad", "sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E}, +#if FF_API_AFD +{"dtg_active_format", NULL, OFFSET(dtg_active_format), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif +{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#if FF_API_QUANT_BIAS +{"ibias", "intra quant bias", OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E}, +{"pbias", "inter quant bias", OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E}, +#endif +{"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +#if FF_API_CODER_TYPE +{"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"}, +{"vlc", "variable length coder / Huffman coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"}, +{"ac", "arithmetic coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_AC }, INT_MIN, INT_MAX, V|E, "coder"}, +{"raw", "raw (no encoding)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RAW }, INT_MIN, INT_MAX, V|E, "coder"}, +{"rle", "run-length coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RLE }, INT_MIN, INT_MAX, V|E, "coder"}, +#if FF_API_UNUSED_MEMBERS +{"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"}, +#endif /* FF_API_UNUSED_MEMBERS */ +#endif /* FF_API_CODER_TYPE */ +#if FF_API_PRIVATE_OPT +{"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#if FF_API_XVMC +{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif /* FF_API_XVMC */ +{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"}, +{"simple", "use mbcmp", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"}, +{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"}, +{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"}, +#if FF_API_STREAM_CODEC_TAG +{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif +#if FF_API_PRIVATE_OPT +{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#if FF_API_MPV_OPT +{"lmin", "deprecated, use encoder private options instead", OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E}, +{"lmax", "deprecated, use encoder private options instead", OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E}, +#endif +#if FF_API_PRIVATE_OPT +{"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"}, +#if FF_API_ERROR_RATE +{"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"threads", "set the number of threads", OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"}, +{"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"}, +#if FF_API_MPV_OPT +{"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, -8, 16, V|E}, +{"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E}, +{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D}, +{"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D}, +{"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"aac_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_MAIN }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ssr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_SSR }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ltp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LTP }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_he_v2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE_V2 }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LD }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_eld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_ELD }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg2_aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg2_aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_hd_hra", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg4_sp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_core", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_CORE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_MAIN }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_asp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_ADVANCED_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"main10", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, V|E, "profile"}, +{"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, +{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, +{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D}, +#if FF_API_PRIVATE_OPT +{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +#endif +#if FF_API_MPV_OPT +{"border_mask", "deprecated, use encoder private options instead", OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E}, +#endif +{"mblmin", "minimum macroblock Lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E}, +{"mblmax", "maximum macroblock Lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, V|E}, +#endif +{"skip_loop_filter", "skip loop filtering process for the selected frames", OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"skip_idct" , "skip IDCT/dequantization for the selected frames", OFFSET(skip_idct), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"skip_frame" , "skip decoding for the selected frames", OFFSET(skip_frame), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"none" , "discard no frame", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"default" , "discard useless frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"noref" , "discard all non-reference frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"bidir" , "discard all bidirectional frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"nokey" , "discard all frames except keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"nointra" , "discard all frames except I frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"all" , "discard all frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, 4, V|E}, +#if FF_API_PRIVATE_OPT +{"brd_scale", "downscale frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 10, V|E}, +#endif +{"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, V|E}, +{"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.i64 = 1 }, INT_MIN, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"chromaoffset", "chroma QP offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +#if FF_API_UNUSED_MEMBERS +{"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), AV_OPT_TYPE_INT, {.i64 = 6 }, 0, INT_MAX, V|E}, +#endif /* FF_API_UNUSED_MEMBERS */ +{"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"b_sensitivity", "adjust sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, V|E}, +#endif +{"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +#if FF_API_PRIVATE_OPT +{"min_prediction_order", NULL, OFFSET(min_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E}, +{"max_prediction_order", NULL, OFFSET(max_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E}, +{"timecode_frame_start", "GOP timecode frame start number, in non-drop-frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = -1 }, -1, INT64_MAX, V|E}, +#endif +{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_UINT64, {.i64 = DEFAULT }, 0, UINT64_MAX, A|E|D, "channel_layout"}, +{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_UINT64, {.i64 = DEFAULT }, 0, UINT64_MAX, A|D, "request_channel_layout"}, +{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E}, +{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E}, +{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D}, +{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt470m", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"film", "Film", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_FILM }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt2020", "BT.2020", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte431", "SMPTE 431-2", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE431 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte432", "SMPTE 422-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE432 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"jedec-p22", "JEDEC P22", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_JEDEC_P22 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_trc_type"}, +{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"gamma22", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"gamma28", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"linear", "Linear", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log100", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log316", "Log square root", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"iec61966-2-4", "IEC 61966-2-4", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt1361e", "BT.1361", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"iec61966-2-1", "IEC 61966-2-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt2020-10", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt2020-12", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte2084", "SMPTE 2084", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE2084 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"arib-std-b67", "ARIB STD-B67", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_ARIB_STD_B67 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log_sqrt", "Log square root", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"iec61966_2_4", "IEC 61966-2-4", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt1361", "BT.1361", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"iec61966_2_1", "IEC 61966-2-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt2020_10bit", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "colorspace_type"}, +{"rgb", "RGB", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"fcc", "FCC", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycgco", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020nc", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020c", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte2085", "SMPTE 2085", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycocg", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, "color_range_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"tv", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"pc", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"jpeg", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"left", "Left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"center", "Center", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"topleft", "Top-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOPLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"top", "Top", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOP }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"bottomleft", "Bottom-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOMLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"bottom", "Bottom", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOM }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX }, +{"slices", "set the number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E}, +{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"}, +{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, +{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, +{"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"}, +{"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"ef", "Effects", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"vi", "Visually Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"hi", "Hearing Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"di", "Dialogue", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_DIALOGUE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"co", "Commentary", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_COMMENTARY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, "request_sample_fmt"}, +{"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0}, +{"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, S|D}, +{"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, "sub_charenc_mode"}, +{"do_nothing", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +#if FF_API_ASS_TIMING +{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, 0, 1, S|D, "sub_text_format"}, +#else +{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS}, 0, 1, S|D, "sub_text_format"}, +#endif +{"ass", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS}, INT_MIN, INT_MAX, S|D, "sub_text_format"}, +#if FF_API_ASS_TIMING +{"ass_with_timings", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, INT_MIN, INT_MAX, S|D, "sub_text_format"}, +#endif +{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|V|D }, +#if FF_API_SIDEDATA_ONLY_PKT +{"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, A|V|E }, +#endif +{"apply_cropping", NULL, OFFSET(apply_cropping), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, V | D }, +{"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, V|D }, +{"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" }, +{"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" }, +{"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, "field_order" }, +{"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, "field_order" }, +{"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" }, +{"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" }, +{"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, A|V|S|D|E}, +{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, A|V|S|D }, +{"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 }, +{"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 }, +{"max_pixels", "Maximum number of pixels", OFFSET(max_pixels), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|V|S|D|E }, +{"hwaccel_flags", NULL, OFFSET(hwaccel_flags), AV_OPT_TYPE_FLAGS, {.i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, 0, UINT_MAX, V|D, "hwaccel_flags"}, +{"ignore_level", "ignore level even if the codec level used is unknown or higher than the maximum supported level reported by the hardware driver", 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, INT_MIN, INT_MAX, V | D, "hwaccel_flags" }, +{"allow_high_depth", "allow to output YUV pixel formats with a different chroma sampling than 4:2:0 and/or other than 8 bits per component", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, +{"allow_profile_mismatch", "attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, +{NULL}, +}; + +#undef A +#undef V +#undef S +#undef E +#undef D +#undef DEFAULT +#undef OFFSET + +#endif /* AVCODEC_OPTIONS_TABLE_H */ diff --git a/media/ffvpx/libavcodec/parser.c b/media/ffvpx/libavcodec/parser.c index 30cfc55cb..670680ea7 100644 --- a/media/ffvpx/libavcodec/parser.c +++ b/media/ffvpx/libavcodec/parser.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <inttypes.h> #include <stdint.h> #include <string.h> @@ -251,7 +252,7 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) { if (pc->overread) { - ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); @@ -284,6 +285,8 @@ int ff_combine_frame(ParseContext *pc, int next, return -1; } + av_assert0(next >= 0 || pc->buffer); + *buf_size = pc->overread_index = pc->index + next; @@ -314,7 +317,7 @@ int ff_combine_frame(ParseContext *pc, int next, } if (pc->overread) { - ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); diff --git a/media/ffvpx/libavcodec/pixblockdsp.h b/media/ffvpx/libavcodec/pixblockdsp.h index 79ed86c3a..e036700ff 100644 --- a/media/ffvpx/libavcodec/pixblockdsp.h +++ b/media/ffvpx/libavcodec/pixblockdsp.h @@ -21,16 +21,23 @@ #include <stdint.h> +#include "config.h" + #include "avcodec.h" typedef struct PixblockDSPContext { - void (*get_pixels)(int16_t *block /* align 16 */, + void (*get_pixels)(int16_t *av_restrict block /* align 16 */, const uint8_t *pixels /* align 8 */, - ptrdiff_t line_size); - void (*diff_pixels)(int16_t *block /* align 16 */, + ptrdiff_t stride); + void (*diff_pixels)(int16_t *av_restrict block /* align 16 */, const uint8_t *s1 /* align 8 */, const uint8_t *s2 /* align 8 */, - int stride); + ptrdiff_t stride); + void (*diff_pixels_unaligned)(int16_t *av_restrict block /* align 16 */, + const uint8_t *s1, + const uint8_t *s2, + ptrdiff_t stride); + } PixblockDSPContext; void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx); diff --git a/media/ffvpx/libavcodec/profiles.c b/media/ffvpx/libavcodec/profiles.c index da745e139..30498efed 100644 --- a/media/ffvpx/libavcodec/profiles.c +++ b/media/ffvpx/libavcodec/profiles.c @@ -46,6 +46,16 @@ const AVProfile ff_dca_profiles[] = { { FF_PROFILE_UNKNOWN }, }; +const AVProfile ff_dnxhd_profiles[] = { + { FF_PROFILE_DNXHD, "DNXHD"}, + { FF_PROFILE_DNXHR_LB, "DNXHR LB"}, + { FF_PROFILE_DNXHR_SQ, "DNXHR SQ"}, + { FF_PROFILE_DNXHR_HQ, "DNXHR HQ" }, + { FF_PROFILE_DNXHR_HQX, "DNXHR HQX"}, + { FF_PROFILE_DNXHR_444, "DNXHR 444"}, + { FF_PROFILE_UNKNOWN }, +}; + const AVProfile ff_h264_profiles[] = { { FF_PROFILE_H264_BASELINE, "Baseline" }, { FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline" }, @@ -60,6 +70,8 @@ const AVProfile ff_h264_profiles[] = { { FF_PROFILE_H264_HIGH_444_PREDICTIVE, "High 4:4:4 Predictive" }, { FF_PROFILE_H264_HIGH_444_INTRA, "High 4:4:4 Intra" }, { FF_PROFILE_H264_CAVLC_444, "CAVLC 4:4:4" }, + { FF_PROFILE_H264_MULTIVIEW_HIGH, "Multiview High" }, + { FF_PROFILE_H264_STEREO_HIGH, "Stereo High" }, { FF_PROFILE_UNKNOWN }, }; diff --git a/media/ffvpx/libavcodec/profiles.h b/media/ffvpx/libavcodec/profiles.h index c86c683ab..eb18b406a 100644 --- a/media/ffvpx/libavcodec/profiles.h +++ b/media/ffvpx/libavcodec/profiles.h @@ -23,6 +23,7 @@ extern const AVProfile ff_aac_profiles[]; extern const AVProfile ff_dca_profiles[]; +extern const AVProfile ff_dnxhd_profiles[]; extern const AVProfile ff_h264_profiles[]; extern const AVProfile ff_hevc_profiles[]; extern const AVProfile ff_jpeg2000_profiles[]; diff --git a/media/ffvpx/libavcodec/pthread_frame.c b/media/ffvpx/libavcodec/pthread_frame.c index a10fcbfe7..2c702c737 100644 --- a/media/ffvpx/libavcodec/pthread_frame.c +++ b/media/ffvpx/libavcodec/pthread_frame.c @@ -24,9 +24,11 @@ #include "config.h" +#include <stdatomic.h> #include <stdint.h> #include "avcodec.h" +#include "hwaccel.h" #include "internal.h" #include "pthread_internal.h" #include "thread.h" @@ -43,29 +45,28 @@ #include "libavutil/opt.h" #include "libavutil/thread.h" -#if defined(MOZ_TSAN) -typedef _Atomic(int) atomic_int; -#else -typedef volatile int atomic_int; -#endif +enum { + ///< Set when the thread is awaiting a packet. + STATE_INPUT_READY, + ///< Set before the codec has called ff_thread_finish_setup(). + STATE_SETTING_UP, + /** + * Set when the codec calls get_buffer(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_BUFFER, + /** + * Set when the codec calls get_format(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_FORMAT, + ///< Set after the codec has called ff_thread_finish_setup(). + STATE_SETUP_FINISHED, +}; /** * Context used by codec threads and stored in their AVCodecInternal thread_ctx. */ -typedef enum { - STATE_INPUT_READY, ///< Set when the thread is awaiting a packet. - STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup(). - STATE_GET_BUFFER, /**< - * Set when the codec calls get_buffer(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_GET_FORMAT, /**< - * Set when the codec calls get_format(). - * State is returned to STATE_SETTING_UP afterwards. - */ - STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup(). -} State; - typedef struct PerThreadContext { struct FrameThreadContext *parent; @@ -103,6 +104,11 @@ typedef struct PerThreadContext { enum AVPixelFormat result_format; ///< get_format() result int die; ///< Set when the thread should exit. + + int hwaccel_serializing; + int async_serializing; + + atomic_int debug_threads; ///< Set if the FF_DEBUG_THREADS option is set. } PerThreadContext; /** @@ -113,6 +119,14 @@ typedef struct FrameThreadContext { PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). + /** + * This lock is used for ensuring threads run in serial when hwaccel + * is used. + */ + pthread_mutex_t hwaccel_mutex; + pthread_mutex_t async_mutex; + pthread_cond_t async_cond; + int async_lock; int next_decoding; ///< The next context to submit a packet to. int next_finished; ///< The next context to return output from. @@ -126,6 +140,24 @@ typedef struct FrameThreadContext { #define THREAD_SAFE_CALLBACKS(avctx) \ ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2) +static void async_lock(FrameThreadContext *fctx) +{ + pthread_mutex_lock(&fctx->async_mutex); + while (fctx->async_lock) + pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex); + fctx->async_lock = 1; + pthread_mutex_unlock(&fctx->async_mutex); +} + +static void async_unlock(FrameThreadContext *fctx) +{ + pthread_mutex_lock(&fctx->async_mutex); + av_assert0(fctx->async_lock); + fctx->async_lock = 0; + pthread_cond_broadcast(&fctx->async_cond); + pthread_mutex_unlock(&fctx->async_mutex); +} + /** * Codec worker thread. * @@ -141,14 +173,29 @@ static attribute_align_arg void *frame_worker_thread(void *arg) pthread_mutex_lock(&p->mutex); while (1) { - while (p->state == STATE_INPUT_READY && !p->die) - pthread_cond_wait(&p->input_cond, &p->mutex); + while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die) + pthread_cond_wait(&p->input_cond, &p->mutex); if (p->die) break; if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx)) ff_thread_finish_setup(avctx); + /* If a decoder supports hwaccel, then it must call ff_get_format(). + * Since that call must happen before ff_thread_finish_setup(), the + * decoder is required to implement update_thread_context() and call + * ff_thread_finish_setup() manually. Therefore the above + * ff_thread_finish_setup() call did not happen and hwaccel_serializing + * cannot be true here. */ + av_assert0(!p->hwaccel_serializing); + + /* if the previous thread uses hwaccel then we take the lock to ensure + * the threads don't run concurrently */ + if (avctx->hwaccel) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + av_frame_unref(p->frame); p->got_frame = 0; p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt); @@ -160,17 +207,23 @@ static attribute_align_arg void *frame_worker_thread(void *arg) av_frame_unref(p->frame); } - if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx); + if (atomic_load(&p->state) == STATE_SETTING_UP) + ff_thread_finish_setup(avctx); + + if (p->hwaccel_serializing) { + p->hwaccel_serializing = 0; + pthread_mutex_unlock(&p->parent->hwaccel_mutex); + } + + if (p->async_serializing) { + p->async_serializing = 0; + + async_unlock(p->parent); + } pthread_mutex_lock(&p->progress_mutex); -#if 0 //BUFREF-FIXME - for (i = 0; i < MAX_BUFFERS; i++) - if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) { - p->progress[i][0] = INT_MAX; - p->progress[i][1] = INT_MAX; - } -#endif - p->state = STATE_INPUT_READY; + + atomic_store(&p->state, STATE_INPUT_READY); pthread_cond_broadcast(&p->progress_cond); pthread_cond_signal(&p->output_cond); @@ -193,12 +246,13 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, { int err = 0; - if (dst != src) { + if (dst != src && (for_user || !(av_codec_get_codec_descriptor(src)->props & AV_CODEC_PROP_INTRA_ONLY))) { dst->time_base = src->time_base; dst->framerate = src->framerate; dst->width = src->width; dst->height = src->height; dst->pix_fmt = src->pix_fmt; + dst->sw_pix_fmt = src->sw_pix_fmt; dst->coded_width = src->coded_width; dst->coded_height = src->coded_height; @@ -234,6 +288,19 @@ FF_ENABLE_DEPRECATION_WARNINGS dst->sample_fmt = src->sample_fmt; dst->channel_layout = src->channel_layout; dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; + + if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx || + (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) { + av_buffer_unref(&dst->hw_frames_ctx); + + if (src->hw_frames_ctx) { + dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dst->hw_frames_ctx) + return AVERROR(ENOMEM); + } + } + + dst->hwaccel_flags = src->hwaccel_flags; } if (for_user) { @@ -315,24 +382,35 @@ static void release_delayed_buffers(PerThreadContext *p) } } -static int submit_packet(PerThreadContext *p, AVPacket *avpkt) +static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, + AVPacket *avpkt) { FrameThreadContext *fctx = p->parent; PerThreadContext *prev_thread = fctx->prev_thread; const AVCodec *codec = p->avctx->codec; + int ret; if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY)) return 0; pthread_mutex_lock(&p->mutex); + ret = update_context_from_user(p->avctx, user_avctx); + if (ret) { + pthread_mutex_unlock(&p->mutex); + return ret; + } + atomic_store_explicit(&p->debug_threads, + (p->avctx->debug & FF_DEBUG_THREADS) != 0, + memory_order_relaxed); + release_delayed_buffers(p); if (prev_thread) { int err; - if (prev_thread->state == STATE_SETTING_UP) { + if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) { pthread_mutex_lock(&prev_thread->progress_mutex); - while (prev_thread->state == STATE_SETTING_UP) + while (atomic_load(&prev_thread->state) == STATE_SETTING_UP) pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex); pthread_mutex_unlock(&prev_thread->progress_mutex); } @@ -345,9 +423,14 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) } av_packet_unref(&p->avpkt); - av_packet_ref(&p->avpkt, avpkt); + ret = av_packet_ref(&p->avpkt, avpkt); + if (ret < 0) { + pthread_mutex_unlock(&p->mutex); + av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n"); + return ret; + } - p->state = STATE_SETTING_UP; + atomic_store(&p->state, STATE_SETTING_UP); pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); @@ -360,14 +443,13 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) if (!p->avctx->thread_safe_callbacks && ( p->avctx->get_format != avcodec_default_get_format || p->avctx->get_buffer2 != avcodec_default_get_buffer2)) { - while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) { + while (atomic_load(&p->state) != STATE_SETUP_FINISHED && atomic_load(&p->state) != STATE_INPUT_READY) { int call_done = 1; pthread_mutex_lock(&p->progress_mutex); - while (p->state == STATE_SETTING_UP) + while (atomic_load(&p->state) == STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); - State p_state = (State)p->state; - switch (p_state) { + switch (atomic_load_explicit(&p->state, memory_order_acquire)) { case STATE_GET_BUFFER: p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); break; @@ -379,7 +461,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) break; } if (call_done) { - p->state = STATE_SETTING_UP; + atomic_store(&p->state, STATE_SETTING_UP); pthread_cond_signal(&p->progress_cond); } pthread_mutex_unlock(&p->progress_mutex); @@ -401,15 +483,18 @@ int ff_thread_decode_frame(AVCodecContext *avctx, PerThreadContext *p; int err; + /* release the async lock, permitting blocked hwaccel threads to + * go forward while we are in this function */ + async_unlock(fctx); + /* * Submit a packet to the next decoding thread. */ p = &fctx->threads[fctx->next_decoding]; - err = update_context_from_user(p->avctx, avctx); - if (err) return err; - err = submit_packet(p, avpkt); - if (err) return err; + err = submit_packet(p, avctx, avpkt); + if (err) + goto finish; /* * If we're still receiving the initial packets, don't return a frame. @@ -420,23 +505,25 @@ int ff_thread_decode_frame(AVCodecContext *avctx, if (fctx->delaying) { *got_picture_ptr=0; - if (avpkt->size) - return avpkt->size; + if (avpkt->size) { + err = avpkt->size; + goto finish; + } } /* * Return the next available frame from the oldest thread. * If we're at the end of the stream, then we have to skip threads that - * didn't output a frame, because we don't want to accidentally signal - * EOF (avpkt->size == 0 && *got_picture_ptr == 0). + * didn't output a frame/error, because we don't want to accidentally signal + * EOF (avpkt->size == 0 && *got_picture_ptr == 0 && err >= 0). */ do { p = &fctx->threads[finished++]; - if (p->state != STATE_INPUT_READY) { + if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) + while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -444,20 +531,19 @@ int ff_thread_decode_frame(AVCodecContext *avctx, av_frame_move_ref(picture, p->frame); *got_picture_ptr = p->got_frame; picture->pkt_dts = p->avpkt.dts; - - if (p->result < 0) - err = p->result; + err = p->result; /* * A later call with avkpt->size == 0 may loop over all threads, - * including this one, searching for a frame to return before being + * including this one, searching for a frame/error to return before being * stopped by the "finished != fctx->next_finished" condition. - * Make sure we don't mistakenly return the same frame again. + * Make sure we don't mistakenly return the same frame/error again. */ p->got_frame = 0; + p->result = 0; if (finished >= avctx->thread_count) finished = 0; - } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished); + } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished); update_context_from_thread(avctx, p->avctx, 1); @@ -465,16 +551,12 @@ int ff_thread_decode_frame(AVCodecContext *avctx, fctx->next_finished = finished; - /* - * When no frame was found while flushing, but an error occurred in - * any thread, return it instead of 0. - * Otherwise the error can get lost. - */ - if (!avpkt->size && !*got_picture_ptr) - return err; - /* return the size of the consumed packet if no error occurred */ - return (p->result >= 0) ? avpkt->size : p->result; + if (err >= 0) + err = avpkt->size; +finish: + async_lock(fctx); + return err; } void ff_thread_report_progress(ThreadFrame *f, int n, int field) @@ -482,15 +564,20 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) PerThreadContext *p; atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; - if (!progress || progress[field] >= n) return; + if (!progress || + atomic_load_explicit(&progress[field], memory_order_relaxed) >= n) + return; - p = f->owner->internal->thread_ctx; + p = f->owner[field]->internal->thread_ctx; - if (f->owner->debug&FF_DEBUG_THREADS) - av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field); + if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed)) + av_log(f->owner[field], AV_LOG_DEBUG, + "%p finished %d field %d\n", progress, n, field); pthread_mutex_lock(&p->progress_mutex); - progress[field] = n; + + atomic_store_explicit(&progress[field], n, memory_order_release); + pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); } @@ -500,15 +587,18 @@ void ff_thread_await_progress(ThreadFrame *f, int n, int field) PerThreadContext *p; atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; - if (!progress || progress[field] >= n) return; + if (!progress || + atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + return; - p = f->owner->internal->thread_ctx; + p = f->owner[field]->internal->thread_ctx; - if (f->owner->debug&FF_DEBUG_THREADS) - av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress); + if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed)) + av_log(f->owner[field], AV_LOG_DEBUG, + "thread awaiting %d field %d from %p\n", n, field, progress); pthread_mutex_lock(&p->progress_mutex); - while (progress[field] < n) + while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } @@ -518,12 +608,26 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; - if(p->state == STATE_SETUP_FINISHED){ - av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); + if (avctx->hwaccel && !p->hwaccel_serializing) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + + /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */ + if (avctx->hwaccel && + !(avctx->hwaccel->caps_internal & HWACCEL_CAP_ASYNC_SAFE)) { + p->async_serializing = 1; + + async_lock(p->parent); } pthread_mutex_lock(&p->progress_mutex); - p->state = STATE_SETUP_FINISHED; + if(atomic_load(&p->state) == STATE_SETUP_FINISHED){ + av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); + } + + atomic_store(&p->state, STATE_SETUP_FINISHED); + pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); } @@ -533,17 +637,21 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count { int i; + async_unlock(fctx); + for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; - if (p->state != STATE_INPUT_READY) { + if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); - while (p->state != STATE_INPUT_READY) + while (atomic_load(&p->state) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } p->got_frame = 0; } + + async_lock(fctx); } void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) @@ -596,13 +704,20 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_freep(&p->avctx->slice_offset); } - if (p->avctx) + if (p->avctx) { av_freep(&p->avctx->internal); + av_buffer_unref(&p->avctx->hw_frames_ctx); + } + av_freep(&p->avctx); } av_freep(&fctx->threads); pthread_mutex_destroy(&fctx->buffer_mutex); + pthread_mutex_destroy(&fctx->hwaccel_mutex); + pthread_mutex_destroy(&fctx->async_mutex); + pthread_cond_destroy(&fctx->async_cond); + av_freep(&avctx->internal->thread_ctx); if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) @@ -624,8 +739,10 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (!thread_count) { int nb_cpus = av_cpu_count(); +#if FF_API_DEBUG_MV if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv) nb_cpus = 1; +#endif // use number of cores + 1 as thread count if there is more than one if (nb_cpus > 1) thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); @@ -649,6 +766,11 @@ int ff_frame_thread_init(AVCodecContext *avctx) } pthread_mutex_init(&fctx->buffer_mutex, NULL); + pthread_mutex_init(&fctx->hwaccel_mutex, NULL); + pthread_mutex_init(&fctx->async_mutex, NULL); + pthread_cond_init(&fctx->async_cond, NULL); + + fctx->async_lock = 1; fctx->delaying = 1; for (i = 0; i < thread_count; i++) { @@ -686,7 +808,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) } *copy->internal = *src->internal; copy->internal->thread_ctx = p; - copy->internal->pkt = &p->avpkt; + copy->internal->last_pkt_props = &p->avpkt; if (!i) { src = copy; @@ -710,6 +832,8 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (err) goto error; + atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); + err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); p->thread_init= !err; if(!p->thread_init) @@ -745,6 +869,7 @@ void ff_thread_flush(AVCodecContext *avctx) // Make sure decode flush calls with size=0 won't return old frames p->got_frame = 0; av_frame_unref(p->frame); + p->result = 0; release_delayed_buffers(p); @@ -756,7 +881,7 @@ void ff_thread_flush(AVCodecContext *avctx) int ff_thread_can_start_frame(AVCodecContext *avctx) { PerThreadContext *p = avctx->internal->thread_ctx; - if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP && + if ((avctx->active_thread_type&FF_THREAD_FRAME) && atomic_load(&p->state) != STATE_SETTING_UP && (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { return 0; } @@ -768,28 +893,29 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int PerThreadContext *p = avctx->internal->thread_ctx; int err; - f->owner = avctx; + f->owner[0] = f->owner[1] = avctx; ff_init_buffer_info(avctx, f->f); if (!(avctx->active_thread_type & FF_THREAD_FRAME)) return ff_get_buffer(avctx, f->f, flags); - if (p->state != STATE_SETTING_UP && + if (atomic_load(&p->state) != STATE_SETTING_UP && (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); return -1; } if (avctx->internal->allocate_progress) { - int *progress; - f->progress = av_buffer_alloc(2 * sizeof(int)); + atomic_int *progress; + f->progress = av_buffer_alloc(2 * sizeof(*progress)); if (!f->progress) { return AVERROR(ENOMEM); } - progress = (int*)f->progress->data; + progress = (atomic_int*)f->progress->data; - progress[0] = progress[1] = -1; + atomic_init(&progress[0], -1); + atomic_init(&progress[1], -1); } pthread_mutex_lock(&p->parent->buffer_mutex); @@ -800,10 +926,10 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int pthread_mutex_lock(&p->progress_mutex); p->requested_frame = f->f; p->requested_flags = flags; - p->state = STATE_GET_BUFFER; + atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release); pthread_cond_broadcast(&p->progress_cond); - while (p->state != STATE_SETTING_UP) + while (atomic_load(&p->state) != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); err = p->result; @@ -828,16 +954,16 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks || avctx->get_format == avcodec_default_get_format) return ff_get_format(avctx, fmt); - if (p->state != STATE_SETTING_UP) { + if (atomic_load(&p->state) != STATE_SETTING_UP) { av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n"); return -1; } pthread_mutex_lock(&p->progress_mutex); p->available_formats = fmt; - p->state = STATE_GET_FORMAT; + atomic_store(&p->state, STATE_GET_FORMAT); pthread_cond_broadcast(&p->progress_cond); - while (p->state != STATE_SETTING_UP) + while (atomic_load(&p->state) != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); res = p->result_format; @@ -871,7 +997,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f); av_buffer_unref(&f->progress); - f->owner = NULL; + f->owner[0] = f->owner[1] = NULL; if (can_direct_free) { av_frame_unref(f->f); diff --git a/media/ffvpx/libavcodec/pthread_slice.c b/media/ffvpx/libavcodec/pthread_slice.c index 96a7643f6..d659f9b0b 100644 --- a/media/ffvpx/libavcodec/pthread_slice.c +++ b/media/ffvpx/libavcodec/pthread_slice.c @@ -34,26 +34,21 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/thread.h" +#include "libavutil/slicethread.h" typedef int (action_func)(AVCodecContext *c, void *arg); typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); +typedef int (main_func)(AVCodecContext *c); typedef struct SliceThreadContext { - pthread_t *workers; + AVSliceThread *thread; action_func *func; action_func2 *func2; + main_func *mainfunc; void *args; int *rets; - int job_count; int job_size; - pthread_cond_t last_job_cond; - pthread_cond_t current_job_cond; - pthread_mutex_t current_job_lock; - unsigned current_execute; - int current_job; - int done; - int *entries; int entries_count; int thread_count; @@ -61,43 +56,22 @@ typedef struct SliceThreadContext { pthread_mutex_t *progress_mutex; } SliceThreadContext; -static void* attribute_align_arg worker(void *v) -{ - AVCodecContext *avctx = v; +static void main_function(void *priv) { + AVCodecContext *avctx = priv; SliceThreadContext *c = avctx->internal->thread_ctx; - unsigned last_execute = 0; - int our_job = c->job_count; - int thread_count = avctx->thread_count; - int self_id; - - pthread_mutex_lock(&c->current_job_lock); - self_id = c->current_job++; - for (;;){ - int ret; - while (our_job >= c->job_count) { - if (c->current_job == thread_count + c->job_count) - pthread_cond_signal(&c->last_job_cond); - - while (last_execute == c->current_execute && !c->done) - pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); - last_execute = c->current_execute; - our_job = self_id; - - if (c->done) { - pthread_mutex_unlock(&c->current_job_lock); - return NULL; - } - } - pthread_mutex_unlock(&c->current_job_lock); + c->mainfunc(avctx); +} - ret = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size): - c->func2(avctx, c->args, our_job, self_id); - if (c->rets) - c->rets[our_job%c->job_count] = ret; +static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads) +{ + AVCodecContext *avctx = priv; + SliceThreadContext *c = avctx->internal->thread_ctx; + int ret; - pthread_mutex_lock(&c->current_job_lock); - our_job = c->current_job++; - } + ret = c->func ? c->func(avctx, (char *)c->args + c->job_size * jobnr) + : c->func2(avctx, c->args, jobnr, threadnr); + if (c->rets) + c->rets[jobnr] = ret; } void ff_slice_thread_free(AVCodecContext *avctx) @@ -105,40 +79,19 @@ void ff_slice_thread_free(AVCodecContext *avctx) SliceThreadContext *c = avctx->internal->thread_ctx; int i; - pthread_mutex_lock(&c->current_job_lock); - c->done = 1; - pthread_cond_broadcast(&c->current_job_cond); - for (i = 0; i < c->thread_count; i++) - pthread_cond_broadcast(&c->progress_cond[i]); - pthread_mutex_unlock(&c->current_job_lock); - - for (i=0; i<avctx->thread_count; i++) - pthread_join(c->workers[i], NULL); + avpriv_slicethread_free(&c->thread); for (i = 0; i < c->thread_count; i++) { pthread_mutex_destroy(&c->progress_mutex[i]); pthread_cond_destroy(&c->progress_cond[i]); } - pthread_mutex_destroy(&c->current_job_lock); - pthread_cond_destroy(&c->current_job_cond); - pthread_cond_destroy(&c->last_job_cond); - av_freep(&c->entries); av_freep(&c->progress_mutex); av_freep(&c->progress_cond); - - av_freep(&c->workers); av_freep(&avctx->internal->thread_ctx); } -static av_always_inline void thread_park_workers(SliceThreadContext *c, int thread_count) -{ - while (c->current_job != thread_count + c->job_count) - pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); - pthread_mutex_unlock(&c->current_job_lock); -} - static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size) { SliceThreadContext *c = avctx->internal->thread_ctx; @@ -149,23 +102,12 @@ static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, i if (job_count <= 0) return 0; - pthread_mutex_lock(&c->current_job_lock); - - c->current_job = avctx->thread_count; - c->job_count = job_count; c->job_size = job_size; c->args = arg; c->func = func; - if (ret) { - c->rets = ret; - } else { - c->rets = NULL; - } - c->current_execute++; - pthread_cond_broadcast(&c->current_job_cond); - - thread_park_workers(c, avctx->thread_count); + c->rets = ret; + avpriv_slicethread_execute(c->thread, job_count, !!c->mainfunc ); return 0; } @@ -176,11 +118,19 @@ static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg return thread_execute(avctx, NULL, arg, ret, job_count, 0); } +int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, action_func2* func2, main_func *mainfunc, void *arg, int *ret, int job_count) +{ + SliceThreadContext *c = avctx->internal->thread_ctx; + c->func2 = func2; + c->mainfunc = mainfunc; + return thread_execute(avctx, NULL, arg, ret, job_count, 0); +} + int ff_slice_thread_init(AVCodecContext *avctx) { - int i; SliceThreadContext *c; int thread_count = avctx->thread_count; + static void (*mainfunc)(void *); #if HAVE_W32THREADS w32thread_init(); @@ -208,35 +158,17 @@ int ff_slice_thread_init(AVCodecContext *avctx) return 0; } - c = av_mallocz(sizeof(SliceThreadContext)); - if (!c) - return -1; - - c->workers = av_mallocz_array(thread_count, sizeof(pthread_t)); - if (!c->workers) { - av_free(c); - return -1; - } - - avctx->internal->thread_ctx = c; - c->current_job = 0; - c->job_count = 0; - c->job_size = 0; - c->done = 0; - pthread_cond_init(&c->current_job_cond, NULL); - pthread_cond_init(&c->last_job_cond, NULL); - pthread_mutex_init(&c->current_job_lock, NULL); - pthread_mutex_lock(&c->current_job_lock); - for (i=0; i<thread_count; i++) { - if(pthread_create(&c->workers[i], NULL, worker, avctx)) { - avctx->thread_count = i; - pthread_mutex_unlock(&c->current_job_lock); - ff_thread_free(avctx); - return -1; - } + avctx->internal->thread_ctx = c = av_mallocz(sizeof(*c)); + mainfunc = avctx->codec->caps_internal & FF_CODEC_CAP_SLICE_THREAD_HAS_MF ? &main_function : NULL; + if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, mainfunc, thread_count)) <= 1) { + if (c) + avpriv_slicethread_free(&c->thread); + av_freep(&avctx->internal->thread_ctx); + avctx->thread_count = 1; + avctx->active_thread_type = 0; + return 0; } - - thread_park_workers(c, thread_count); + avctx->thread_count = thread_count; avctx->execute = thread_execute; avctx->execute2 = thread_execute2; diff --git a/media/ffvpx/libavcodec/put_bits.h b/media/ffvpx/libavcodec/put_bits.h index 68ed39119..1ceb1cc76 100644 --- a/media/ffvpx/libavcodec/put_bits.h +++ b/media/ffvpx/libavcodec/put_bits.h @@ -119,6 +119,18 @@ static inline void flush_put_bits(PutBitContext *s) s->bit_buf = 0; } +static inline void flush_put_bits_le(PutBitContext *s) +{ + while (s->bit_left < 32) { + av_assert0(s->buf_ptr < s->buf_end); + *s->buf_ptr++ = s->bit_buf; + s->bit_buf >>= 8; + s->bit_left += 8; + } + s->bit_left = 32; + s->bit_buf = 0; +} + #ifdef BITSTREAM_WRITER_LE #define avpriv_align_put_bits align_put_bits_unsupported_here #define avpriv_put_string ff_put_string_unsupported_here @@ -197,6 +209,34 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) s->bit_left = bit_left; } +static inline void put_bits_le(PutBitContext *s, int n, unsigned int value) +{ + unsigned int bit_buf; + int bit_left; + + av_assert2(n <= 31 && value < (1U << n)); + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + + bit_buf |= value << (32 - bit_left); + if (n >= bit_left) { + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = value >> bit_left; + bit_left += 32; + } + bit_left -= n; + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + static inline void put_sbits(PutBitContext *pb, int n, int32_t value) { av_assert2(n >= 0 && n <= 31); @@ -209,15 +249,72 @@ static inline void put_sbits(PutBitContext *pb, int n, int32_t value) */ static void av_unused put_bits32(PutBitContext *s, uint32_t value) { - int lo = value & 0xffff; - int hi = value >> 16; + unsigned int bit_buf; + int bit_left; + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + #ifdef BITSTREAM_WRITER_LE - put_bits(s, 16, lo); - put_bits(s, 16, hi); + bit_buf |= value << (32 - bit_left); + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = (uint64_t)value >> bit_left; #else - put_bits(s, 16, hi); - put_bits(s, 16, lo); + bit_buf = (uint64_t)bit_buf << bit_left; + bit_buf |= value >> (32 - bit_left); + if (3 < s->buf_end - s->buf_ptr) { + AV_WB32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = value; #endif + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + +/** + * Write up to 64 bits into a bitstream. + */ +static inline void put_bits64(PutBitContext *s, int n, uint64_t value) +{ + av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); + + if (n < 32) + put_bits(s, n, value); + else if (n == 32) + put_bits32(s, value); + else if (n < 64) { + uint32_t lo = value & 0xffffffff; + uint32_t hi = value >> 32; +#ifdef BITSTREAM_WRITER_LE + put_bits32(s, lo); + put_bits(s, n - 32, hi); +#else + put_bits(s, n - 32, hi); + put_bits32(s, lo); +#endif + } else { + uint32_t lo = value & 0xffffffff; + uint32_t hi = value >> 32; +#ifdef BITSTREAM_WRITER_LE + put_bits32(s, lo); + put_bits32(s, hi); +#else + put_bits32(s, hi); + put_bits32(s, lo); +#endif + + } } /** diff --git a/media/ffvpx/libavcodec/ratecontrol.h b/media/ffvpx/libavcodec/ratecontrol.h index c15f9e258..2a7aaec64 100644 --- a/media/ffvpx/libavcodec/ratecontrol.h +++ b/media/ffvpx/libavcodec/ratecontrol.h @@ -96,8 +96,4 @@ void ff_rate_control_uninit(struct MpegEncContext *s); int ff_vbv_update(struct MpegEncContext *s, int frame_size); void ff_get_2pass_fcode(struct MpegEncContext *s); -int ff_xvid_rate_control_init(struct MpegEncContext *s); -void ff_xvid_rate_control_uninit(struct MpegEncContext *s); -float ff_xvid_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); - #endif /* AVCODEC_RATECONTROL_H */ diff --git a/media/ffvpx/libavcodec/raw.c b/media/ffvpx/libavcodec/raw.c index f73a134a9..8da2a9735 100644 --- a/media/ffvpx/libavcodec/raw.c +++ b/media/ffvpx/libavcodec/raw.c @@ -119,6 +119,12 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { AV_PIX_FMT_RGB48BE, MKTAG( 48, 'R', 'G', 'B') }, { AV_PIX_FMT_BGR48LE, MKTAG('B', 'G', 'R', 48 ) }, { AV_PIX_FMT_BGR48BE, MKTAG( 48, 'B', 'G', 'R') }, + { AV_PIX_FMT_GRAY9LE, MKTAG('Y', '1', 0 , 9 ) }, + { AV_PIX_FMT_GRAY9BE, MKTAG( 9 , 0 , '1', 'Y') }, + { AV_PIX_FMT_GRAY10LE, MKTAG('Y', '1', 0 , 10 ) }, + { AV_PIX_FMT_GRAY10BE, MKTAG(10 , 0 , '1', 'Y') }, + { AV_PIX_FMT_GRAY12LE, MKTAG('Y', '1', 0 , 12 ) }, + { AV_PIX_FMT_GRAY12BE, MKTAG(12 , 0 , '1', 'Y') }, { AV_PIX_FMT_GRAY16LE, MKTAG('Y', '1', 0 , 16 ) }, { AV_PIX_FMT_GRAY16BE, MKTAG(16 , 0 , '1', 'Y') }, { AV_PIX_FMT_YUV420P9LE, MKTAG('Y', '3', 11 , 9 ) }, @@ -266,6 +272,14 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { AV_PIX_FMT_YUV422P10BE, MKTAG('I', '2', 'A', 'B') }, { AV_PIX_FMT_YUV444P10LE, MKTAG('I', '4', 'A', 'L') }, { AV_PIX_FMT_YUV444P10BE, MKTAG('I', '4', 'A', 'B') }, + { AV_PIX_FMT_YUV420P12LE, MKTAG('I', '0', 'C', 'L') }, + { AV_PIX_FMT_YUV420P12BE, MKTAG('I', '0', 'C', 'B') }, + { AV_PIX_FMT_YUV422P12LE, MKTAG('I', '2', 'C', 'L') }, + { AV_PIX_FMT_YUV422P12BE, MKTAG('I', '2', 'C', 'B') }, + { AV_PIX_FMT_YUV444P12LE, MKTAG('I', '4', 'C', 'L') }, + { AV_PIX_FMT_YUV444P12BE, MKTAG('I', '4', 'C', 'B') }, + { AV_PIX_FMT_YUV420P16LE, MKTAG('I', '0', 'F', 'L') }, + { AV_PIX_FMT_YUV420P16BE, MKTAG('I', '0', 'F', 'B') }, { AV_PIX_FMT_YUV444P16LE, MKTAG('I', '4', 'F', 'L') }, { AV_PIX_FMT_YUV444P16BE, MKTAG('I', '4', 'F', 'B') }, diff --git a/media/ffvpx/libavcodec/thread.h b/media/ffvpx/libavcodec/thread.h index c848d7ae8..318619316 100644 --- a/media/ffvpx/libavcodec/thread.h +++ b/media/ffvpx/libavcodec/thread.h @@ -34,7 +34,7 @@ typedef struct ThreadFrame { AVFrame *f; - AVCodecContext *owner; + AVCodecContext *owner[2]; // progress->data is an array of 2 ints holding progress for top/bottom // fields AVBufferRef *progress; @@ -133,8 +133,10 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f); int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src); int ff_thread_init(AVCodecContext *s); +int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, + int (*action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr), + int (*main_func)(AVCodecContext *c), void *arg, int *ret, int job_count); void ff_thread_free(AVCodecContext *s); - int ff_alloc_entries(AVCodecContext *avctx, int count); void ff_reset_entries(AVCodecContext *avctx); void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n); diff --git a/media/ffvpx/libavcodec/utils.c b/media/ffvpx/libavcodec/utils.c index 87de15fc6..0c47e761f 100644 --- a/media/ffvpx/libavcodec/utils.c +++ b/media/ffvpx/libavcodec/utils.c @@ -44,6 +44,7 @@ #include "libavutil/dict.h" #include "libavutil/thread.h" #include "avcodec.h" +#include "decode.h" #include "libavutil/opt.h" #include "me_cmp.h" #include "mpegvideo.h" @@ -172,7 +173,7 @@ int av_codec_is_encoder(const AVCodec *codec) int av_codec_is_decoder(const AVCodec *codec) { - return codec && (codec->decode || codec->send_packet); + return codec && (codec->decode || codec->receive_frame); } av_cold void avcodec_register(AVCodec *codec) @@ -209,7 +210,7 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height) int ff_set_dimensions(AVCodecContext *s, int width, int height) { - int ret = av_image_check_size(width, height, 0, s); + int ret = av_image_check_size2(width, height, s->max_pixels, AV_PIX_FMT_NONE, 0, s); if (ret < 0) width = height = 0; @@ -376,6 +377,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, w_align = 4; h_align = 4; } + if (s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) { + w_align = 8; + h_align = 8; + } break; case AV_PIX_FMT_PAL8: case AV_PIX_FMT_BGR8: @@ -385,7 +390,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, w_align = 4; h_align = 4; } - if (s->codec_id == AV_CODEC_ID_JV) { + if (s->codec_id == AV_CODEC_ID_JV || + s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) { w_align = 8; h_align = 8; } @@ -503,200 +509,6 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, return ret; } -static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) -{ - FramePool *pool = avctx->internal->pool; - int i, ret; - - switch (avctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: { - uint8_t *data[4]; - int linesize[4]; - int size[4] = { 0 }; - int w = frame->width; - int h = frame->height; - int tmpsize, unaligned; - - if (pool->format == frame->format && - pool->width == frame->width && pool->height == frame->height) - return 0; - - avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); - - do { - // NOTE: do not align linesizes individually, this breaks e.g. assumptions - // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 - ret = av_image_fill_linesizes(linesize, avctx->pix_fmt, w); - if (ret < 0) - return ret; - // increase alignment of w for next try (rhs gives the lowest bit set in w) - w += w & ~(w - 1); - - unaligned = 0; - for (i = 0; i < 4; i++) - unaligned |= linesize[i] % pool->stride_align[i]; - } while (unaligned); - - tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, - NULL, linesize); - if (tmpsize < 0) - return -1; - - for (i = 0; i < 3 && data[i + 1]; i++) - size[i] = data[i + 1] - data[i]; - size[i] = tmpsize - (data[i] - data[0]); - - for (i = 0; i < 4; i++) { - av_buffer_pool_uninit(&pool->pools[i]); - pool->linesize[i] = linesize[i]; - if (size[i]) { - pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, - CONFIG_MEMORY_POISONING ? - NULL : - av_buffer_allocz); - if (!pool->pools[i]) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - } - pool->format = frame->format; - pool->width = frame->width; - pool->height = frame->height; - - break; - } - case AVMEDIA_TYPE_AUDIO: { - int ch = av_frame_get_channels(frame); //av_get_channel_layout_nb_channels(frame->channel_layout); - int planar = av_sample_fmt_is_planar(frame->format); - int planes = planar ? ch : 1; - - if (pool->format == frame->format && pool->planes == planes && - pool->channels == ch && frame->nb_samples == pool->samples) - return 0; - - av_buffer_pool_uninit(&pool->pools[0]); - ret = av_samples_get_buffer_size(&pool->linesize[0], ch, - frame->nb_samples, frame->format, 0); - if (ret < 0) - goto fail; - - pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); - if (!pool->pools[0]) { - ret = AVERROR(ENOMEM); - goto fail; - } - - pool->format = frame->format; - pool->planes = planes; - pool->channels = ch; - pool->samples = frame->nb_samples; - break; - } - default: av_assert0(0); - } - return 0; -fail: - for (i = 0; i < 4; i++) - av_buffer_pool_uninit(&pool->pools[i]); - pool->format = -1; - pool->planes = pool->channels = pool->samples = 0; - pool->width = pool->height = 0; - return ret; -} - -static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) -{ - FramePool *pool = avctx->internal->pool; - int planes = pool->planes; - int i; - - frame->linesize[0] = pool->linesize[0]; - - if (planes > AV_NUM_DATA_POINTERS) { - frame->extended_data = av_mallocz_array(planes, sizeof(*frame->extended_data)); - frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; - frame->extended_buf = av_mallocz_array(frame->nb_extended_buf, - sizeof(*frame->extended_buf)); - if (!frame->extended_data || !frame->extended_buf) { - av_freep(&frame->extended_data); - av_freep(&frame->extended_buf); - return AVERROR(ENOMEM); - } - } else { - frame->extended_data = frame->data; - av_assert0(frame->nb_extended_buf == 0); - } - - for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { - frame->buf[i] = av_buffer_pool_get(pool->pools[0]); - if (!frame->buf[i]) - goto fail; - frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; - } - for (i = 0; i < frame->nb_extended_buf; i++) { - frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); - if (!frame->extended_buf[i]) - goto fail; - frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; - } - - if (avctx->debug & FF_DEBUG_BUFFERS) - av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); - - return 0; -fail: - av_frame_unref(frame); - return AVERROR(ENOMEM); -} - -static int video_get_buffer(AVCodecContext *s, AVFrame *pic) -{ - FramePool *pool = s->internal->pool; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); - int i; - - if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) { - av_log(s, AV_LOG_ERROR, "pic->data[*]!=NULL in avcodec_default_get_buffer\n"); - return -1; - } - - if (!desc) { - av_log(s, AV_LOG_ERROR, - "Unable to get pixel format descriptor for format %s\n", - av_get_pix_fmt_name(pic->format)); - return AVERROR(EINVAL); - } - - memset(pic->data, 0, sizeof(pic->data)); - pic->extended_data = pic->data; - - for (i = 0; i < 4 && pool->pools[i]; i++) { - pic->linesize[i] = pool->linesize[i]; - - pic->buf[i] = av_buffer_pool_get(pool->pools[i]); - if (!pic->buf[i]) - goto fail; - - pic->data[i] = pic->buf[i]->data; - } - for (; i < AV_NUM_DATA_POINTERS; i++) { - pic->data[i] = NULL; - pic->linesize[i] = 0; - } - if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) - avpriv_set_systematic_pal2((uint32_t *)pic->data[1], pic->format); - - if (s->debug & FF_DEBUG_BUFFERS) - av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); - - return 0; -fail: - av_frame_unref(pic); - return AVERROR(ENOMEM); -} - void ff_color_frame(AVFrame *frame, const int c[4]) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); @@ -720,287 +532,6 @@ void ff_color_frame(AVFrame *frame, const int c[4]) } } -int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - int ret; - - if (avctx->hw_frames_ctx) - return av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); - - if ((ret = update_frame_pool(avctx, frame)) < 0) - return ret; - - switch (avctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: - return video_get_buffer(avctx, frame); - case AVMEDIA_TYPE_AUDIO: - return audio_get_buffer(avctx, frame); - default: - return -1; - } -} - -static int add_metadata_from_side_data(AVPacket *avpkt, AVFrame *frame) -{ - int size; - const uint8_t *side_metadata; - - AVDictionary **frame_md = avpriv_frame_get_metadatap(frame); - - side_metadata = av_packet_get_side_data(avpkt, - AV_PKT_DATA_STRINGS_METADATA, &size); - return av_packet_unpack_dictionary(side_metadata, size, frame_md); -} - -int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) -{ - AVPacket *pkt = avctx->internal->pkt; - int i; - static const struct { - enum AVPacketSideDataType packet; - enum AVFrameSideDataType frame; - } sd[] = { - { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN }, - { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, - { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, - { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, - { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, - }; - - if (pkt) { - frame->pts = pkt->pts; -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = pkt->pts; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - av_frame_set_pkt_pos (frame, pkt->pos); - av_frame_set_pkt_duration(frame, pkt->duration); - av_frame_set_pkt_size (frame, pkt->size); - - for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) { - int size; - uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); - if (packet_sd) { - AVFrameSideData *frame_sd = av_frame_new_side_data(frame, - sd[i].frame, - size); - if (!frame_sd) - return AVERROR(ENOMEM); - - memcpy(frame_sd->data, packet_sd, size); - } - } - add_metadata_from_side_data(pkt, frame); - - if (pkt->flags & AV_PKT_FLAG_DISCARD) { - frame->flags |= AV_FRAME_FLAG_DISCARD; - } else { - frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); - } - } else { - frame->pts = AV_NOPTS_VALUE; -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = AV_NOPTS_VALUE; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - av_frame_set_pkt_pos (frame, -1); - av_frame_set_pkt_duration(frame, 0); - av_frame_set_pkt_size (frame, -1); - } - frame->reordered_opaque = avctx->reordered_opaque; - - if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED) - frame->color_primaries = avctx->color_primaries; - if (frame->color_trc == AVCOL_TRC_UNSPECIFIED) - frame->color_trc = avctx->color_trc; - if (av_frame_get_colorspace(frame) == AVCOL_SPC_UNSPECIFIED) - av_frame_set_colorspace(frame, avctx->colorspace); - if (av_frame_get_color_range(frame) == AVCOL_RANGE_UNSPECIFIED) - av_frame_set_color_range(frame, avctx->color_range); - if (frame->chroma_location == AVCHROMA_LOC_UNSPECIFIED) - frame->chroma_location = avctx->chroma_sample_location; - - switch (avctx->codec->type) { - case AVMEDIA_TYPE_VIDEO: - frame->format = avctx->pix_fmt; - if (!frame->sample_aspect_ratio.num) - frame->sample_aspect_ratio = avctx->sample_aspect_ratio; - - if (frame->width && frame->height && - av_image_check_sar(frame->width, frame->height, - frame->sample_aspect_ratio) < 0) { - av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", - frame->sample_aspect_ratio.num, - frame->sample_aspect_ratio.den); - frame->sample_aspect_ratio = (AVRational){ 0, 1 }; - } - - break; - case AVMEDIA_TYPE_AUDIO: - if (!frame->sample_rate) - frame->sample_rate = avctx->sample_rate; - if (frame->format < 0) - frame->format = avctx->sample_fmt; - if (!frame->channel_layout) { - if (avctx->channel_layout) { - if (av_get_channel_layout_nb_channels(avctx->channel_layout) != - avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Inconsistent channel " - "configuration.\n"); - return AVERROR(EINVAL); - } - - frame->channel_layout = avctx->channel_layout; - } else { - if (avctx->channels > FF_SANE_NB_CHANNELS) { - av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n", - avctx->channels); - return AVERROR(ENOSYS); - } - } - } - av_frame_set_channels(frame, avctx->channels); - break; - } - return 0; -} - -int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) -{ - return ff_init_buffer_info(avctx, frame); -} - -static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame) -{ - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - int i; - int num_planes = av_pix_fmt_count_planes(frame->format); - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - int flags = desc ? desc->flags : 0; - if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL)) - num_planes = 2; - for (i = 0; i < num_planes; i++) { - av_assert0(frame->data[i]); - } - // For now do not enforce anything for palette of pseudopal formats - if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) - num_planes = 2; - // For formats without data like hwaccel allow unused pointers to be non-NULL. - for (i = num_planes; num_planes > 0 && i < FF_ARRAY_ELEMS(frame->data); i++) { - if (frame->data[i]) - av_log(avctx, AV_LOG_ERROR, "Buffer returned by get_buffer2() did not zero unused plane pointers\n"); - frame->data[i] = NULL; - } - } -} - -static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - const AVHWAccel *hwaccel = avctx->hwaccel; - int override_dimensions = 1; - int ret; - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0 || avctx->pix_fmt<0) { - av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); - return AVERROR(EINVAL); - } - - if (frame->width <= 0 || frame->height <= 0) { - frame->width = FFMAX(avctx->width, AV_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); - frame->height = FFMAX(avctx->height, AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); - override_dimensions = 0; - } - - if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) { - av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n"); - return AVERROR(EINVAL); - } - } - ret = ff_decode_frame_props(avctx, frame); - if (ret < 0) - return ret; - - if (hwaccel) { - if (hwaccel->alloc_frame) { - ret = hwaccel->alloc_frame(avctx, frame); - goto end; - } - } else - avctx->sw_pix_fmt = avctx->pix_fmt; - - ret = avctx->get_buffer2(avctx, frame, flags); - if (ret >= 0) - validate_avframe_allocation(avctx, frame); - -end: - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions) { - frame->width = avctx->width; - frame->height = avctx->height; - } - - return ret; -} - -int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) -{ - int ret = get_buffer_internal(avctx, frame, flags); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - frame->width = frame->height = 0; - } - return ret; -} - -static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame) -{ - AVFrame *tmp; - int ret; - - av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); - - if (frame->data[0] && (frame->width != avctx->width || frame->height != avctx->height || frame->format != avctx->pix_fmt)) { - av_log(avctx, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n", - frame->width, frame->height, av_get_pix_fmt_name(frame->format), avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt)); - av_frame_unref(frame); - } - - ff_init_buffer_info(avctx, frame); - - if (!frame->data[0]) - return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); - - if (av_frame_is_writable(frame)) - return ff_decode_frame_props(avctx, frame); - - tmp = av_frame_alloc(); - if (!tmp) - return AVERROR(ENOMEM); - - av_frame_move_ref(tmp, frame); - - ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); - if (ret < 0) { - av_frame_free(&tmp); - return ret; - } - - av_frame_copy(frame, tmp); - av_frame_free(&tmp); - - return 0; -} - -int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) -{ - int ret = reget_buffer_internal(avctx, frame); - if (ret < 0) - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return ret; -} - int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) { int i; @@ -1038,145 +569,6 @@ enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, return AV_PIX_FMT_NONE; } -static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; -} - -enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) -{ - while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt)) - ++fmt; - return fmt[0]; -} - -static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, - enum AVPixelFormat pix_fmt) -{ - AVHWAccel *hwaccel = NULL; - - while ((hwaccel = av_hwaccel_next(hwaccel))) - if (hwaccel->id == codec_id - && hwaccel->pix_fmt == pix_fmt) - return hwaccel; - return NULL; -} - -static int setup_hwaccel(AVCodecContext *avctx, - const enum AVPixelFormat fmt, - const char *name) -{ - AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt); - int ret = 0; - - if (avctx->active_thread_type & FF_THREAD_FRAME) { - av_log(avctx, AV_LOG_WARNING, - "Hardware accelerated decoding with frame threading is known to be unstable and its use is discouraged.\n"); - } - - if (!hwa) { - av_log(avctx, AV_LOG_ERROR, - "Could not find an AVHWAccel for the pixel format: %s", - name); - return AVERROR(ENOENT); - } - - if (hwa->capabilities & HWACCEL_CODEC_CAP_EXPERIMENTAL && - avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { - av_log(avctx, AV_LOG_WARNING, "Ignoring experimental hwaccel: %s\n", - hwa->name); - return AVERROR_PATCHWELCOME; - } - - if (hwa->priv_data_size) { - avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size); - if (!avctx->internal->hwaccel_priv_data) - return AVERROR(ENOMEM); - } - - if (hwa->init) { - ret = hwa->init(avctx); - if (ret < 0) { - av_freep(&avctx->internal->hwaccel_priv_data); - return ret; - } - } - - avctx->hwaccel = hwa; - - return 0; -} - -int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) -{ - const AVPixFmtDescriptor *desc; - enum AVPixelFormat *choices; - enum AVPixelFormat ret; - unsigned n = 0; - - while (fmt[n] != AV_PIX_FMT_NONE) - ++n; - - av_assert0(n >= 1); - avctx->sw_pix_fmt = fmt[n - 1]; - av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); - - choices = av_malloc_array(n + 1, sizeof(*choices)); - if (!choices) - return AV_PIX_FMT_NONE; - - memcpy(choices, fmt, (n + 1) * sizeof(*choices)); - - for (;;) { - if (avctx->hwaccel && avctx->hwaccel->uninit) - avctx->hwaccel->uninit(avctx); - av_freep(&avctx->internal->hwaccel_priv_data); - avctx->hwaccel = NULL; - - av_buffer_unref(&avctx->hw_frames_ctx); - - ret = avctx->get_format(avctx, choices); - - desc = av_pix_fmt_desc_get(ret); - if (!desc) { - ret = AV_PIX_FMT_NONE; - break; - } - - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) - break; -#if FF_API_CAP_VDPAU - if (avctx->codec->capabilities&AV_CODEC_CAP_HWACCEL_VDPAU) - break; -#endif - - if (avctx->hw_frames_ctx) { - AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; - if (hw_frames_ctx->format != ret) { - av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " - "does not match the format of provided AVHWFramesContext\n"); - ret = AV_PIX_FMT_NONE; - break; - } - } - - if (!setup_hwaccel(avctx, ret, desc->name)) - break; - - /* Remove failed hwaccel from choices */ - for (n = 0; choices[n] != ret; n++) - av_assert0(choices[n] != AV_PIX_FMT_NONE); - - do - choices[n] = choices[n + 1]; - while (choices[n++] != AV_PIX_FMT_NONE); - } - - av_freep(&choices); - return ret; -} - MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase) MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor) MAKE_ACCESSORS(AVCodecContext, codec, int, lowres) @@ -1197,12 +589,6 @@ int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec){ return !!(codec->caps_internal & FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM); } -static void get_subtitle_defaults(AVSubtitle *sub) -{ - memset(sub, 0, sizeof(*sub)); - sub->pts = AV_NOPTS_VALUE; -} - static int64_t get_bit_rate(AVCodecContext *ctx) { int64_t bit_rate; @@ -1269,7 +655,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code if (ret < 0) return ret; - avctx->internal = av_mallocz(sizeof(AVCodecInternal)); + avctx->internal = av_mallocz(sizeof(*avctx->internal)); if (!avctx->internal) { ret = AVERROR(ENOMEM); goto end; @@ -1287,6 +673,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->compat_decode_frame = av_frame_alloc(); + if (!avctx->internal->compat_decode_frame) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + avctx->internal->buffer_frame = av_frame_alloc(); if (!avctx->internal->buffer_frame) { ret = AVERROR(ENOMEM); @@ -1299,6 +691,20 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->ds.in_pkt = av_packet_alloc(); + if (!avctx->internal->ds.in_pkt) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->last_pkt_props = av_packet_alloc(); + if (!avctx->internal->last_pkt_props) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->skip_samples_multiplier = 1; + if (codec->priv_data_size > 0) { if (!avctx->priv_data) { avctx->priv_data = av_mallocz(codec->priv_data_size); @@ -1337,8 +743,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code } if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height) - && ( av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0 - || av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)) { + && ( av_image_check_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0 + || av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0)) { av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n"); ff_set_dimensions(avctx, 0, 0); } @@ -1561,11 +967,11 @@ FF_ENABLE_DEPRECATION_WARNINGS } if ( (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO) && avctx->bit_rate>0 && avctx->bit_rate<1000) { - av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", (int64_t)avctx->bit_rate, (int64_t)avctx->bit_rate); + av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", avctx->bit_rate, avctx->bit_rate); } if (!avctx->rc_initial_buffer_occupancy) - avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3 / 4; + avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3LL / 4; if (avctx->ticks_per_frame && avctx->time_base.num && avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { @@ -1585,6 +991,17 @@ FF_ENABLE_DEPRECATION_WARNINGS ret = AVERROR(EINVAL); goto free_and_end; } + if (avctx->sw_pix_fmt != AV_PIX_FMT_NONE && + avctx->sw_pix_fmt != frames_ctx->sw_format) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching AVCodecContext.sw_pix_fmt (%s) " + "and AVHWFramesContext.sw_format (%s)\n", + av_get_pix_fmt_name(avctx->sw_pix_fmt), + av_get_pix_fmt_name(frames_ctx->sw_format)); + ret = AVERROR(EINVAL); + goto free_and_end; + } + avctx->sw_pix_fmt = frames_ctx->sw_format; } } @@ -1709,9 +1126,14 @@ FF_ENABLE_DEPRECATION_WARNINGS av_dict_free(&tmp); av_freep(&avctx->priv_data); if (avctx->internal) { - av_packet_free(&avctx->internal->buffer_pkt); - av_frame_free(&avctx->internal->buffer_frame); av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); + av_frame_free(&avctx->internal->buffer_frame); + av_packet_free(&avctx->internal->buffer_pkt); + av_packet_free(&avctx->internal->last_pkt_props); + + av_packet_free(&avctx->internal->ds.in_pkt); + av_freep(&avctx->internal->pool); } av_freep(&avctx->internal); @@ -1719,1032 +1141,6 @@ FF_ENABLE_DEPRECATION_WARNINGS goto end; } -int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size) -{ - if (avpkt->size < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid negative user packet size %d\n", avpkt->size); - return AVERROR(EINVAL); - } - if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { - av_log(avctx, AV_LOG_ERROR, "Invalid minimum required packet size %"PRId64" (max allowed is %d)\n", - size, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); - return AVERROR(EINVAL); - } - - if (avctx && 2*min_size < size) { // FIXME The factor needs to be finetuned - av_assert0(!avpkt->data || avpkt->data != avctx->internal->byte_buffer); - if (!avpkt->data || avpkt->size < size) { - av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size); - avpkt->data = avctx->internal->byte_buffer; - avpkt->size = avctx->internal->byte_buffer_size; - } - } - - if (avpkt->data) { - AVBufferRef *buf = avpkt->buf; - - if (avpkt->size < size) { - av_log(avctx, AV_LOG_ERROR, "User packet is too small (%d < %"PRId64")\n", avpkt->size, size); - return AVERROR(EINVAL); - } - - av_init_packet(avpkt); - avpkt->buf = buf; - avpkt->size = size; - return 0; - } else { - int ret = av_new_packet(avpkt, size); - if (ret < 0) - av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %"PRId64"\n", size); - return ret; - } -} - -int ff_alloc_packet(AVPacket *avpkt, int size) -{ - return ff_alloc_packet2(NULL, avpkt, size, 0); -} - -/** - * Pad last frame with silence. - */ -static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) -{ - AVFrame *frame = NULL; - int ret; - - if (!(frame = av_frame_alloc())) - return AVERROR(ENOMEM); - - frame->format = src->format; - frame->channel_layout = src->channel_layout; - av_frame_set_channels(frame, av_frame_get_channels(src)); - frame->nb_samples = s->frame_size; - ret = av_frame_get_buffer(frame, 32); - if (ret < 0) - goto fail; - - ret = av_frame_copy_props(frame, src); - if (ret < 0) - goto fail; - - if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0, - src->nb_samples, s->channels, s->sample_fmt)) < 0) - goto fail; - if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples, - frame->nb_samples - src->nb_samples, - s->channels, s->sample_fmt)) < 0) - goto fail; - - *dst = frame; - - return 0; - -fail: - av_frame_free(&frame); - return ret; -} - -int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - AVFrame *extended_frame = NULL; - AVFrame *padded_frame = NULL; - int ret; - AVPacket user_pkt = *avpkt; - int needs_realloc = !user_pkt.data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - return 0; - } - - /* ensure that extended_data is properly set */ - if (frame && !frame->extended_data) { - if (av_sample_fmt_is_planar(avctx->sample_fmt) && - avctx->channels > AV_NUM_DATA_POINTERS) { - av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, " - "with more than %d channels, but extended_data is not set.\n", - AV_NUM_DATA_POINTERS); - return AVERROR(EINVAL); - } - av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); - - extended_frame = av_frame_alloc(); - if (!extended_frame) - return AVERROR(ENOMEM); - - memcpy(extended_frame, frame, sizeof(AVFrame)); - extended_frame->extended_data = extended_frame->data; - frame = extended_frame; - } - - /* extract audio service type metadata */ - if (frame) { - AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); - if (sd && sd->size >= sizeof(enum AVAudioServiceType)) - avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; - } - - /* check for valid frame size */ - if (frame) { - if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { - if (frame->nb_samples > avctx->frame_size) { - av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n"); - ret = AVERROR(EINVAL); - goto end; - } - } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { - if (frame->nb_samples < avctx->frame_size && - !avctx->internal->last_audio_frame) { - ret = pad_last_frame(avctx, &padded_frame, frame); - if (ret < 0) - goto end; - - frame = padded_frame; - avctx->internal->last_audio_frame = 1; - } - - if (frame->nb_samples != avctx->frame_size) { - av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size); - ret = AVERROR(EINVAL); - goto end; - } - } - } - - av_assert0(avctx->codec->encode2); - - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - if (!ret) { - if (*got_packet_ptr) { - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { - if (avpkt->pts == AV_NOPTS_VALUE) - avpkt->pts = frame->pts; - if (!avpkt->duration) - avpkt->duration = ff_samples_to_time_base(avctx, - frame->nb_samples); - } - avpkt->dts = avpkt->pts; - } else { - avpkt->size = 0; - } - } - if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { - needs_realloc = 0; - if (user_pkt.data) { - if (user_pkt.size >= avpkt->size) { - memcpy(user_pkt.data, avpkt->data, avpkt->size); - } else { - av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); - avpkt->size = user_pkt.size; - ret = -1; - } - avpkt->buf = user_pkt.buf; - avpkt->data = user_pkt.data; - } else { - if (av_dup_packet(avpkt) < 0) { - ret = AVERROR(ENOMEM); - } - } - } - - if (!ret) { - if (needs_realloc && avpkt->data) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - goto end; - } - - /* NOTE: if we add any audio encoders which output non-keyframe packets, - * this needs to be moved to the encoders, but for now we can do it - * here to simplify things */ - avpkt->flags |= AV_PKT_FLAG_KEY; - -end: - av_frame_free(&padded_frame); - av_free(extended_frame); - -#if FF_API_AUDIOENC_DELAY - avctx->delay = avctx->initial_padding; -#endif - - return ret; -} - -int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - int ret; - AVPacket user_pkt = *avpkt; - int needs_realloc = !user_pkt.data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if(CONFIG_FRAME_THREAD_ENCODER && - avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME)) - return ff_thread_video_encode_frame(avctx, avpkt, frame, got_packet_ptr); - - if ((avctx->flags&AV_CODEC_FLAG_PASS1) && avctx->stats_out) - avctx->stats_out[0] = '\0'; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { - av_packet_unref(avpkt); - av_init_packet(avpkt); - avpkt->size = 0; - return 0; - } - - if (av_image_check_size(avctx->width, avctx->height, 0, avctx)) - return AVERROR(EINVAL); - - if (frame && frame->format == AV_PIX_FMT_NONE) - av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n"); - if (frame && (frame->width == 0 || frame->height == 0)) - av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n"); - - av_assert0(avctx->codec->encode2); - - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - av_assert0(ret <= 0); - - emms_c(); - - if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { - needs_realloc = 0; - if (user_pkt.data) { - if (user_pkt.size >= avpkt->size) { - memcpy(user_pkt.data, avpkt->data, avpkt->size); - } else { - av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); - avpkt->size = user_pkt.size; - ret = -1; - } - avpkt->buf = user_pkt.buf; - avpkt->data = user_pkt.data; - } else { - if (av_dup_packet(avpkt) < 0) { - ret = AVERROR(ENOMEM); - } - } - } - - if (!ret) { - if (!*got_packet_ptr) - avpkt->size = 0; - else if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - avpkt->pts = avpkt->dts = frame->pts; - - if (needs_realloc && avpkt->data) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) - av_packet_unref(avpkt); - - return ret; -} - -int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVSubtitle *sub) -{ - int ret; - if (sub->start_display_time) { - av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); - return -1; - } - - ret = avctx->codec->encode_sub(avctx, buf, buf_size, sub); - avctx->frame_number++; - return ret; -} - -/** - * Attempt to guess proper monotonic timestamps for decoded video frames - * which might have incorrect times. Input timestamps may wrap around, in - * which case the output will as well. - * - * @param pts the pts field of the decoded AVPacket, as passed through - * AVFrame.pts - * @param dts the dts field of the decoded AVPacket - * @return one of the input values, may be AV_NOPTS_VALUE - */ -static int64_t guess_correct_pts(AVCodecContext *ctx, - int64_t reordered_pts, int64_t dts) -{ - int64_t pts = AV_NOPTS_VALUE; - - if (dts != AV_NOPTS_VALUE) { - ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; - ctx->pts_correction_last_dts = dts; - } else if (reordered_pts != AV_NOPTS_VALUE) - ctx->pts_correction_last_dts = reordered_pts; - - if (reordered_pts != AV_NOPTS_VALUE) { - ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; - ctx->pts_correction_last_pts = reordered_pts; - } else if(dts != AV_NOPTS_VALUE) - ctx->pts_correction_last_pts = dts; - - if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) - && reordered_pts != AV_NOPTS_VALUE) - pts = reordered_pts; - else - pts = dts; - - return pts; -} - -static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) -{ - int size = 0, ret; - const uint8_t *data; - uint32_t flags; - int64_t val; - - data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); - if (!data) - return 0; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { - av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " - "changes, but PARAM_CHANGE side data was sent to it.\n"); - ret = AVERROR(EINVAL); - goto fail2; - } - - if (size < 4) - goto fail; - - flags = bytestream_get_le32(&data); - size -= 4; - - if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { - if (size < 4) - goto fail; - val = bytestream_get_le32(&data); - if (val <= 0 || val > INT_MAX) { - av_log(avctx, AV_LOG_ERROR, "Invalid channel count"); - ret = AVERROR_INVALIDDATA; - goto fail2; - } - avctx->channels = val; - size -= 4; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { - if (size < 8) - goto fail; - avctx->channel_layout = bytestream_get_le64(&data); - size -= 8; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { - if (size < 4) - goto fail; - val = bytestream_get_le32(&data); - if (val <= 0 || val > INT_MAX) { - av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); - ret = AVERROR_INVALIDDATA; - goto fail2; - } - avctx->sample_rate = val; - size -= 4; - } - if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { - if (size < 8) - goto fail; - avctx->width = bytestream_get_le32(&data); - avctx->height = bytestream_get_le32(&data); - size -= 8; - ret = ff_set_dimensions(avctx, avctx->width, avctx->height); - if (ret < 0) - goto fail2; - } - - return 0; -fail: - av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); - ret = AVERROR_INVALIDDATA; -fail2: - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); - if (avctx->err_recognition & AV_EF_EXPLODE) - return ret; - } - return 0; -} - -static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) -{ - int ret; - - /* move the original frame to our backup */ - av_frame_unref(avci->to_free); - av_frame_move_ref(avci->to_free, frame); - - /* now copy everything except the AVBufferRefs back - * note that we make a COPY of the side data, so calling av_frame_free() on - * the caller's frame will work properly */ - ret = av_frame_copy_props(frame, avci->to_free); - if (ret < 0) - return ret; - - memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); - memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); - if (avci->to_free->extended_data != avci->to_free->data) { - int planes = av_frame_get_channels(avci->to_free); - int size = planes * sizeof(*frame->extended_data); - - if (!size) { - av_frame_unref(frame); - return AVERROR_BUG; - } - - frame->extended_data = av_malloc(size); - if (!frame->extended_data) { - av_frame_unref(frame); - return AVERROR(ENOMEM); - } - memcpy(frame->extended_data, avci->to_free->extended_data, - size); - } else - frame->extended_data = frame->data; - - frame->format = avci->to_free->format; - frame->width = avci->to_free->width; - frame->height = avci->to_free->height; - frame->channel_layout = avci->to_free->channel_layout; - frame->nb_samples = avci->to_free->nb_samples; - av_frame_set_channels(frame, av_frame_get_channels(avci->to_free)); - - return 0; -} - -int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - const AVPacket *avpkt) -{ - AVCodecInternal *avci = avctx->internal; - int ret; - // copy to ensure we do not change avpkt - AVPacket tmp = *avpkt; - - if (!avctx->codec) - return AVERROR(EINVAL); - if (avctx->codec->type != AVMEDIA_TYPE_VIDEO) { - av_log(avctx, AV_LOG_ERROR, "Invalid media type for video\n"); - return AVERROR(EINVAL); - } - - if (!avctx->codec->decode) { - av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); - return AVERROR(ENOSYS); - } - - *got_picture_ptr = 0; - if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) - return AVERROR(EINVAL); - - avctx->internal->pkt = avpkt; - ret = apply_param_change(avctx, avpkt); - if (ret < 0) - return ret; - - av_frame_unref(picture); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || - (avctx->active_thread_type & FF_THREAD_FRAME)) { - int did_split = av_packet_split_side_data(&tmp); - ret = apply_param_change(avctx, &tmp); - if (ret < 0) - goto fail; - - avctx->internal->pkt = &tmp; - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, - &tmp); - else { - ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - &tmp); - if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) - picture->pkt_dts = avpkt->dts; - - if(!avctx->has_b_frames){ - av_frame_set_pkt_pos(picture, avpkt->pos); - } - //FIXME these should be under if(!avctx->has_b_frames) - /* get_buffer is supposed to set frame parameters */ - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { - if (!picture->sample_aspect_ratio.num) picture->sample_aspect_ratio = avctx->sample_aspect_ratio; - if (!picture->width) picture->width = avctx->width; - if (!picture->height) picture->height = avctx->height; - if (picture->format == AV_PIX_FMT_NONE) picture->format = avctx->pix_fmt; - } - } - -fail: - emms_c(); //needed to avoid an emms_c() call before every return; - - avctx->internal->pkt = NULL; - if (did_split) { - av_packet_free_side_data(&tmp); - if(ret == tmp.size) - ret = avpkt->size; - } - if (picture->flags & AV_FRAME_FLAG_DISCARD) { - *got_picture_ptr = 0; - } - if (*got_picture_ptr) { - if (!avctx->refcounted_frames) { - int err = unrefcount_frame(avci, picture); - if (err < 0) - return err; - } - - avctx->frame_number++; - av_frame_set_best_effort_timestamp(picture, - guess_correct_pts(avctx, - picture->pts, - picture->pkt_dts)); - } else - av_frame_unref(picture); - } else - ret = 0; - - /* many decoders assign whole AVFrames, thus overwriting extended_data; - * make sure it's set correctly */ - av_assert0(!picture->extended_data || picture->extended_data == picture->data); - -#if FF_API_AVCTX_TIMEBASE - if (avctx->framerate.num > 0 && avctx->framerate.den > 0) - avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); -#endif - - return ret; -} - -int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, - AVFrame *frame, - int *got_frame_ptr, - const AVPacket *avpkt) -{ - AVCodecInternal *avci = avctx->internal; - int ret = 0; - - *got_frame_ptr = 0; - - if (!avctx->codec) - return AVERROR(EINVAL); - - if (!avctx->codec->decode) { - av_log(avctx, AV_LOG_ERROR, "This decoder requires using the avcodec_send_packet() API.\n"); - return AVERROR(ENOSYS); - } - - if (!avpkt->data && avpkt->size) { - av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); - return AVERROR(EINVAL); - } - if (avctx->codec->type != AVMEDIA_TYPE_AUDIO) { - av_log(avctx, AV_LOG_ERROR, "Invalid media type for audio\n"); - return AVERROR(EINVAL); - } - - av_frame_unref(frame); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { - uint8_t *side; - int side_size; - uint32_t discard_padding = 0; - uint8_t skip_reason = 0; - uint8_t discard_reason = 0; - // copy to ensure we do not change avpkt - AVPacket tmp = *avpkt; - int did_split = av_packet_split_side_data(&tmp); - ret = apply_param_change(avctx, &tmp); - if (ret < 0) - goto fail; - - avctx->internal->pkt = &tmp; - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp); - else { - ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp); - av_assert0(ret <= tmp.size); - frame->pkt_dts = avpkt->dts; - } - if (ret >= 0 && *got_frame_ptr) { - avctx->frame_number++; - av_frame_set_best_effort_timestamp(frame, - guess_correct_pts(avctx, - frame->pts, - frame->pkt_dts)); - if (frame->format == AV_SAMPLE_FMT_NONE) - frame->format = avctx->sample_fmt; - if (!frame->channel_layout) - frame->channel_layout = avctx->channel_layout; - if (!av_frame_get_channels(frame)) - av_frame_set_channels(frame, avctx->channels); - if (!frame->sample_rate) - frame->sample_rate = avctx->sample_rate; - } - - side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); - if(side && side_size>=10) { - avctx->internal->skip_samples = AV_RL32(side); - discard_padding = AV_RL32(side + 4); - av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n", - avctx->internal->skip_samples, (int)discard_padding); - skip_reason = AV_RL8(side + 8); - discard_reason = AV_RL8(side + 9); - } - - if ((frame->flags & AV_FRAME_FLAG_DISCARD) && *got_frame_ptr && - !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { - avctx->internal->skip_samples -= frame->nb_samples; - *got_frame_ptr = 0; - } - - if (avctx->internal->skip_samples > 0 && *got_frame_ptr && - !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { - if(frame->nb_samples <= avctx->internal->skip_samples){ - *got_frame_ptr = 0; - avctx->internal->skip_samples -= frame->nb_samples; - av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", - avctx->internal->skip_samples); - } else { - av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples, - frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format); - if(avctx->pkt_timebase.num && avctx->sample_rate) { - int64_t diff_ts = av_rescale_q(avctx->internal->skip_samples, - (AVRational){1, avctx->sample_rate}, - avctx->pkt_timebase); - if(frame->pts!=AV_NOPTS_VALUE) - frame->pts += diff_ts; -#if FF_API_PKT_PTS -FF_DISABLE_DEPRECATION_WARNINGS - if(frame->pkt_pts!=AV_NOPTS_VALUE) - frame->pkt_pts += diff_ts; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - if(frame->pkt_dts!=AV_NOPTS_VALUE) - frame->pkt_dts += diff_ts; - if (av_frame_get_pkt_duration(frame) >= diff_ts) - av_frame_set_pkt_duration(frame, av_frame_get_pkt_duration(frame) - diff_ts); - } else { - av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n"); - } - av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n", - avctx->internal->skip_samples, frame->nb_samples); - frame->nb_samples -= avctx->internal->skip_samples; - avctx->internal->skip_samples = 0; - } - } - - if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr && - !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { - if (discard_padding == frame->nb_samples) { - *got_frame_ptr = 0; - } else { - if(avctx->pkt_timebase.num && avctx->sample_rate) { - int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, - (AVRational){1, avctx->sample_rate}, - avctx->pkt_timebase); - av_frame_set_pkt_duration(frame, diff_ts); - } else { - av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n"); - } - av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n", - (int)discard_padding, frame->nb_samples); - frame->nb_samples -= discard_padding; - } - } - - if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL) && *got_frame_ptr) { - AVFrameSideData *fside = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10); - if (fside) { - AV_WL32(fside->data, avctx->internal->skip_samples); - AV_WL32(fside->data + 4, discard_padding); - AV_WL8(fside->data + 8, skip_reason); - AV_WL8(fside->data + 9, discard_reason); - avctx->internal->skip_samples = 0; - } - } -fail: - avctx->internal->pkt = NULL; - if (did_split) { - av_packet_free_side_data(&tmp); - if(ret == tmp.size) - ret = avpkt->size; - } - - if (ret >= 0 && *got_frame_ptr) { - if (!avctx->refcounted_frames) { - int err = unrefcount_frame(avci, frame); - if (err < 0) - return err; - } - } else - av_frame_unref(frame); - } - - av_assert0(ret <= avpkt->size); - - if (!avci->showed_multi_packet_warning && - ret >= 0 && ret != avpkt->size && !(avctx->codec->capabilities & AV_CODEC_CAP_SUBFRAMES)) { - av_log(avctx, AV_LOG_WARNING, "Multiple frames in a packet.\n"); - avci->showed_multi_packet_warning = 1; - } - - return ret; -} - -#define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */ -static int recode_subtitle(AVCodecContext *avctx, - AVPacket *outpkt, const AVPacket *inpkt) -{ -#if CONFIG_ICONV - iconv_t cd = (iconv_t)-1; - int ret = 0; - char *inb, *outb; - size_t inl, outl; - AVPacket tmp; -#endif - - if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) - return 0; - -#if CONFIG_ICONV - cd = iconv_open("UTF-8", avctx->sub_charenc); - av_assert0(cd != (iconv_t)-1); - - inb = inpkt->data; - inl = inpkt->size; - - if (inl >= INT_MAX / UTF8_MAX_BYTES - AV_INPUT_BUFFER_PADDING_SIZE) { - av_log(avctx, AV_LOG_ERROR, "Subtitles packet is too big for recoding\n"); - ret = AVERROR(ENOMEM); - goto end; - } - - ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES); - if (ret < 0) - goto end; - outpkt->buf = tmp.buf; - outpkt->data = tmp.data; - outpkt->size = tmp.size; - outb = outpkt->data; - outl = outpkt->size; - - if (iconv(cd, &inb, &inl, &outb, &outl) == (size_t)-1 || - iconv(cd, NULL, NULL, &outb, &outl) == (size_t)-1 || - outl >= outpkt->size || inl != 0) { - ret = FFMIN(AVERROR(errno), -1); - av_log(avctx, AV_LOG_ERROR, "Unable to recode subtitle event \"%s\" " - "from %s to UTF-8\n", inpkt->data, avctx->sub_charenc); - av_packet_unref(&tmp); - goto end; - } - outpkt->size -= outl; - memset(outpkt->data + outpkt->size, 0, outl); - -end: - if (cd != (iconv_t)-1) - iconv_close(cd); - return ret; -#else - av_log(avctx, AV_LOG_ERROR, "requesting subtitles recoding without iconv"); - return AVERROR(EINVAL); -#endif -} - -static int utf8_check(const uint8_t *str) -{ - const uint8_t *byte; - uint32_t codepoint, min; - - while (*str) { - byte = str; - GET_UTF8(codepoint, *(byte++), return 0;); - min = byte - str == 1 ? 0 : byte - str == 2 ? 0x80 : - 1 << (5 * (byte - str) - 4); - if (codepoint < min || codepoint >= 0x110000 || - codepoint == 0xFFFE /* BOM */ || - codepoint >= 0xD800 && codepoint <= 0xDFFF /* surrogates */) - return 0; - str = byte; - } - return 1; -} - -#if FF_API_ASS_TIMING -static void insert_ts(AVBPrint *buf, int ts) -{ - if (ts == -1) { - av_bprintf(buf, "9:59:59.99,"); - } else { - int h, m, s; - - h = ts/360000; ts -= 360000*h; - m = ts/ 6000; ts -= 6000*m; - s = ts/ 100; ts -= 100*s; - av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts); - } -} - -static int convert_sub_to_old_ass_form(AVSubtitle *sub, const AVPacket *pkt, AVRational tb) -{ - int i; - AVBPrint buf; - - av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); - - for (i = 0; i < sub->num_rects; i++) { - char *final_dialog; - const char *dialog; - AVSubtitleRect *rect = sub->rects[i]; - int ts_start, ts_duration = -1; - long int layer; - - if (rect->type != SUBTITLE_ASS || !strncmp(rect->ass, "Dialogue: ", 10)) - continue; - - av_bprint_clear(&buf); - - /* skip ReadOrder */ - dialog = strchr(rect->ass, ','); - if (!dialog) - continue; - dialog++; - - /* extract Layer or Marked */ - layer = strtol(dialog, (char**)&dialog, 10); - if (*dialog != ',') - continue; - dialog++; - - /* rescale timing to ASS time base (ms) */ - ts_start = av_rescale_q(pkt->pts, tb, av_make_q(1, 100)); - if (pkt->duration != -1) - ts_duration = av_rescale_q(pkt->duration, tb, av_make_q(1, 100)); - sub->end_display_time = FFMAX(sub->end_display_time, 10 * ts_duration); - - /* construct ASS (standalone file form with timestamps) string */ - av_bprintf(&buf, "Dialogue: %ld,", layer); - insert_ts(&buf, ts_start); - insert_ts(&buf, ts_duration == -1 ? -1 : ts_start + ts_duration); - av_bprintf(&buf, "%s\r\n", dialog); - - final_dialog = av_strdup(buf.str); - if (!av_bprint_is_complete(&buf) || !final_dialog) { - av_freep(&final_dialog); - av_bprint_finalize(&buf, NULL); - return AVERROR(ENOMEM); - } - av_freep(&rect->ass); - rect->ass = final_dialog; - } - - av_bprint_finalize(&buf, NULL); - return 0; -} -#endif - -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt) -{ - int i, ret = 0; - - if (!avpkt->data && avpkt->size) { - av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); - return AVERROR(EINVAL); - } - if (!avctx->codec) - return AVERROR(EINVAL); - if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) { - av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n"); - return AVERROR(EINVAL); - } - - *got_sub_ptr = 0; - get_subtitle_defaults(sub); - - if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { - AVPacket pkt_recoded; - AVPacket tmp = *avpkt; - int did_split = av_packet_split_side_data(&tmp); - //apply_param_change(avctx, &tmp); - - if (did_split) { - /* FFMIN() prevents overflow in case the packet wasn't allocated with - * proper padding. - * If the side data is smaller than the buffer padding size, the - * remaining bytes should have already been filled with zeros by the - * original packet allocation anyway. */ - memset(tmp.data + tmp.size, 0, - FFMIN(avpkt->size - tmp.size, AV_INPUT_BUFFER_PADDING_SIZE)); - } - - pkt_recoded = tmp; - ret = recode_subtitle(avctx, &pkt_recoded, &tmp); - if (ret < 0) { - *got_sub_ptr = 0; - } else { - avctx->internal->pkt = &pkt_recoded; - - if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) - sub->pts = av_rescale_q(avpkt->pts, - avctx->pkt_timebase, AV_TIME_BASE_Q); - ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded); - av_assert1((ret >= 0) >= !!*got_sub_ptr && - !!*got_sub_ptr >= !!sub->num_rects); - -#if FF_API_ASS_TIMING - if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS - && *got_sub_ptr && sub->num_rects) { - const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase - : avctx->time_base; - int err = convert_sub_to_old_ass_form(sub, avpkt, tb); - if (err < 0) - ret = err; - } -#endif - - if (sub->num_rects && !sub->end_display_time && avpkt->duration && - avctx->pkt_timebase.num) { - AVRational ms = { 1, 1000 }; - sub->end_display_time = av_rescale_q(avpkt->duration, - avctx->pkt_timebase, ms); - } - - for (i = 0; i < sub->num_rects; i++) { - if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { - av_log(avctx, AV_LOG_ERROR, - "Invalid UTF-8 in decoded subtitles text; " - "maybe missing -sub_charenc option\n"); - avsubtitle_free(sub); - return AVERROR_INVALIDDATA; - } - } - - if (tmp.data != pkt_recoded.data) { // did we recode? - /* prevent from destroying side data from original packet */ - pkt_recoded.side_data = NULL; - pkt_recoded.side_data_elems = 0; - - av_packet_unref(&pkt_recoded); - } - if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) - sub->format = 0; - else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) - sub->format = 1; - avctx->internal->pkt = NULL; - } - - if (did_split) { - av_packet_free_side_data(&tmp); - if(ret == tmp.size) - ret = avpkt->size; - } - - if (*got_sub_ptr) - avctx->frame_number++; - } - - return ret; -} - void avsubtitle_free(AVSubtitle *sub) { int i; @@ -2761,263 +1157,7 @@ void avsubtitle_free(AVSubtitle *sub) av_freep(&sub->rects); - memset(sub, 0, sizeof(AVSubtitle)); -} - -static int do_decode(AVCodecContext *avctx, AVPacket *pkt) -{ - int got_frame; - int ret; - - av_assert0(!avctx->internal->buffer_frame->buf[0]); - - if (!pkt) - pkt = avctx->internal->buffer_pkt; - - // This is the lesser evil. The field is for compatibility with legacy users - // of the legacy API, and users using the new API should not be forced to - // even know about this field. - avctx->refcounted_frames = 1; - - // Some codecs (at least wma lossless) will crash when feeding drain packets - // after EOF was signaled. - if (avctx->internal->draining_done) - return AVERROR_EOF; - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_decode_video2(avctx, avctx->internal->buffer_frame, - &got_frame, pkt); - if (ret >= 0) - ret = pkt->size; - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_decode_audio4(avctx, avctx->internal->buffer_frame, - &got_frame, pkt); - } else { - ret = AVERROR(EINVAL); - } - - if (ret == AVERROR(EAGAIN)) - ret = pkt->size; - - if (ret < 0) - return ret; - - if (avctx->internal->draining && !got_frame) - avctx->internal->draining_done = 1; - - if (ret >= pkt->size) { - av_packet_unref(avctx->internal->buffer_pkt); - } else { - int consumed = ret; - - if (pkt != avctx->internal->buffer_pkt) { - av_packet_unref(avctx->internal->buffer_pkt); - if ((ret = av_packet_ref(avctx->internal->buffer_pkt, pkt)) < 0) - return ret; - } - - avctx->internal->buffer_pkt->data += consumed; - avctx->internal->buffer_pkt->size -= consumed; - avctx->internal->buffer_pkt->pts = AV_NOPTS_VALUE; - avctx->internal->buffer_pkt->dts = AV_NOPTS_VALUE; - } - - if (got_frame) - av_assert0(avctx->internal->buffer_frame->buf[0]); - - return 0; -} - -int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) -{ - int ret; - - if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->internal->draining) - return AVERROR_EOF; - - if (avpkt && !avpkt->size && avpkt->data) - return AVERROR(EINVAL); - - if (!avpkt || !avpkt->size) { - avctx->internal->draining = 1; - avpkt = NULL; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; - } - - if (avctx->codec->send_packet) { - if (avpkt) { - AVPacket tmp = *avpkt; - int did_split = av_packet_split_side_data(&tmp); - ret = apply_param_change(avctx, &tmp); - if (ret >= 0) - ret = avctx->codec->send_packet(avctx, &tmp); - if (did_split) - av_packet_free_side_data(&tmp); - return ret; - } else { - return avctx->codec->send_packet(avctx, NULL); - } - } - - // Emulation via old API. Assume avpkt is likely not refcounted, while - // decoder output is always refcounted, and avoid copying. - - if (avctx->internal->buffer_pkt->size || avctx->internal->buffer_frame->buf[0]) - return AVERROR(EAGAIN); - - // The goal is decoding the first frame of the packet without using memcpy, - // because the common case is having only 1 frame per packet (especially - // with video, but audio too). In other cases, it can't be avoided, unless - // the user is feeding refcounted packets. - return do_decode(avctx, (AVPacket *)avpkt); -} - -int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) -{ - int ret; - - av_frame_unref(frame); - - if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->codec->receive_frame) { - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; - ret = avctx->codec->receive_frame(avctx, frame); - if (ret >= 0) { - if (av_frame_get_best_effort_timestamp(frame) == AV_NOPTS_VALUE) { - av_frame_set_best_effort_timestamp(frame, - guess_correct_pts(avctx, frame->pts, frame->pkt_dts)); - } - } - return ret; - } - - // Emulation via old API. - - if (!avctx->internal->buffer_frame->buf[0]) { - if (!avctx->internal->buffer_pkt->size && !avctx->internal->draining) - return AVERROR(EAGAIN); - - while (1) { - if ((ret = do_decode(avctx, avctx->internal->buffer_pkt)) < 0) { - av_packet_unref(avctx->internal->buffer_pkt); - return ret; - } - // Some audio decoders may consume partial data without returning - // a frame (fate-wmapro-2ch). There is no way to make the caller - // call avcodec_receive_frame() again without returning a frame, - // so try to decode more in these cases. - if (avctx->internal->buffer_frame->buf[0] || - !avctx->internal->buffer_pkt->size) - break; - } - } - - if (!avctx->internal->buffer_frame->buf[0]) - return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN); - - av_frame_move_ref(frame, avctx->internal->buffer_frame); - return 0; -} - -static int do_encode(AVCodecContext *avctx, const AVFrame *frame, int *got_packet) -{ - int ret; - *got_packet = 0; - - av_packet_unref(avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_encode_video2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_encode_audio2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else { - ret = AVERROR(EINVAL); - } - - if (ret >= 0 && *got_packet) { - // Encoders must always return ref-counted buffers. - // Side-data only packets have no data and can be not ref-counted. - av_assert0(!avctx->internal->buffer_pkt->data || avctx->internal->buffer_pkt->buf); - avctx->internal->buffer_pkt_valid = 1; - ret = 0; - } else { - av_packet_unref(avctx->internal->buffer_pkt); - } - - return ret; -} - -int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) -{ - if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->internal->draining) - return AVERROR_EOF; - - if (!frame) { - avctx->internal->draining = 1; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; - } - - if (avctx->codec->send_frame) - return avctx->codec->send_frame(avctx, frame); - - // Emulation via old API. Do it here instead of avcodec_receive_packet, because: - // 1. if the AVFrame is not refcounted, the copying will be much more - // expensive than copying the packet data - // 2. assume few users use non-refcounted AVPackets, so usually no copy is - // needed - - if (avctx->internal->buffer_pkt_valid) - return AVERROR(EAGAIN); - - return do_encode(avctx, frame, &(int){0}); -} - -int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) -{ - av_packet_unref(avpkt); - - if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) - return AVERROR(EINVAL); - - if (avctx->codec->receive_packet) { - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; - return avctx->codec->receive_packet(avctx, avpkt); - } - - // Emulation via old API. - - if (!avctx->internal->buffer_pkt_valid) { - int got_packet; - int ret; - if (!avctx->internal->draining) - return AVERROR(EAGAIN); - ret = do_encode(avctx, NULL, &got_packet); - if (ret < 0) - return ret; - if (ret >= 0 && !got_packet) - return AVERROR_EOF; - } - - av_packet_move_ref(avpkt, avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - return 0; + memset(sub, 0, sizeof(*sub)); } av_cold int avcodec_close(AVCodecContext *avctx) @@ -3040,8 +1180,13 @@ av_cold int avcodec_close(AVCodecContext *avctx) avctx->internal->byte_buffer_size = 0; av_freep(&avctx->internal->byte_buffer); av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); av_frame_free(&avctx->internal->buffer_frame); av_packet_free(&avctx->internal->buffer_pkt); + av_packet_free(&avctx->internal->last_pkt_props); + + av_packet_free(&avctx->internal->ds.in_pkt); + for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) av_buffer_pool_uninit(&pool->pools[i]); av_freep(&avctx->internal->pool); @@ -3050,6 +1195,8 @@ av_cold int avcodec_close(AVCodecContext *avctx) avctx->hwaccel->uninit(avctx); av_freep(&avctx->internal->hwaccel_priv_data); + ff_decode_bsfs_uninit(avctx); + av_freep(&avctx->internal); } @@ -3059,6 +1206,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) avctx->nb_coded_side_data = 0; av_buffer_unref(&avctx->hw_frames_ctx); + av_buffer_unref(&avctx->hw_device_ctx); if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) av_opt_free(avctx->priv_data); @@ -3215,12 +1363,9 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", %d reference frame%s", enc->refs, enc->refs > 1 ? "s" : ""); - if (enc->codec_tag) { - char tag_buf[32]; - av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%s / 0x%04X)", tag_buf, enc->codec_tag); - } + if (enc->codec_tag) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s / 0x%04X)", + av_fourcc2str(enc->codec_tag), enc->codec_tag); switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: @@ -3377,7 +1522,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", %"PRId64" kb/s", bitrate / 1000); } else if (enc->rc_max_rate > 0) { snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", max. %"PRId64" kb/s", (int64_t)enc->rc_max_rate / 1000); + ", max. %"PRId64" kb/s", enc->rc_max_rate / 1000); } } @@ -3432,26 +1577,6 @@ const char *avcodec_license(void) return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; } -void avcodec_flush_buffers(AVCodecContext *avctx) -{ - avctx->internal->draining = 0; - avctx->internal->draining_done = 0; - av_frame_unref(avctx->internal->buffer_frame); - av_packet_unref(avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; - - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) - ff_thread_flush(avctx); - else if (avctx->codec->flush) - avctx->codec->flush(avctx); - - avctx->pts_correction_last_pts = - avctx->pts_correction_last_dts = INT64_MIN; - - if (!avctx->refcounted_frames) - av_frame_unref(avctx->internal->to_free); -} - int av_get_exact_bits_per_sample(enum AVCodecID codec_id) { switch (codec_id) { @@ -3499,6 +1624,8 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) case AV_CODEC_ID_PCM_U32LE: case AV_CODEC_ID_PCM_F32BE: case AV_CODEC_ID_PCM_F32LE: + case AV_CODEC_ID_PCM_F24LE: + case AV_CODEC_ID_PCM_F16LE: return 32; case AV_CODEC_ID_PCM_F64BE: case AV_CODEC_ID_PCM_F64LE: @@ -3595,6 +1722,9 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (id == AV_CODEC_ID_BINKAUDIO_DCT) return (480 << (sr / 22050)) / ch; } + + if (id == AV_CODEC_ID_MP3) + return sr <= 24000 ? 576 : 1152; } if (ba > 0) { @@ -3627,7 +1757,7 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (bps > 0) { /* calc from frame_bytes and bits_per_coded_sample */ - if (id == AV_CODEC_ID_ADPCM_G726) + if (id == AV_CODEC_ID_ADPCM_G726 || id == AV_CODEC_ID_ADPCM_G726LE) return frame_bytes * 8 / bps; } @@ -3931,7 +2061,8 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) { int ret; - dst->owner = src->owner; + dst->owner[0] = src->owner[0]; + dst->owner[1] = src->owner[1]; ret = av_frame_ref(dst->f, src->f); if (ret < 0) @@ -3941,7 +2072,7 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) if (src->progress && !(dst->progress = av_buffer_ref(src->progress))) { - ff_thread_release_buffer(dst->owner, dst); + ff_thread_release_buffer(dst->owner[0], dst); return AVERROR(ENOMEM); } @@ -3957,7 +2088,7 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) { - f->owner = avctx; + f->owner[0] = f->owner[1] = avctx; return ff_get_buffer(avctx, f->f, flags); } @@ -4319,3 +2450,24 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, return 0; } + +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx) +{ + AVRational framerate = avctx->framerate; + int bits_per_coded_sample = avctx->bits_per_coded_sample; + int64_t bitrate; + + if (!(framerate.num && framerate.den)) + framerate = av_inv_q(avctx->time_base); + if (!(framerate.num && framerate.den)) + return 0; + + if (!bits_per_coded_sample) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + bits_per_coded_sample = av_get_bits_per_pixel(desc); + } + bitrate = (int64_t)bits_per_coded_sample * avctx->width * avctx->height * + framerate.num / framerate.den; + + return bitrate; +} diff --git a/media/ffvpx/libavcodec/version.h b/media/ffvpx/libavcodec/version.h index ec8837a4e..10d9ac4eb 100644 --- a/media/ffvpx/libavcodec/version.h +++ b/media/ffvpx/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 64 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 107 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ @@ -60,9 +60,6 @@ #ifndef FF_API_AVCODEC_RESAMPLE #define FF_API_AVCODEC_RESAMPLE FF_API_AUDIO_CONVERT #endif -#ifndef FF_API_GETCHROMA -#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 58) -#endif #ifndef FF_API_MISSING_SAMPLE #define FF_API_MISSING_SAMPLE (LIBAVCODEC_VERSION_MAJOR < 58) #endif @@ -157,6 +154,9 @@ #ifndef FF_API_VAAPI_CONTEXT #define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 58) #endif +#ifndef FF_API_MERGE_SD +#define FF_API_MERGE_SD (LIBAVCODEC_VERSION_MAJOR < 58) +#endif #ifndef FF_API_AVCTX_TIMEBASE #define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) #endif @@ -226,5 +226,18 @@ #ifndef FF_API_NVENC_OLD_NAME #define FF_API_NVENC_OLD_NAME (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_STRUCT_VAAPI_CONTEXT +#define FF_API_STRUCT_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_MERGE_SD_API +#define FF_API_MERGE_SD_API (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_TAG_STRING +#define FF_API_TAG_STRING (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_GETCHROMA +#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 59) +#endif + #endif /* AVCODEC_VERSION_H */ diff --git a/media/ffvpx/libavcodec/videodsp.c b/media/ffvpx/libavcodec/videodsp.c index ba618a7bb..ce9e9eb14 100644 --- a/media/ffvpx/libavcodec/videodsp.c +++ b/media/ffvpx/libavcodec/videodsp.c @@ -52,4 +52,6 @@ av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc) ff_videodsp_init_ppc(ctx, bpc); if (ARCH_X86) ff_videodsp_init_x86(ctx, bpc); + if (ARCH_MIPS) + ff_videodsp_init_mips(ctx, bpc); } diff --git a/media/ffvpx/libavcodec/videodsp.h b/media/ffvpx/libavcodec/videodsp.h index fc01a31dc..c0545f22b 100644 --- a/media/ffvpx/libavcodec/videodsp.h +++ b/media/ffvpx/libavcodec/videodsp.h @@ -83,5 +83,6 @@ void ff_videodsp_init_aarch64(VideoDSPContext *ctx, int bpc); void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc); void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc); void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc); +void ff_videodsp_init_mips(VideoDSPContext *ctx, int bpc); #endif /* AVCODEC_VIDEODSP_H */ diff --git a/media/ffvpx/libavcodec/vlc.h b/media/ffvpx/libavcodec/vlc.h index 9e38f8c6b..42ccddf3f 100644 --- a/media/ffvpx/libavcodec/vlc.h +++ b/media/ffvpx/libavcodec/vlc.h @@ -54,12 +54,28 @@ void ff_free_vlc(VLC *vlc); #define INIT_VLC_LE 2 #define INIT_VLC_USE_NEW_STATIC 4 -#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ +#define INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ + do { \ + static VLC_TYPE table[static_size][2]; \ + (vlc)->table = table; \ + (vlc)->table_allocated = static_size; \ + ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ + INIT_VLC_USE_NEW_STATIC); \ + } while (0) + +#define INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ do { \ static VLC_TYPE table[static_size][2]; \ (vlc)->table = table; \ (vlc)->table_allocated = static_size; \ - init_vlc(vlc, bits, a, b, c, d, e, f, g, INIT_VLC_USE_NEW_STATIC); \ + ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); \ } while (0) +#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ + INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) + +#define INIT_LE_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ + INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) + #endif /* AVCODEC_VLC_H */ diff --git a/media/ffvpx/libavcodec/vorbis_parser.h b/media/ffvpx/libavcodec/vorbis_parser.h index 92050277e..789932ac4 100644 --- a/media/ffvpx/libavcodec/vorbis_parser.h +++ b/media/ffvpx/libavcodec/vorbis_parser.h @@ -32,9 +32,6 @@ typedef struct AVVorbisParseContext AVVorbisParseContext; /** * Allocate and initialize the Vorbis parser using headers in the extradata. - * - * @param avctx codec context - * @param s Vorbis parser context */ AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata, int extradata_size); diff --git a/media/ffvpx/libavcodec/vp3dsp.h b/media/ffvpx/libavcodec/vp3dsp.h index b95adae79..2fdad162c 100644 --- a/media/ffvpx/libavcodec/vp3dsp.h +++ b/media/ffvpx/libavcodec/vp3dsp.h @@ -38,11 +38,11 @@ typedef struct VP3DSPContext { const uint8_t *b, ptrdiff_t stride, int h); - void (*idct_put)(uint8_t *dest, int line_size, int16_t *block); - void (*idct_add)(uint8_t *dest, int line_size, int16_t *block); - void (*idct_dc_add)(uint8_t *dest, int line_size, int16_t *block); - void (*v_loop_filter)(uint8_t *src, int stride, int *bounding_values); - void (*h_loop_filter)(uint8_t *src, int stride, int *bounding_values); + void (*idct_put)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*idct_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*idct_dc_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block); + void (*v_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values); + void (*h_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values); } VP3DSPContext; void ff_vp3dsp_init(VP3DSPContext *c, int flags); diff --git a/media/ffvpx/libavcodec/vp56.h b/media/ffvpx/libavcodec/vp56.h index 56c30919b..b8dda9e73 100644 --- a/media/ffvpx/libavcodec/vp56.h +++ b/media/ffvpx/libavcodec/vp56.h @@ -26,6 +26,7 @@ #ifndef AVCODEC_VP56_H #define AVCODEC_VP56_H +#include "avcodec.h" #include "get_bits.h" #include "hpeldsp.h" #include "bytestream.h" @@ -72,9 +73,9 @@ typedef struct VP56mv { typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, VP56mv *vect); typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, - int offset1, int offset2, int stride, + int offset1, int offset2, ptrdiff_t stride, VP56mv mv, int mask, int select, int luma); -typedef void (*VP56ParseCoeff)(VP56Context *s); +typedef int (*VP56ParseCoeff)(VP56Context *s); typedef void (*VP56DefaultModelsInit)(VP56Context *s); typedef void (*VP56ParseVectorModels)(VP56Context *s); typedef int (*VP56ParseCoeffModels)(VP56Context *s); @@ -179,7 +180,7 @@ struct vp56_context { 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 */ + ptrdiff_t stride[4]; /* stride for each plan */ const uint8_t *vp56_coord_div; VP56ParseVectorAdjustment parse_vector_adjustment; @@ -203,6 +204,9 @@ struct vp56_context { 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; }; @@ -221,7 +225,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, */ extern const uint8_t ff_vp56_norm_shift[256]; -void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size); +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) { diff --git a/media/ffvpx/libavcodec/vp56dsp.h b/media/ffvpx/libavcodec/vp56dsp.h index 7807baa4b..e35e232ea 100644 --- a/media/ffvpx/libavcodec/vp56dsp.h +++ b/media/ffvpx/libavcodec/vp56dsp.h @@ -21,22 +21,24 @@ #ifndef AVCODEC_VP56DSP_H #define AVCODEC_VP56DSP_H +#include <stddef.h> #include <stdint.h> -#include "avcodec.h" typedef struct VP56DSPContext { - void (*edge_filter_hor)(uint8_t *yuv, int stride, int t); - void (*edge_filter_ver)(uint8_t *yuv, int stride, int t); + void (*edge_filter_hor)(uint8_t *yuv, ptrdiff_t stride, int t); + void (*edge_filter_ver)(uint8_t *yuv, ptrdiff_t stride, int t); - void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, int stride, + void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights,const int16_t *v_weights); } VP56DSPContext; -void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, +void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, const int16_t *h_weights, const int16_t *v_weights); -void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec); -void ff_vp6dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec); -void ff_vp6dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec); +void ff_vp5dsp_init(VP56DSPContext *s); +void ff_vp6dsp_init(VP56DSPContext *s); + +void ff_vp6dsp_init_arm(VP56DSPContext *s); +void ff_vp6dsp_init_x86(VP56DSPContext *s); #endif /* AVCODEC_VP56DSP_H */ diff --git a/media/ffvpx/libavcodec/vp56rac.c b/media/ffvpx/libavcodec/vp56rac.c index 6061b7ee7..e70302bf8 100644 --- a/media/ffvpx/libavcodec/vp56rac.c +++ b/media/ffvpx/libavcodec/vp56rac.c @@ -37,11 +37,14 @@ const uint8_t ff_vp56_norm_shift[256]= { 0,0,0,0,0,0,0,0,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) +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/media/ffvpx/libavcodec/vp8.c b/media/ffvpx/libavcodec/vp8.c index c1c3eb707..7841a9d96 100644 --- a/media/ffvpx/libavcodec/vp8.c +++ b/media/ffvpx/libavcodec/vp8.c @@ -261,6 +261,7 @@ 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); @@ -274,13 +275,13 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) if (buf_size - size < 0) return -1; - ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); + ret = ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); + if (ret < 0) + return ret; buf += size; buf_size -= size; } - ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); - - return 0; + return ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); } static void vp7_get_quants(VP8Context *s) @@ -434,8 +435,8 @@ static void copy_chroma(AVFrame *dst, AVFrame *src, int width, int height) } } -static void fade(uint8_t *dst, int dst_linesize, - const uint8_t *src, int src_linesize, +static void fade(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, int width, int height, int alpha, int beta) { @@ -518,7 +519,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si 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); + ret = ff_vp56_init_range_decoder(c, buf, part1_size); + if (ret < 0) + return ret; buf += part1_size; buf_size -= part1_size; @@ -570,7 +573,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si s->lf_delta.enabled = 0; s->num_coeff_partitions = 1; - ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size); + 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 || @@ -699,7 +704,9 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si memset(&s->lf_delta, 0, sizeof(s->lf_delta)); } - ff_vp56_init_range_decoder(c, buf, header_size); + ret = ff_vp56_init_range_decoder(c, buf, header_size); + if (ret < 0) + return ret; buf += header_size; buf_size -= header_size; @@ -765,7 +772,7 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si } static av_always_inline -void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src) +void clamp_mv(VP8mvbounds *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)); @@ -1024,7 +1031,7 @@ void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb, } static av_always_inline -void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb, +void vp8_decode_mvs(VP8Context *s, VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, int layout) { VP8Macroblock *mb_edge[3] = { 0 /* top */, @@ -1095,7 +1102,7 @@ void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb, 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])]); + clamp_mv(mv_bounds, &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); @@ -1109,11 +1116,11 @@ void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb, mb->bmv[0] = mb->mv; } } else { - clamp_mv(s, &mb->mv, &near_mv[CNT_NEAR]); + clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAR]); mb->bmv[0] = mb->mv; } } else { - clamp_mv(s, &mb->mv, &near_mv[CNT_NEAREST]); + clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAREST]); mb->bmv[0] = mb->mv; } } else { @@ -1159,14 +1166,15 @@ void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb, } static av_always_inline -void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, +void decode_mb_mode(VP8Context *s, VP8mvbounds *mv_bounds, + VP8Macroblock *mb, int mb_x, int mb_y, uint8_t *segment, uint8_t *ref, int layout, int is_vp7) { VP56RangeCoder *c = &s->c; - static const char *vp7_feature_name[] = { "q-index", - "lf-delta", - "partial-golden-update", - "blit-pitch" }; + static const char * const vp7_feature_name[] = { "q-index", + "lf-delta", + "partial-golden-update", + "blit-pitch" }; if (is_vp7) { int i; *segment = 0; @@ -1223,7 +1231,7 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, if (is_vp7) vp7_decode_mvs(s, mb, mb_x, mb_y, layout); else - vp8_decode_mvs(s, mb, mb_x, mb_y, layout); + vp8_decode_mvs(s, mv_bounds, 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); @@ -1461,7 +1469,7 @@ void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VP56RangeCoder *c, 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) + ptrdiff_t linesize, ptrdiff_t uvlinesize, int simple) { AV_COPY128(top_border, src_y + 15 * linesize); if (!simple) { @@ -1472,7 +1480,7 @@ void backup_mb_border(uint8_t *top_border, uint8_t *src_y, 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, + uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t 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 @@ -1625,7 +1633,8 @@ void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], 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; + int copy = 0; + ptrdiff_t linesize = s->linesize; uint8_t *dst = ptr + 4 * x; LOCAL_ALIGNED(4, uint8_t, copy_dst, [5 * 8]); @@ -1731,7 +1740,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, uint8_t *src = ref->f->data[0]; if (AV_RN32A(mv)) { - int src_linesize = linesize; + ptrdiff_t 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]; @@ -2077,8 +2086,8 @@ void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f, 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; + ptrdiff_t linesize = s->linesize; + ptrdiff_t 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, @@ -2164,7 +2173,7 @@ void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f, int filter_level = f->filter_level; int inner_limit = f->inner_limit; int inner_filter = f->inner_filter; - int linesize = s->linesize; + ptrdiff_t linesize = s->linesize; if (!filter_level) return; @@ -2197,8 +2206,8 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, 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; + s->mv_bounds.mv_min.y = -MARGIN; + s->mv_bounds.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); @@ -2206,20 +2215,20 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, 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; + s->mv_bounds.mv_min.x = -MARGIN; + s->mv_bounds.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, + decode_mb_mode(s, &s->mv_bounds, 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_bounds.mv_min.x -= 64; + s->mv_bounds.mv_max.x -= 64; } - s->mv_min.y -= 64; - s->mv_max.y -= 64; + s->mv_bounds.mv_min.y -= 64; + s->mv_bounds.mv_max.y -= 64; } } @@ -2239,15 +2248,15 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, #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) { \ + if (atomic_load(&otd->thread_mb_pos) < tmp) { \ pthread_mutex_lock(&otd->lock); \ - td->wait_mb_pos = tmp; \ + atomic_store(&td->wait_mb_pos, tmp); \ do { \ - if (otd->thread_mb_pos >= tmp) \ + if (atomic_load(&otd->thread_mb_pos) >= tmp) \ break; \ pthread_cond_wait(&otd->cond, &otd->lock); \ } while (1); \ - td->wait_mb_pos = INT_MAX; \ + atomic_store(&td->wait_mb_pos, INT_MAX); \ pthread_mutex_unlock(&otd->lock); \ } \ } while (0) @@ -2258,12 +2267,10 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, 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; \ + int pos_check = (is_null) ? 1 : \ + (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)) || \ + (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)); \ + atomic_store(&td->thread_mb_pos, pos); \ if (sliced_threading && pos_check) { \ pthread_mutex_lock(&td->lock); \ pthread_cond_broadcast(&td->cond); \ @@ -2275,12 +2282,12 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, #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, +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_y = atomic_load(&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; @@ -2291,6 +2298,10 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void 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 @@ -2315,10 +2326,12 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void 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; + td->mv_bounds.mv_min.x = -MARGIN; + td->mv_bounds.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) { @@ -2338,7 +2351,7 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void dst[2] - dst[1], 2); if (!s->mb_layout) - decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy, + decode_mb_mode(s, &td->mv_bounds, 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); @@ -2385,8 +2398,8 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void dst[0] += 16; dst[1] += 8; dst[2] += 8; - s->mv_min.x -= 64; - s->mv_max.x -= 64; + td->mv_bounds.mv_min.x -= 64; + td->mv_bounds.mv_max.x -= 64; if (mb_x == s->mb_width + 1) { update_pos(td, mb_y, s->mb_width + 3); @@ -2394,18 +2407,19 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void update_pos(td, mb_y, mb_x); } } + return 0; } -static void vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, +static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) { - decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); + return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); } -static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, +static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) { - decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); + return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); } static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, @@ -2413,7 +2427,7 @@ static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, { 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; + int mb_x, mb_y = atomic_load(&td->thread_mb_pos) >> 16, num_jobs = s->num_jobs; AVFrame *curframe = s->curframe->tf.f; VP8Macroblock *mb; VP8ThreadData *prev_td, *next_td; @@ -2488,19 +2502,24 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int 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; + td->mv_bounds.mv_min.y = -MARGIN - 64 * threadnr; + td->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN - 64 * 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); + atomic_store(&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; + td->mv_bounds.mv_min.y -= 64 * num_jobs; + td->mv_bounds.mv_max.y -= 64 * num_jobs; if (avctx->active_thread_type == FF_THREAD_FRAME) ff_thread_report_progress(&curframe->tf, mb_y, 0); @@ -2531,6 +2550,8 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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 @@ -2646,11 +2667,12 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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; + s->mv_bounds.mv_min.y = -MARGIN; + s->mv_bounds.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; + VP8ThreadData *td = &s->thread_data[i]; + atomic_init(&td->thread_mb_pos, 0); + atomic_init(&td->wait_mb_pos, INT_MAX); } if (is_vp7) avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL, diff --git a/media/ffvpx/libavcodec/vp8.h b/media/ffvpx/libavcodec/vp8.h index 374e1388e..8263997e3 100644 --- a/media/ffvpx/libavcodec/vp8.h +++ b/media/ffvpx/libavcodec/vp8.h @@ -26,6 +26,8 @@ #ifndef AVCODEC_VP8_H #define AVCODEC_VP8_H +#include <stdatomic.h> + #include "libavutil/buffer.h" #include "libavutil/thread.h" @@ -91,6 +93,16 @@ typedef struct VP8Macroblock { VP56mv bmv[16]; } VP8Macroblock; +typedef struct VP8intmv { + int x; + int y; +} VP8intmv; + +typedef struct VP8mvbounds { + VP8intmv mv_min; + VP8intmv mv_max; +} VP8mvbounds; + typedef struct VP8ThreadData { DECLARE_ALIGNED(16, int16_t, block)[6][4][16]; DECLARE_ALIGNED(16, int16_t, block_dc)[16]; @@ -114,12 +126,13 @@ typedef struct VP8ThreadData { 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. + atomic_int thread_mb_pos; // (mb_y << 16) | (mb_x & 0xFFFF) + atomic_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; + VP8mvbounds mv_bounds; } VP8ThreadData; typedef struct VP8Frame { @@ -127,11 +140,6 @@ typedef struct VP8Frame { AVBufferRef *seg_map; } VP8Frame; -typedef struct VP8intmv { - int x; - int y; -} VP8intmv; - #define MAX_THREADS 8 typedef struct VP8Context { VP8ThreadData *thread_data; @@ -143,15 +151,14 @@ typedef struct VP8Context { uint16_t mb_width; /* number of horizontal MB */ uint16_t mb_height; /* number of vertical MB */ - int linesize; - int uvlinesize; + ptrdiff_t linesize; + ptrdiff_t uvlinesize; uint8_t keyframe; uint8_t deblock_filter; uint8_t mbskip_enabled; uint8_t profile; - VP8intmv mv_min; - VP8intmv mv_max; + VP8mvbounds mv_bounds; int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type int ref_count[3]; @@ -275,7 +282,7 @@ typedef struct VP8Context { */ int mb_layout; - void (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); + 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; diff --git a/media/ffvpx/libavcodec/vp8_parser.c b/media/ffvpx/libavcodec/vp8_parser.c index afc7f991e..609f5077d 100644 --- a/media/ffvpx/libavcodec/vp8_parser.c +++ b/media/ffvpx/libavcodec/vp8_parser.c @@ -1,6 +1,4 @@ /* - * Copyright (C) 2008 Michael Niedermayer - * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,15 +16,56 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "parser.h" +#include "libavutil/intreadwrite.h" + +#include "avcodec.h" static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { - s->pict_type = (buf[0] & 0x01) ? AV_PICTURE_TYPE_P - : AV_PICTURE_TYPE_I; + unsigned int frame_type; + unsigned int profile; + + if (buf_size < 3) + return buf_size; + + frame_type = buf[0] & 1; + profile = (buf[0] >> 1) & 7; + if (profile > 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid profile %u.\n", profile); + return buf_size; + } + + avctx->profile = profile; + s->key_frame = frame_type == 0; + s->pict_type = frame_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + s->format = AV_PIX_FMT_YUV420P; + s->field_order = AV_FIELD_PROGRESSIVE; + s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; + + if (frame_type == 0) { + unsigned int sync_code; + unsigned int width, height; + + if (buf_size < 10) + return buf_size; + + sync_code = AV_RL24(buf + 3); + if (sync_code != 0x2a019d) { + av_log(avctx, AV_LOG_ERROR, "Invalid sync code %06x.\n", sync_code); + return buf_size; + } + + width = AV_RL16(buf + 6) & 0x3fff; + height = AV_RL16(buf + 8) & 0x3fff; + + s->width = width; + s->height = height; + s->coded_width = FFALIGN(width, 16); + s->coded_height = FFALIGN(height, 16); + } *poutbuf = buf; *poutbuf_size = buf_size; diff --git a/media/ffvpx/libavcodec/vp8dsp.c b/media/ffvpx/libavcodec/vp8dsp.c index 07bea69c7..fed5c67a9 100644 --- a/media/ffvpx/libavcodec/vp8dsp.c +++ b/media/ffvpx/libavcodec/vp8dsp.c @@ -53,7 +53,8 @@ static void name ## _idct_dc_add4y_c(uint8_t *dst, int16_t block[4][16], \ #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; + int i; + unsigned a1, b1, c1, d1; int16_t tmp[16]; for (i = 0; i < 4; i++) { @@ -61,10 +62,10 @@ static void vp7_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16]) 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; + 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++) { @@ -73,10 +74,10 @@ static void vp7_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16]) 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; + 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; } } @@ -95,7 +96,8 @@ static void vp7_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16]) static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride) { - int i, a1, b1, c1, d1; + int i; + unsigned a1, b1, c1, d1; int16_t tmp[16]; for (i = 0; i < 4; i++) { @@ -104,10 +106,10 @@ static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride) 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; + 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++) { @@ -116,13 +118,13 @@ static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride) 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)); + ((int)(a1 + d1 + 0x20000) >> 18)); dst[3 * stride + i] = av_clip_uint8(dst[3 * stride + i] + - ((a1 - d1 + 0x20000) >> 18)); + ((int)(a1 - d1 + 0x20000) >> 18)); dst[1 * stride + i] = av_clip_uint8(dst[1 * stride + i] + - ((b1 + c1 + 0x20000) >> 18)); + ((int)(b1 + c1 + 0x20000) >> 18)); dst[2 * stride + i] = av_clip_uint8(dst[2 * stride + i] + - ((b1 - c1 + 0x20000) >> 18)); + ((int)(b1 - c1 + 0x20000) >> 18)); } } diff --git a/media/ffvpx/libavcodec/vp8dsp.h b/media/ffvpx/libavcodec/vp8dsp.h index 0401c9221..eaae4aed6 100644 --- a/media/ffvpx/libavcodec/vp8dsp.h +++ b/media/ffvpx/libavcodec/vp8dsp.h @@ -70,12 +70,12 @@ typedef struct VP8DSPContext { void (*vp8_h_loop_filter_simple)(uint8_t *dst, ptrdiff_t stride, int flim); /** - * first dimension: width>>3, height is assumed equal to width + * first dimension: 4-log2(width) * second dimension: 0 if no vertical interpolation is needed; * 1 4-tap vertical interpolation filter (my & 1) * 2 6-tap vertical interpolation filter (!(my & 1)) * third dimension: same as second dimension, for horizontal interpolation - * so something like put_vp8_epel_pixels_tab[width>>3][2*!!my-(my&1)][2*!!mx-(mx&1)](..., mx, my) + * so something like put_vp8_epel_pixels_tab[4-log2(width)][2*!!my-(my&1)][2*!!mx-(mx&1)](..., mx, my) */ vp8_mc_func put_vp8_epel_pixels_tab[3][3][3]; vp8_mc_func put_vp8_bilinear_pixels_tab[3][3][3]; diff --git a/media/ffvpx/libavcodec/vp9.c b/media/ffvpx/libavcodec/vp9.c index 1aab6ba03..f2cf19424 100644 --- a/media/ffvpx/libavcodec/vp9.c +++ b/media/ffvpx/libavcodec/vp9.c @@ -30,176 +30,97 @@ #include "vp56.h" #include "vp9.h" #include "vp9data.h" -#include "vp9dsp.h" +#include "vp9dec.h" #include "libavutil/avassert.h" #include "libavutil/pixdesc.h" #define VP9_SYNCCODE 0x498342 -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 */]; -}; +#if HAVE_THREADS +static void vp9_free_entries(AVCodecContext *avctx) { + VP9Context *s = avctx->priv_data; -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 { - VP9SharedContext s; - - 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; - - uint8_t ss_h, ss_v; - uint8_t last_bpp, bpp, bpp_index, bytesperpixel; - uint8_t last_keyframe; - // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal - // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads - // and are therefore per-stream. pix_fmt represents the value in the header - // of the currently processed frame. - int w, h; - enum AVPixelFormat pix_fmt, last_fmt, gf_fmt; - unsigned sb_cols, sb_rows, rows, cols; - ThreadFrame next_refs[8]; - - struct { - uint8_t lim_lut[64]; - uint8_t mblim_lut[64]; - } filter_lut; - unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end; - 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]; - } 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; - - // 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 }, + if (avctx->active_thread_type & FF_THREAD_SLICE) { + pthread_mutex_destroy(&s->progress_mutex); + pthread_cond_destroy(&s->progress_cond); + av_freep(&s->entries); } -}; +} + +static int vp9_alloc_entries(AVCodecContext *avctx, int n) { + VP9Context *s = avctx->priv_data; + int i; + + if (avctx->active_thread_type & FF_THREAD_SLICE) { + if (s->entries) + av_freep(&s->entries); + + s->entries = av_malloc_array(n, sizeof(atomic_int)); + + if (!s->entries) { + av_freep(&s->entries); + return AVERROR(ENOMEM); + } -static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f) + for (i = 0; i < n; i++) + atomic_init(&s->entries[i], 0); + + pthread_mutex_init(&s->progress_mutex, NULL); + pthread_cond_init(&s->progress_cond, NULL); + } + return 0; +} + +static void vp9_report_tile_progress(VP9Context *s, int field, int n) { + pthread_mutex_lock(&s->progress_mutex); + atomic_fetch_add_explicit(&s->entries[field], n, memory_order_release); + pthread_cond_signal(&s->progress_cond); + pthread_mutex_unlock(&s->progress_mutex); +} + +static void vp9_await_tile_progress(VP9Context *s, int field, int n) { + if (atomic_load_explicit(&s->entries[field], memory_order_acquire) >= n) + return; + + pthread_mutex_lock(&s->progress_mutex); + while (atomic_load_explicit(&s->entries[field], memory_order_relaxed) != n) + pthread_cond_wait(&s->progress_cond, &s->progress_mutex); + pthread_mutex_unlock(&s->progress_mutex); +} +#else +static void vp9_free_entries(AVCodecContext *avctx) {} +static int vp9_alloc_entries(AVCodecContext *avctx, int n) { return 0; } +#endif + +static void vp9_frame_unref(AVCodecContext *avctx, VP9Frame *f) { - ff_thread_release_buffer(ctx, &f->tf); + ff_thread_release_buffer(avctx, &f->tf); av_buffer_unref(&f->extradata); av_buffer_unref(&f->hwaccel_priv_buf); f->segmentation_map = NULL; f->hwaccel_picture_private = NULL; } -static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) +static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int ret, sz; - if ((ret = ff_thread_get_buffer(ctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0) + ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) return ret; + sz = 64 * s->sb_cols * s->sb_rows; - if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) { + f->extradata = av_buffer_allocz(sz * (1 + sizeof(VP9mvrefPair))); + if (!f->extradata) { goto fail; } f->segmentation_map = f->extradata->data; - f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz); + f->mv = (VP9mvrefPair *) (f->extradata->data + sz); - if (ctx->hwaccel) { - const AVHWAccel *hwaccel = ctx->hwaccel; + if (avctx->hwaccel) { + const AVHWAccel *hwaccel = avctx->hwaccel; av_assert0(!f->hwaccel_picture_private); if (hwaccel->frame_priv_data_size) { f->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); @@ -212,19 +133,21 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) return 0; fail: - vp9_unref_frame(ctx, f); + vp9_frame_unref(avctx, f); return AVERROR(ENOMEM); } -static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src) +static int vp9_frame_ref(AVCodecContext *avctx, VP9Frame *dst, VP9Frame *src) { - int res; + int ret; - if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) { - return res; - } else if (!(dst->extradata = av_buffer_ref(src->extradata))) { + ret = ff_thread_ref_frame(&dst->tf, &src->tf); + if (ret < 0) + return ret; + + dst->extradata = av_buffer_ref(src->extradata); + if (!dst->extradata) goto fail; - } dst->segmentation_map = src->segmentation_map; dst->mv = src->mv; @@ -240,44 +163,54 @@ static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src) return 0; fail: - vp9_unref_frame(ctx, dst); + vp9_frame_unref(avctx, dst); return AVERROR(ENOMEM); } -static int update_size(AVCodecContext *ctx, int w, int h) +static int update_size(AVCodecContext *avctx, int w, int h) { -#define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + CONFIG_VP9_D3D11VA_HWACCEL + CONFIG_VP9_VAAPI_HWACCEL) +#define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + CONFIG_VP9_D3D11VA_HWACCEL * 2 + CONFIG_VP9_VAAPI_HWACCEL) enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts; - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; uint8_t *p; - int bytesperpixel = s->bytesperpixel, res, cols, rows; + int bytesperpixel = s->bytesperpixel, ret, cols, rows; + int lflvl_len, i; av_assert0(w > 0 && h > 0); if (!(s->pix_fmt == s->gf_fmt && w == s->w && h == s->h)) { - if ((res = ff_set_dimensions(ctx, w, h)) < 0) - return res; + if ((ret = ff_set_dimensions(avctx, w, h)) < 0) + return ret; - if (s->pix_fmt == AV_PIX_FMT_YUV420P) { + switch (s->pix_fmt) { + case AV_PIX_FMT_YUV420P: #if CONFIG_VP9_DXVA2_HWACCEL *fmtp++ = AV_PIX_FMT_DXVA2_VLD; #endif #if CONFIG_VP9_D3D11VA_HWACCEL *fmtp++ = AV_PIX_FMT_D3D11VA_VLD; + *fmtp++ = AV_PIX_FMT_D3D11; #endif #if CONFIG_VP9_VAAPI_HWACCEL *fmtp++ = AV_PIX_FMT_VAAPI; #endif + break; + case AV_PIX_FMT_YUV420P10: + case AV_PIX_FMT_YUV420P12: +#if CONFIG_VP9_VAAPI_HWACCEL + *fmtp++ = AV_PIX_FMT_VAAPI; +#endif + break; } *fmtp++ = s->pix_fmt; *fmtp = AV_PIX_FMT_NONE; - res = ff_thread_get_format(ctx, pix_fmts); - if (res < 0) - return res; + ret = ff_thread_get_format(avctx, pix_fmts); + if (ret < 0) + return ret; - ctx->pix_fmt = res; + avctx->pix_fmt = ret; s->gf_fmt = s->pix_fmt; s->w = w; s->h = h; @@ -294,13 +227,14 @@ static int update_size(AVCodecContext *ctx, int w, int h) s->sb_rows = (h + 63) >> 6; s->cols = (w + 7) >> 3; s->rows = (h + 7) >> 3; + lflvl_len = avctx->active_thread_type == FF_THREAD_SLICE ? s->sb_rows : 1; #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))); + lflvl_len * sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); if (!p) return AVERROR(ENOMEM); assign(s->intra_pred_data[0], uint8_t *, 64 * bytesperpixel); @@ -319,65 +253,78 @@ static int update_size(AVCodecContext *ctx, int w, int h) 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); + assign(s->lflvl, VP9Filter *, lflvl_len); #undef assign - // these will be re-allocated a little later - av_freep(&s->b_base); - av_freep(&s->block_base); + if (s->td) { + for (i = 0; i < s->active_tile_cols; i++) { + av_freep(&s->td[i].b_base); + av_freep(&s->td[i].block_base); + } + } - if (s->bpp != s->last_bpp) { - ff_vp9dsp_init(&s->dsp, s->bpp, ctx->flags & AV_CODEC_FLAG_BITEXACT); - ff_videodsp_init(&s->vdsp, s->bpp); - s->last_bpp = s->bpp; + if (s->s.h.bpp != s->last_bpp) { + ff_vp9dsp_init(&s->dsp, s->s.h.bpp, avctx->flags & AV_CODEC_FLAG_BITEXACT); + ff_videodsp_init(&s->vdsp, s->s.h.bpp); + s->last_bpp = s->s.h.bpp; } return 0; } -static int update_block_buffers(AVCodecContext *ctx) +static int update_block_buffers(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + int i; + VP9Context *s = avctx->priv_data; int chroma_blocks, chroma_eobs, bytesperpixel = s->bytesperpixel; + VP9TileData *td = &s->td[0]; - if (s->b_base && s->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) + if (td->b_base && td->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) return 0; - av_free(s->b_base); - av_free(s->block_base); + av_free(td->b_base); + av_free(td->block_base); chroma_blocks = 64 * 64 >> (s->ss_h + s->ss_v); chroma_eobs = 16 * 16 >> (s->ss_h + s->ss_v); if (s->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) + + td->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block)); + td->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) + if (!td->b_base || !td->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; + td->uvblock_base[0] = td->block_base + sbs * 64 * 64 * bytesperpixel; + td->uvblock_base[1] = td->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel; + td->eob_base = (uint8_t *) (td->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel); + td->uveob_base[0] = td->eob_base + 16 * 16 * sbs; + td->uveob_base[1] = td->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; + for (i = 1; i < s->active_tile_cols; i++) { + if (s->td[i].b_base && s->td[i].block_base) { + av_free(s->td[i].b_base); + av_free(s->td[i].block_base); + } + } + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].b_base = av_malloc(sizeof(VP9Block)); + s->td[i].block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + + 16 * 16 + 2 * chroma_eobs); + if (!s->td[i].b_base || !s->td[i].block_base) + return AVERROR(ENOMEM); + s->td[i].uvblock_base[0] = s->td[i].block_base + 64 * 64 * bytesperpixel; + s->td[i].uvblock_base[1] = s->td[i].uvblock_base[0] + chroma_blocks * bytesperpixel; + s->td[i].eob_base = (uint8_t *) (s->td[i].uvblock_base[1] + chroma_blocks * bytesperpixel); + s->td[i].uveob_base[0] = s->td[i].eob_base + 16 * 16; + s->td[i].uveob_base[1] = s->td[i].uveob_base[0] + chroma_eobs; + } } s->block_alloc_using_2pass = s->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 +// 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); @@ -386,7 +333,11 @@ static av_always_inline int get_sbits_inv(GetBitContext *gb, int n) 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); + if (v > 2 * m) + return v; + if (v & 1) + return m - ((v + 1) >> 1); + return m + (v >> 1); } // differential forward probability updates @@ -417,13 +368,13 @@ static int update_prob(VP56RangeCoder *c, int p) /* 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 + * 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 + * 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' @@ -448,34 +399,34 @@ static int update_prob(VP56RangeCoder *c, int p) 255 - inv_recenter_nonneg(inv_map_table[d], 255 - p); } -static int read_colorspace_details(AVCodecContext *ctx) +static int read_colorspace_details(AVCodecContext *avctx) { 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; - int bits = ctx->profile <= 1 ? 0 : 1 + get_bits1(&s->gb); // 0:8, 1:10, 2:12 + VP9Context *s = avctx->priv_data; + int bits = avctx->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 + s->s.h.bpp = 8 + bits * 2; + s->bytesperpixel = (7 + s->s.h.bpp) >> 3; + avctx->colorspace = colorspaces[get_bits(&s->gb, 3)]; + if (avctx->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 }; s->ss_h = s->ss_v = 0; - ctx->color_range = AVCOL_RANGE_JPEG; + avctx->color_range = AVCOL_RANGE_JPEG; s->pix_fmt = pix_fmt_rgb[bits]; - if (ctx->profile & 1) { + if (avctx->profile & 1) { if (get_bits1(&s->gb)) { - av_log(ctx, AV_LOG_ERROR, "Reserved bit set in RGB\n"); + av_log(avctx, 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); + av_log(avctx, AV_LOG_ERROR, "RGB not supported in profile %d\n", + avctx->profile); return AVERROR_INVALIDDATA; } } else { @@ -487,18 +438,18 @@ static int read_colorspace_details(AVCodecContext *ctx) { { 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) { + avctx->color_range = get_bits1(&s->gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + if (avctx->profile & 1) { s->ss_h = get_bits1(&s->gb); s->ss_v = get_bits1(&s->gb); s->pix_fmt = pix_fmt_for_ss[bits][s->ss_v][s->ss_h]; if (s->pix_fmt == AV_PIX_FMT_YUV420P) { - av_log(ctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile %d\n", - ctx->profile); + av_log(avctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile %d\n", + avctx->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); + av_log(avctx, AV_LOG_ERROR, "Profile %d color details reserved bit set\n", + avctx->profile); return AVERROR_INVALIDDATA; } } else { @@ -510,48 +461,51 @@ static int read_colorspace_details(AVCodecContext *ctx) return 0; } -static int decode_frame_header(AVCodecContext *ctx, +static int decode_frame_header(AVCodecContext *avctx, 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; + VP9Context *s = avctx->priv_data; + int c, i, j, k, l, m, n, w, h, max, size2, ret, sharp; 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 ((ret = init_get_bits8(&s->gb, data, size)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n"); + return ret; } if (get_bits(&s->gb, 2) != 0x2) { // frame marker - av_log(ctx, AV_LOG_ERROR, "Invalid frame marker\n"); + av_log(avctx, 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); + avctx->profile = get_bits1(&s->gb); + avctx->profile |= get_bits1(&s->gb) << 1; + if (avctx->profile == 3) avctx->profile += get_bits1(&s->gb); + if (avctx->profile > 3) { + av_log(avctx, AV_LOG_ERROR, "Profile %d is not yet supported\n", avctx->profile); return AVERROR_INVALIDDATA; } - s->s.h.profile = ctx->profile; + s->s.h.profile = avctx->profile; if (get_bits1(&s->gb)) { *ref = get_bits(&s->gb, 3); return 0; } + s->last_keyframe = s->s.h.keyframe; - s->s.h.keyframe = !get_bits1(&s->gb); - last_invisible = s->s.h.invisible; - s->s.h.invisible = !get_bits1(&s->gb); - s->s.h.errorres = get_bits1(&s->gb); + s->s.h.keyframe = !get_bits1(&s->gb); + + last_invisible = s->s.h.invisible; + s->s.h.invisible = !get_bits1(&s->gb); + s->s.h.errorres = get_bits1(&s->gb); s->s.h.use_last_frame_mvs = !s->s.h.errorres && !last_invisible; + if (s->s.h.keyframe) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode - av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); return AVERROR_INVALIDDATA; } - if ((res = read_colorspace_details(ctx)) < 0) - return res; + if ((ret = read_colorspace_details(avctx)) < 0) + return ret; // for profile 1, here follows the subsampling bits s->s.h.refreshrefmask = 0xff; w = get_bits(&s->gb, 16) + 1; @@ -559,24 +513,24 @@ static int decode_frame_header(AVCodecContext *ctx, if (get_bits1(&s->gb)) // display size skip_bits(&s->gb, 32); } else { - s->s.h.intraonly = s->s.h.invisible ? get_bits1(&s->gb) : 0; - s->s.h.resetctx = s->s.h.errorres ? 0 : get_bits(&s->gb, 2); + s->s.h.intraonly = s->s.h.invisible ? get_bits1(&s->gb) : 0; + s->s.h.resetctx = s->s.h.errorres ? 0 : get_bits(&s->gb, 2); if (s->s.h.intraonly) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode - av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n"); return AVERROR_INVALIDDATA; } - if (ctx->profile >= 1) { - if ((res = read_colorspace_details(ctx)) < 0) - return res; + if (avctx->profile >= 1) { + if ((ret = read_colorspace_details(avctx)) < 0) + return ret; } else { s->ss_h = s->ss_v = 1; - s->bpp = 8; + s->s.h.bpp = 8; s->bpp_index = 0; s->bytesperpixel = 1; s->pix_fmt = AV_PIX_FMT_YUV420P; - ctx->colorspace = AVCOL_SPC_BT470BG; - ctx->color_range = AVCOL_RANGE_JPEG; + avctx->colorspace = AVCOL_SPC_BT470BG; + avctx->color_range = AVCOL_RANGE_MPEG; } s->s.h.refreshrefmask = get_bits(&s->gb, 8); w = get_bits(&s->gb, 16) + 1; @@ -594,7 +548,7 @@ static int decode_frame_header(AVCodecContext *ctx, if (!s->s.refs[s->s.h.refidx[0]].f->buf[0] || !s->s.refs[s->s.h.refidx[1]].f->buf[0] || !s->s.refs[s->s.h.refidx[2]].f->buf[0]) { - av_log(ctx, AV_LOG_ERROR, "Not all references are available\n"); + av_log(avctx, AV_LOG_ERROR, "Not all references are available\n"); return AVERROR_INVALIDDATA; } if (get_bits1(&s->gb)) { @@ -660,8 +614,20 @@ static int decode_frame_header(AVCodecContext *ctx, 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->s.h.filter.sharpness != sharp) - memset(s->filter_lut.lim_lut, 0, sizeof(s->filter_lut.lim_lut)); + if (s->s.h.filter.sharpness != sharp) { + for (i = 1; i <= 63; i++) { + int limit = i; + + if (sharp > 0) { + limit >>= (sharp + 3) >> 2; + limit = FFMIN(limit, 9 - sharp); + } + limit = FFMAX(limit, 1); + + s->filter_lut.lim_lut[i] = limit; + s->filter_lut.mblim_lut[i] = 2 * (i + 2) + limit; + } + } s->s.h.filter.sharpness = sharp; if ((s->s.h.lf_delta.enabled = get_bits1(&s->gb))) { if ((s->s.h.lf_delta.updated = get_bits1(&s->gb))) { @@ -682,7 +648,7 @@ static int decode_frame_header(AVCodecContext *ctx, s->s.h.lossless = s->s.h.yac_qi == 0 && s->s.h.ydc_qdelta == 0 && s->s.h.uvdc_qdelta == 0 && s->s.h.uvac_qdelta == 0; if (s->s.h.lossless) - ctx->properties |= FF_CODEC_PROPERTY_LOSSLESS; + avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS; /* segmentation header info */ if ((s->s.h.segmentation.enabled = get_bits1(&s->gb))) { @@ -690,11 +656,10 @@ static int decode_frame_header(AVCodecContext *ctx, for (i = 0; i < 7; i++) s->s.h.segmentation.prob[i] = get_bits1(&s->gb) ? get_bits(&s->gb, 8) : 255; - if ((s->s.h.segmentation.temporal = get_bits1(&s->gb))) { + if ((s->s.h.segmentation.temporal = get_bits1(&s->gb))) for (i = 0; i < 3; i++) s->s.h.segmentation.pred_prob[i] = get_bits1(&s->gb) ? get_bits(&s->gb, 8) : 255; - } } if (get_bits1(&s->gb)) { @@ -728,10 +693,10 @@ static int decode_frame_header(AVCodecContext *ctx, quvac = av_clip_uintp2(qyac + s->s.h.uvac_qdelta, 8); qyac = av_clip_uintp2(qyac, 8); - s->s.h.segmentation.feat[i].qmul[0][0] = vp9_dc_qlookup[s->bpp_index][qydc]; - s->s.h.segmentation.feat[i].qmul[0][1] = vp9_ac_qlookup[s->bpp_index][qyac]; - s->s.h.segmentation.feat[i].qmul[1][0] = vp9_dc_qlookup[s->bpp_index][quvdc]; - s->s.h.segmentation.feat[i].qmul[1][1] = vp9_ac_qlookup[s->bpp_index][quvac]; + s->s.h.segmentation.feat[i].qmul[0][0] = ff_vp9_dc_qlookup[s->bpp_index][qydc]; + s->s.h.segmentation.feat[i].qmul[0][1] = ff_vp9_ac_qlookup[s->bpp_index][qyac]; + s->s.h.segmentation.feat[i].qmul[1][0] = ff_vp9_dc_qlookup[s->bpp_index][quvdc]; + s->s.h.segmentation.feat[i].qmul[1][1] = ff_vp9_ac_qlookup[s->bpp_index][quvac]; sh = s->s.h.filter.level >= 32; if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[i].lf_enabled) { @@ -761,10 +726,10 @@ static int decode_frame_header(AVCodecContext *ctx, } /* tiling info */ - if ((res = update_size(ctx, w, h)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", + if ((ret = update_size(avctx, w, h)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", w, h, s->pix_fmt); - return res; + return ret; } for (s->s.h.tiling.log2_tile_cols = 0; s->sb_cols > (64 << s->s.h.tiling.log2_tile_cols); @@ -780,12 +745,36 @@ static int decode_frame_header(AVCodecContext *ctx, s->s.h.tiling.log2_tile_rows = decode012(&s->gb); s->s.h.tiling.tile_rows = 1 << s->s.h.tiling.log2_tile_rows; if (s->s.h.tiling.tile_cols != (1 << s->s.h.tiling.log2_tile_cols)) { + int n_range_coders; + VP56RangeCoder *rc; + + if (s->td) { + for (i = 0; i < s->active_tile_cols; i++) { + av_free(s->td[i].b_base); + av_free(s->td[i].block_base); + } + av_free(s->td); + } + s->s.h.tiling.tile_cols = 1 << s->s.h.tiling.log2_tile_cols; - s->c_b = av_fast_realloc(s->c_b, &s->c_b_size, - sizeof(VP56RangeCoder) * s->s.h.tiling.tile_cols); - if (!s->c_b) { - av_log(ctx, AV_LOG_ERROR, "Ran out of memory during range coder init\n"); + vp9_free_entries(avctx); + s->active_tile_cols = avctx->active_thread_type == FF_THREAD_SLICE ? + s->s.h.tiling.tile_cols : 1; + vp9_alloc_entries(avctx, s->sb_rows); + if (avctx->active_thread_type == FF_THREAD_SLICE) { + n_range_coders = 4; // max_tile_rows + } else { + n_range_coders = s->s.h.tiling.tile_cols; + } + s->td = av_mallocz_array(s->active_tile_cols, sizeof(VP9TileData) + + n_range_coders * sizeof(VP56RangeCoder)); + if (!s->td) return AVERROR(ENOMEM); + rc = (VP56RangeCoder *) &s->td[s->active_tile_cols]; + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].s = s; + s->td[i].c_b = rc; + rc += n_range_coders; } } @@ -795,17 +784,17 @@ static int decode_frame_header(AVCodecContext *ctx, AVFrame *ref = s->s.refs[s->s.h.refidx[i]].f; int refw = ref->width, refh = ref->height; - if (ref->format != ctx->pix_fmt) { - av_log(ctx, AV_LOG_ERROR, + if (ref->format != avctx->pix_fmt) { + av_log(avctx, AV_LOG_ERROR, "Ref pixfmt (%s) did not match current frame (%s)", av_get_pix_fmt_name(ref->format), - av_get_pix_fmt_name(ctx->pix_fmt)); + av_get_pix_fmt_name(avctx->pix_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, + av_log(avctx, AV_LOG_ERROR, "Invalid ref frame dimensions %dx%d for frame size %dx%d\n", refw, refh, w, h); return AVERROR_INVALIDDATA; @@ -820,19 +809,19 @@ static int decode_frame_header(AVCodecContext *ctx, if (s->s.h.keyframe || s->s.h.errorres || (s->s.h.intraonly && s->s.h.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)); + s->prob_ctx[3].p = ff_vp9_default_probs; + memcpy(s->prob_ctx[0].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[1].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[2].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); + memcpy(s->prob_ctx[3].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); } else if (s->s.h.intraonly && s->s.h.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)); + s->prob_ctx[c].p = ff_vp9_default_probs; + memcpy(s->prob_ctx[c].coef, ff_vp9_default_coef_probs, + sizeof(ff_vp9_default_coef_probs)); } // next 16 bits is size of the rest of the header (arith-coded) @@ -841,24 +830,30 @@ static int decode_frame_header(AVCodecContext *ctx, data2 = align_get_bits(&s->gb); if (size2 > size - (data2 - data)) { - av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n"); + av_log(avctx, AV_LOG_ERROR, "Invalid compressed header size\n"); return AVERROR_INVALIDDATA; } - ff_vp56_init_range_decoder(&s->c, data2, size2); + ret = ff_vp56_init_range_decoder(&s->c, data2, size2); + if (ret < 0) + return ret; + if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit - av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n"); + av_log(avctx, AV_LOG_ERROR, "Marker bit was set\n"); return AVERROR_INVALIDDATA; } - if (s->s.h.keyframe || s->s.h.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)); + for (i = 0; i < s->active_tile_cols; i++) { + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(s->td[i].counts.coef, 0, sizeof(s->td[0].counts.coef)); + memset(s->td[i].counts.eob, 0, sizeof(s->td[0].counts.eob)); + } else { + memset(&s->td[i].counts, 0, sizeof(s->td[0].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)? + + /* 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 @@ -899,13 +894,12 @@ static int decode_frame_header(AVCodecContext *ctx, 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)) { + if (vp56_rac_get_prob_branchy(&s->c, 252)) p[n] = update_prob(&s->c, r[n]); - } else { + else p[n] = r[n]; - } } - p[3] = 0; + memcpy(&p[3], ff_vp9_model_pareto8[p[2]], 8); } } else { for (j = 0; j < 2; j++) @@ -917,7 +911,7 @@ static int decode_frame_header(AVCodecContext *ctx, if (m > 3 && l == 0) // dc only has 3 pt break; memcpy(p, r, 3); - p[3] = 0; + memcpy(&p[3], ff_vp9_model_pareto8[p[2]], 8); } } if (s->s.h.txfmmode == i) @@ -988,7 +982,8 @@ static int decode_frame_header(AVCodecContext *ctx, 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]); + 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++) @@ -997,7 +992,8 @@ static int decode_frame_header(AVCodecContext *ctx, 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; + 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)) @@ -1005,7 +1001,8 @@ static int decode_frame_header(AVCodecContext *ctx, (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; + 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)) @@ -1042,2354 +1039,13 @@ static int decode_frame_header(AVCodecContext *ctx, 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->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->tile_col_start) { - struct VP9mvrefPair *mv = &s->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->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - struct VP9mvrefPair *mv = &s->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->s.h.use_last_frame_mvs) { - struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; - - if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass) - ff_thread_await_progress(&s->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->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { - struct VP9mvrefPair *mv = &s->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->s.h.signbias[mv->ref[0]] != s->s.h.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->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); - } - } - } - - // MV at this position in previous frame, using different reference frame - if (s->s.h.use_last_frame_mvs) { - struct VP9mvrefPair *mv = &s->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->s.h.signbias[mv->ref[0]] != s->s.h.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->s.h.signbias[mv->ref[1]] != s->s.h.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->s.h.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->s.h.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->tile_col_start; - int vref, filter_id; - - if (!s->s.h.segmentation.enabled) { - b->seg_id = 0; - } else if (s->s.h.keyframe || s->s.h.intraonly) { - b->seg_id = !s->s.h.segmentation.update_map ? 0 : - vp8_rac_get_tree(&s->c, vp9_segmentation_tree, s->s.h.segmentation.prob); - } else if (!s->s.h.segmentation.update_map || - (s->s.h.segmentation.temporal && - vp56_rac_get_prob_branchy(&s->c, - s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] + - s->left_segpred_ctx[row7]]))) { - if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) { - int pred = 8, x; - uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map; - - if (!s->s.frames[REF_FRAME_SEGMAP].uses_2pass) - ff_thread_await_progress(&s->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->s.h.segmentation.prob); - - memset(&s->above_segpred_ctx[col], 0, w4); - memset(&s->left_segpred_ctx[row7], 0, h4); - } - if (s->s.h.segmentation.enabled && - (s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) { - setctx_2d(&s->s.frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col], - bw4, bh4, 8 * s->sb_cols, b->seg_id); - } - - b->skip = s->s.h.segmentation.enabled && - s->s.h.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->s.h.keyframe || s->s.h.intraonly) { - b->intra = 1; - } else if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { - b->intra = !s->s.h.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->s.h.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->s.h.txfmmode); - } - - if (s->s.h.keyframe || s->s.h.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->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { - av_assert2(s->s.h.segmentation.feat[b->seg_id].ref_val != 0); - b->comp = 0; - b->ref[0] = s->s.h.segmentation.feat[b->seg_id].ref_val - 1; - } else { - // read comp_pred flag - if (s->s.h.comppredmode != PRED_SWITCHABLE) { - b->comp = s->s.h.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->s.h.fixcompref); - } else if (s->left_comp_ctx[row7]) { - c = 2 + (s->above_intra_ctx[col] || - s->above_ref_ctx[col] == s->s.h.fixcompref); - } else { - c = (!s->above_intra_ctx[col] && - s->above_ref_ctx[col] == s->s.h.fixcompref) ^ - (!s->left_intra_ctx[row7] && - s->left_ref_ctx[row & 7] == s->s.h.fixcompref); - } - } else { - c = s->above_comp_ctx[col] ? 3 : - (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref); - } - } else if (have_l) { - c = s->left_comp_ctx[row7] ? 3 : - (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->s.h.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->s.h.signbias[s->s.h.fixcompref], var_idx = !fix_idx, c, bit; - - b->ref[fix_idx] = s->s.h.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->s.h.varcompref[1]); - } - } else if (s->left_intra_ctx[row7]) { - c = 1 + 2 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); - } else { - int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; - - if (refl == refa && refa == s->s.h.varcompref[1]) { - c = 0; - } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { - if ((refa == s->s.h.fixcompref && refl == s->s.h.varcompref[0]) || - (refl == s->s.h.fixcompref && refa == s->s.h.varcompref[0])) { - c = 4; - } else { - c = (refa == refl) ? 3 : 1; - } - } else if (!s->left_comp_ctx[row7]) { - if (refa == s->s.h.varcompref[1] && refl != s->s.h.varcompref[1]) { - c = 1; - } else { - c = (refl == s->s.h.varcompref[1] && - refa != s->s.h.varcompref[1]) ? 2 : 4; - } - } else if (!s->above_comp_ctx[col]) { - if (refl == s->s.h.varcompref[1] && refa != s->s.h.varcompref[1]) { - c = 1; - } else { - c = (refa == s->s.h.varcompref[1] && - refl != s->s.h.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->s.h.varcompref[1]); - } else { - c = 3 * (s->above_ref_ctx[col] != s->s.h.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->s.h.varcompref[1]); - } else { - c = 3 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); - } - } else { - c = 2; - } - bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]); - b->ref[var_idx] = s->s.h.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->s.h.fixcompref || !s->left_ref_ctx[row7] || - !s->above_ref_ctx[col]); - } else { - c = (3 * !s->above_ref_ctx[col]) + - (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); - } - } else if (s->above_comp_ctx[col]) { - c = (3 * !s->left_ref_ctx[row7]) + - (!s->s.h.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->s.h.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->s.h.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->s.h.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->s.h.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->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else { - c = 2; - } - } else if (!s->left_ref_ctx[row7]) { - c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->above_ref_ctx[col] == 1); - } else { - c = 3 * (s->left_ref_ctx[row7] == 1) + - (s->s.h.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->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else { - c = 3 * (s->above_ref_ctx[col] == 1) + - (s->s.h.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->s.h.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->s.h.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->s.h.segmentation.enabled && s->s.h.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->s.h.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->s.h.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->s.h.signbias[s->s.h.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->s.h.keyframe && !s->s.h.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->s.h.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->s.h.keyframe && !s->s.h.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->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->s.h.segmentation.feat[b->seg_id].qmul; - int tx = 4 * s->s.h.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->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->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; - int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0], *dst_r = s->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->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->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->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->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->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_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 * (1 << !s->ss_h), my = mv->y * (1 << !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 -#undef mc_chroma_dir -#undef FN -#undef BYTES_PER_PIXEL -#undef SCALED - -static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, - 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 *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) -{ - if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && - s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame, - y, x, in_mv, bw, bh, w, h, bytesperpixel); - } else { -#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) * 8, (s->cols * 8 - x + px + 3) * 8); - mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); - // 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, - 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 *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) -{ - if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && - s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_chroma_unscaled(s, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, - ref_v, src_stride_v, ref_frame, - y, x, in_mv, bw, bh, w, h, bytesperpixel); - } else { - 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) * 16, (s->cols * 4 - x + px + 3) * 16); - 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) * 8, (s->cols * 8 - x + px + 3) * 8); - mx = scale_mv(mv.x * 2, 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) * 16, (s->rows * 4 - y + py + 3) * 16); - 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) * 8, (s->rows * 8 - y + py + 3) * 8); - my = scale_mv(mv.y * 2, 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, s->dsp.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, s->dsp.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 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->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.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->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 * bytesperpixel > f->linesize[0] || - (row + h4) > s->rows; - emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > 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 * bytesperpixel, f->linesize[0], - s->tmp_y + o * bytesperpixel, 128, h, 0, 0); - o += bw; - } - } - } - 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 * bytesperpixel, f->linesize[1], - s->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); - s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o * bytesperpixel, f->linesize[2], - s->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); - o += bw; - } - } - } - - // pick filter level and find edges to apply filter to - if (s->s.h.filter.level && - (lvl = s->s.h.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_lut.lim_lut[lvl]) { - int sharp = s->s.h.filter.sharpness; - int limit = lvl; - - if (sharp > 0) { - limit >>= (sharp + 3) >> 2; - limit = FFMIN(limit, 9 - sharp); - } - limit = FFMAX(limit, 1); - - s->filter_lut.lim_lut[lvl] = limit; - s->filter_lut.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, +static void decode_sb(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - VP9Context *s = ctx->priv_data; + const VP9Context *s = td->s; 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->s.h.keyframe || s->s.h.intraonly ? vp9_default_kf_partition_probs[bl][c] : + (((td->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); + const uint8_t *p = s->s.h.keyframe || s->s.h.intraonly ? ff_vp9_default_kf_partition_probs[bl][c] : s->prob.p.partition[bl][c]; enum BlockPartition bp; ptrdiff_t hbs = 4 >> bl; @@ -3398,75 +1054,75 @@ static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *l 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); + bp = vp8_rac_get_tree(td->c, ff_vp9_partition_tree, p); + ff_vp9_decode_block(td, 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); + bp = vp8_rac_get_tree(td->c, ff_vp9_partition_tree, p); switch (bp) { case PARTITION_NONE: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_H: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, 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); + ff_vp9_decode_block(td, row + hbs, col, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_V: - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, 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); + ff_vp9_decode_block(td, 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, + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, 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, + decode_sb(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, 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])) { + } else if (vp56_rac_get_prob_branchy(td->c, p[1])) { bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(ctx, row, col + hbs, lflvl, + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, 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); + ff_vp9_decode_block(td, 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])) { + if (vp56_rac_get_prob_branchy(td->c, p[2])) { bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, 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); + decode_sb(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } else { bp = PARTITION_V; - decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } } else { bp = PARTITION_SPLIT; - decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); } - s->counts.partition[bl][c][bp]++; + td->counts.partition[bl][c][bp]++; } -static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl, +static void decode_sb_mem(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; + const VP9Context *s = td->s; + VP9Block *b = td->b; ptrdiff_t hbs = 4 >> bl; AVFrame *f = s->s.frames[CUR_FRAME].tf.f; ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; @@ -3474,221 +1130,43 @@ static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filte 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); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (td->b->bl == bl) { + ff_vp9_decode_block(td, 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); + ff_vp9_decode_block(td, 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); + ff_vp9_decode_block(td, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); } } else { - decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, 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, + decode_sb_mem(td, 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, + decode_sb_mem(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, 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); + decode_sb_mem(td, 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); + decode_sb_mem(td, 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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L] << 8; - I |= s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (hm23 & x) { - L = l[8 << ss_v]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L] << 8; - I |= s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; - - if (vm3 & (x << (1 + ss_h))) { - L = l[1 + ss_h]; - H |= (L >> 4) << 8; - E |= s->filter_lut.mblim_lut[L] << 8; - I |= s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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->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; @@ -3697,300 +1175,302 @@ static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n) *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) +static void free_buffers(VP9Context *s) { - 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); + int i; - // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8 - *p = p1 + (((p2 - p1) * update_factor + 128) >> 8); + av_freep(&s->intra_pred_data[0]); + for (i = 0; i < s->active_tile_cols; i++) { + av_freep(&s->td[i].b_base); + av_freep(&s->td[i].block_base); + } } -static void adapt_probs(VP9Context *s) +static av_cold int vp9_decode_free(AVCodecContext *avctx) { - int i, j, k, l, m; - prob_context *p = &s->prob_ctx[s->s.h.framectxid].p; - int uf = (s->s.h.keyframe || s->s.h.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->s.h.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); - } + VP9Context *s = avctx->priv_data; + int i; - if (s->s.h.keyframe || s->s.h.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; + for (i = 0; i < 3; i++) { + if (s->s.frames[i].tf.f->buf[0]) + vp9_frame_unref(avctx, &s->s.frames[i]); + av_frame_free(&s->s.frames[i].tf.f); + } + for (i = 0; i < 8; i++) { + if (s->s.refs[i].f->buf[0]) + ff_thread_release_buffer(avctx, &s->s.refs[i]); + av_frame_free(&s->s.refs[i].f); + if (s->next_refs[i].f->buf[0]) + ff_thread_release_buffer(avctx, &s->next_refs[i]); + av_frame_free(&s->next_refs[i].f); } - // 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); + free_buffers(s); + vp9_free_entries(avctx); + av_freep(&s->td); + return 0; +} - // 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); +static int decode_tiles(AVCodecContext *avctx, + const uint8_t *data, int size) +{ + VP9Context *s = avctx->priv_data; + VP9TileData *td = &s->td[0]; + int row, col, tile_row, tile_col, ret; + int bytesperpixel; + int tile_row_start, tile_row_end, tile_col_start, tile_col_end; + AVFrame *f; + ptrdiff_t yoff, uvoff, ls_y, ls_uv; - // comppred flag - if (s->s.h.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); - } + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; + bytesperpixel = s->bytesperpixel; - // reference frames - if (s->s.h.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); - } + yoff = uvoff = 0; + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { + set_tile_offset(&tile_row_start, &tile_row_end, + tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); - if (s->s.h.comppredmode != PRED_COMPREF) { - for (i = 0; i < 5; i++) { - uint8_t *pp = p->single_ref[i]; - unsigned (*c)[2] = s->counts.single_ref[i]; + for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { + int64_t tile_size; - adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); - adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); - } - } + if (tile_col == s->s.h.tiling.tile_cols - 1 && + tile_row == s->s.h.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->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return AVERROR_INVALIDDATA; + } + ret = ff_vp56_init_range_decoder(&td->c_b[tile_col], data, tile_size); + if (ret < 0) + return ret; + if (vp56_rac_get_prob_branchy(&td->c_b[tile_col], 128)) { // marker bit + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return AVERROR_INVALIDDATA; + } + data += tile_size; + size -= tile_size; + } - // 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]; + for (row = tile_row_start; row < tile_row_end; + row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { + VP9Filter *lflvl_ptr = s->lflvl; + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; - 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); - } + for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { + set_tile_offset(&tile_col_start, &tile_col_end, + tile_col, s->s.h.tiling.log2_tile_cols, s->sb_cols); + td->tile_col_start = tile_col_start; + if (s->pass != 2) { + memset(td->left_partition_ctx, 0, 8); + memset(td->left_skip_ctx, 0, 8); + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(td->left_mode_ctx, DC_PRED, 16); + } else { + memset(td->left_mode_ctx, NEARESTMV, 8); + } + memset(td->left_y_nnz_ctx, 0, 16); + memset(td->left_uv_nnz_ctx, 0, 32); + memset(td->left_segpred_ctx, 0, 8); - // tx size - if (s->s.h.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); - } - } + td->c = &td->c_b[tile_col]; + } - // interpolation filter - if (s->s.h.filtermode == FILTER_SWITCHABLE) { - for (i = 0; i < 4; i++) { - uint8_t *pp = p->filter[i]; - unsigned *c = s->counts.filter[i]; + for (col = tile_col_start; + col < 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)); + } - adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128); - adapt_prob(&pp[1], c[1], c[2], 20, 128); - } - } + if (s->pass == 2) { + decode_sb_mem(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } else { + decode_sb(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } + } + } - // inter modes - for (i = 0; i < 7; i++) { - uint8_t *pp = p->mv_mode[i]; - unsigned *c = s->counts.mv_mode[i]; + 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->s.h.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++) { + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, row, col, + yoff2, uvoff2); + } + } - 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); + // 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->s.frames[CUR_FRAME].tf, row >> 3, 0); + } } + return 0; +} - // mv joints - { - uint8_t *pp = p->mv_joint; - unsigned *c = s->counts.mv_joint; +#if HAVE_THREADS +static av_always_inline +int decode_tiles_mt(AVCodecContext *avctx, void *tdata, int jobnr, + int threadnr) +{ + VP9Context *s = avctx->priv_data; + VP9TileData *td = &s->td[jobnr]; + ptrdiff_t uvoff, yoff, ls_y, ls_uv; + int bytesperpixel = s->bytesperpixel, row, col, tile_row; + unsigned tile_cols_len; + int tile_row_start, tile_row_end, tile_col_start, tile_col_end; + VP9Filter *lflvl_ptr_base; + AVFrame *f; - 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); - } + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; - // 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); + set_tile_offset(&tile_col_start, &tile_col_end, + jobnr, s->s.h.tiling.log2_tile_cols, s->sb_cols); + td->tile_col_start = tile_col_start; + uvoff = (64 * bytesperpixel >> s->ss_h)*(tile_col_start >> 3); + yoff = (64 * bytesperpixel)*(tile_col_start >> 3); + lflvl_ptr_base = s->lflvl+(tile_col_start >> 3); + + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { + set_tile_offset(&tile_row_start, &tile_row_end, + tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); + + td->c = &td->c_b[tile_row]; + for (row = tile_row_start; row < tile_row_end; + row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; + VP9Filter *lflvl_ptr = lflvl_ptr_base+s->sb_cols*(row >> 3); + + memset(td->left_partition_ctx, 0, 8); + memset(td->left_skip_ctx, 0, 8); + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(td->left_mode_ctx, DC_PRED, 16); + } else { + memset(td->left_mode_ctx, NEARESTMV, 8); + } + memset(td->left_y_nnz_ctx, 0, 16); + memset(td->left_uv_nnz_ctx, 0, 32); + memset(td->left_segpred_ctx, 0, 8); - if (s->s.h.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); - } - } + for (col = tile_col_start; + col < 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) + memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); + decode_sb(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } - // 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); - } + // backup pre-loopfilter reconstruction data for intra + // prediction of next row of sb64s + tile_cols_len = tile_col_end - tile_col_start; + if (row + 8 < s->rows) { + memcpy(s->intra_pred_data[0] + (tile_col_start * 8 * bytesperpixel), + f->data[0] + yoff + 63 * ls_y, + 8 * tile_cols_len * bytesperpixel); + memcpy(s->intra_pred_data[1] + (tile_col_start * 8 * bytesperpixel >> s->ss_h), + f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * tile_cols_len * bytesperpixel >> s->ss_h); + memcpy(s->intra_pred_data[2] + (tile_col_start * 8 * bytesperpixel >> s->ss_h), + f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * tile_cols_len * bytesperpixel >> s->ss_h); + } - // 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); + vp9_report_tile_progress(s, row >> 3, 1); + } } + return 0; } -static void free_buffers(VP9Context *s) +static av_always_inline +int loopfilter_proc(AVCodecContext *avctx) { - av_freep(&s->intra_pred_data[0]); - av_freep(&s->b_base); - av_freep(&s->block_base); -} + VP9Context *s = avctx->priv_data; + ptrdiff_t uvoff, yoff, ls_y, ls_uv; + VP9Filter *lflvl_ptr; + int bytesperpixel = s->bytesperpixel, col, i; + AVFrame *f; -static av_cold int vp9_decode_free(AVCodecContext *ctx) -{ - VP9Context *s = ctx->priv_data; - int i; + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; - for (i = 0; i < 3; i++) { - if (s->s.frames[i].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[i]); - av_frame_free(&s->s.frames[i].tf.f); - } - for (i = 0; i < 8; i++) { - if (s->s.refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->s.refs[i]); - av_frame_free(&s->s.refs[i].f); - if (s->next_refs[i].f->buf[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; + for (i = 0; i < s->sb_rows; i++) { + vp9_await_tile_progress(s, i, s->s.h.tiling.tile_cols); + if (s->s.h.filter.level) { + yoff = (ls_y * 64)*i; + uvoff = (ls_uv * 64 >> s->ss_v)*i; + lflvl_ptr = s->lflvl+s->sb_cols*i; + for (col = 0; col < s->cols; + col += 8, yoff += 64 * bytesperpixel, + uvoff += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, i << 3, col, + yoff, uvoff); + } + } + } return 0; } +#endif - -static int vp9_decode_frame(AVCodecContext *ctx, void *frame, +static int vp9_decode_frame(AVCodecContext *avctx, 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; + VP9Context *s = avctx->priv_data; + int ret, i, j, ref; int retain_segmap_ref = s->s.frames[REF_FRAME_SEGMAP].segmentation_map && (!s->s.h.segmentation.enabled || !s->s.h.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 ((ret = decode_frame_header(avctx, data, size, &ref)) < 0) { + return ret; + } else if (ret == 0) { if (!s->s.refs[ref].f->buf[0]) { - av_log(ctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); + av_log(avctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); return AVERROR_INVALIDDATA; } - if ((res = av_frame_ref(frame, s->s.refs[ref].f)) < 0) - return res; + if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0) + return ret; ((AVFrame *)frame)->pts = pkt->pts; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS @@ -4000,73 +1480,70 @@ FF_ENABLE_DEPRECATION_WARNINGS ((AVFrame *)frame)->pkt_dts = pkt->dts; for (i = 0; i < 8; i++) { if (s->next_refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->next_refs[i]); + ff_thread_release_buffer(avctx, &s->next_refs[i]); if (s->s.refs[i].f->buf[0] && - (res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0) - return res; + (ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0) + return ret; } *got_frame = 1; return pkt->size; } - data += res; - size -= res; + data += ret; + size -= ret; if (!retain_segmap_ref || s->s.h.keyframe || s->s.h.intraonly) { if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]); if (!s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_ref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) - return res; + (ret = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0) + return ret; } if (s->s.frames[REF_FRAME_MVPAIR].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_MVPAIR]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_MVPAIR]); if (!s->s.h.intraonly && !s->s.h.keyframe && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->buf[0] && - (res = vp9_ref_frame(ctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) - return res; + (ret = vp9_frame_ref(avctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0) + return ret; if (s->s.frames[CUR_FRAME].tf.f->buf[0]) - vp9_unref_frame(ctx, &s->s.frames[CUR_FRAME]); - if ((res = vp9_alloc_frame(ctx, &s->s.frames[CUR_FRAME])) < 0) - return res; + vp9_frame_unref(avctx, &s->s.frames[CUR_FRAME]); + if ((ret = vp9_frame_alloc(avctx, &s->s.frames[CUR_FRAME])) < 0) + return ret; f = s->s.frames[CUR_FRAME].tf.f; f->key_frame = s->s.h.keyframe; f->pict_type = (s->s.h.keyframe || s->s.h.intraonly) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - ls_y = f->linesize[0]; - ls_uv =f->linesize[1]; if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0] && (s->s.frames[REF_FRAME_MVPAIR].tf.f->width != s->s.frames[CUR_FRAME].tf.f->width || s->s.frames[REF_FRAME_MVPAIR].tf.f->height != s->s.frames[CUR_FRAME].tf.f->height)) { - vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP]); + vp9_frame_unref(avctx, &s->s.frames[REF_FRAME_SEGMAP]); } // ref frame setup for (i = 0; i < 8; i++) { if (s->next_refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->next_refs[i]); + ff_thread_release_buffer(avctx, &s->next_refs[i]); if (s->s.h.refreshrefmask & (1 << i)) { - res = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf); + ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf); } else if (s->s.refs[i].f->buf[0]) { - res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i]); - } - if (res < 0) - return res; - } - - if (ctx->hwaccel) { - res = ctx->hwaccel->start_frame(ctx, NULL, 0); - if (res < 0) - return res; - res = ctx->hwaccel->decode_slice(ctx, pkt->data, pkt->size); - if (res < 0) - return res; - res = ctx->hwaccel->end_frame(ctx); - if (res < 0) - return res; + ret = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i]); + } + if (ret < 0) + return ret; + } + + if (avctx->hwaccel) { + ret = avctx->hwaccel->start_frame(avctx, NULL, 0); + if (ret < 0) + return ret; + ret = avctx->hwaccel->decode_slice(avctx, pkt->data, pkt->size); + if (ret < 0) + return ret; + ret = avctx->hwaccel->end_frame(avctx); + if (ret < 0) + return ret; goto finish; } // 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->s.h.keyframe || s->s.h.intraonly) { @@ -4079,11 +1556,11 @@ FF_ENABLE_DEPRECATION_WARNINGS 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->s.frames[CUR_FRAME].uses_2pass = - ctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode; - if ((res = update_block_buffers(ctx)) < 0) { - av_log(ctx, AV_LOG_ERROR, + avctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode; + if ((ret = update_block_buffers(avctx)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate block buffers\n"); - return res; + return ret; } if (s->s.h.refreshctx && s->s.h.parallelmode) { int j, k, l, m; @@ -4099,25 +1576,36 @@ FF_ENABLE_DEPRECATION_WARNINGS break; } s->prob_ctx[s->s.h.framectxid].p = s->prob.p; - ff_thread_finish_setup(ctx); + ff_thread_finish_setup(avctx); } else if (!s->s.h.refreshctx) { - ff_thread_finish_setup(ctx); + ff_thread_finish_setup(avctx); + } + +#if HAVE_THREADS + if (avctx->active_thread_type & FF_THREAD_SLICE) { + for (i = 0; i < s->sb_rows; i++) + atomic_store(&s->entries[i], 0); } +#endif 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->s.h.tiling.tile_rows; tile_row++) { - set_tile_offset(&s->tile_row_start, &s->tile_row_end, - tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); - if (s->pass != 2) { + for (i = 0; i < s->active_tile_cols; i++) { + s->td[i].b = s->td[i].b_base; + s->td[i].block = s->td[i].block_base; + s->td[i].uvblock[0] = s->td[i].uvblock_base[0]; + s->td[i].uvblock[1] = s->td[i].uvblock_base[1]; + s->td[i].eob = s->td[i].eob_base; + s->td[i].uveob[0] = s->td[i].uveob_base[0]; + s->td[i].uveob[1] = s->td[i].uveob_base[1]; + } + +#if HAVE_THREADS + if (avctx->active_thread_type == FF_THREAD_SLICE) { + int tile_row, tile_col; + + av_assert1(!s->pass); + + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { int64_t tile_size; @@ -4129,107 +1617,38 @@ FF_ENABLE_DEPRECATION_WARNINGS data += 4; size -= 4; } - if (tile_size > size) { - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + if (tile_size > size) 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->s.frames[CUR_FRAME].tf, INT_MAX, 0); + ret = ff_vp56_init_range_decoder(&s->td[tile_col].c_b[tile_row], data, tile_size); + if (ret < 0) + return ret; + if (vp56_rac_get_prob_branchy(&s->td[tile_col].c_b[tile_row], 128)) // marker bit return AVERROR_INVALIDDATA; - } data += tile_size; size -= tile_size; } } - for (row = s->tile_row_start; row < s->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->s.h.tiling.tile_cols; tile_col++) { - set_tile_offset(&s->tile_col_start, &s->tile_col_end, - tile_col, s->s.h.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->s.h.keyframe || s->s.h.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->tile_col_start; - col < s->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->s.h.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->s.frames[CUR_FRAME].tf, row >> 3, 0); + ff_slice_thread_execute_with_mainfunc(avctx, decode_tiles_mt, loopfilter_proc, s->td, NULL, s->s.h.tiling.tile_cols); + } else +#endif + { + ret = decode_tiles(avctx, data, size); + if (ret < 0) { + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return ret; } } + // Sum all counts fields into td[0].counts for tile threading + if (avctx->active_thread_type == FF_THREAD_SLICE) + for (i = 1; i < s->s.h.tiling.tile_cols; i++) + for (j = 0; j < sizeof(s->td[i].counts) / sizeof(unsigned); j++) + ((unsigned *)&s->td[0].counts)[j] += ((unsigned *)&s->td[i].counts)[j]; + if (s->pass < 2 && s->s.h.refreshctx && !s->s.h.parallelmode) { - adapt_probs(s); - ff_thread_finish_setup(ctx); + ff_vp9_adapt_probs(s); + ff_thread_finish_setup(avctx); } } while (s->pass++ == 1); ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); @@ -4238,42 +1657,42 @@ finish: // ref frame setup for (i = 0; i < 8; i++) { if (s->s.refs[i].f->buf[0]) - ff_thread_release_buffer(ctx, &s->s.refs[i]); + ff_thread_release_buffer(avctx, &s->s.refs[i]); if (s->next_refs[i].f->buf[0] && - (res = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0) - return res; + (ret = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0) + return ret; } if (!s->s.h.invisible) { - if ((res = av_frame_ref(frame, s->s.frames[CUR_FRAME].tf.f)) < 0) - return res; + if ((ret = av_frame_ref(frame, s->s.frames[CUR_FRAME].tf.f)) < 0) + return ret; *got_frame = 1; } return pkt->size; } -static void vp9_decode_flush(AVCodecContext *ctx) +static void vp9_decode_flush(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) - vp9_unref_frame(ctx, &s->s.frames[i]); + vp9_frame_unref(avctx, &s->s.frames[i]); for (i = 0; i < 8; i++) - ff_thread_release_buffer(ctx, &s->s.refs[i]); + ff_thread_release_buffer(avctx, &s->s.refs[i]); } -static int init_frames(AVCodecContext *ctx) +static int init_frames(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) { s->s.frames[i].tf.f = av_frame_alloc(); if (!s->s.frames[i].tf.f) { - vp9_decode_free(ctx); - av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); + vp9_decode_free(avctx); + av_log(avctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); return AVERROR(ENOMEM); } } @@ -4281,8 +1700,8 @@ static int init_frames(AVCodecContext *ctx) s->s.refs[i].f = av_frame_alloc(); s->next_refs[i].f = av_frame_alloc(); if (!s->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); + vp9_decode_free(avctx); + av_log(avctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i); return AVERROR(ENOMEM); } } @@ -4290,15 +1709,15 @@ static int init_frames(AVCodecContext *ctx) return 0; } -static av_cold int vp9_decode_init(AVCodecContext *ctx) +static av_cold int vp9_decode_init(AVCodecContext *avctx) { - VP9Context *s = ctx->priv_data; + VP9Context *s = avctx->priv_data; - ctx->internal->allocate_progress = 1; + avctx->internal->allocate_progress = 1; s->last_bpp = 0; s->s.h.filter.sharpness = -1; - return init_frames(ctx); + return init_frames(avctx); } #if HAVE_THREADS @@ -4309,23 +1728,23 @@ static av_cold int vp9_decode_init_thread_copy(AVCodecContext *avctx) static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { - int i, res; + int i, ret; VP9Context *s = dst->priv_data, *ssrc = src->priv_data; for (i = 0; i < 3; i++) { if (s->s.frames[i].tf.f->buf[0]) - vp9_unref_frame(dst, &s->s.frames[i]); + vp9_frame_unref(dst, &s->s.frames[i]); if (ssrc->s.frames[i].tf.f->buf[0]) { - if ((res = vp9_ref_frame(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0) - return res; + if ((ret = vp9_frame_ref(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0) + return ret; } } for (i = 0; i < 8; i++) { if (s->s.refs[i].f->buf[0]) ff_thread_release_buffer(dst, &s->s.refs[i]); if (ssrc->next_refs[i].f->buf[0]) { - if ((res = ff_thread_ref_frame(&s->s.refs[i], &ssrc->next_refs[i])) < 0) - return res; + if ((ret = ff_thread_ref_frame(&s->s.refs[i], &ssrc->next_refs[i])) < 0) + return ret; } } @@ -4341,7 +1760,7 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo s->gf_fmt = ssrc->gf_fmt; s->w = ssrc->w; s->h = ssrc->h; - s->bpp = ssrc->bpp; + s->s.h.bpp = ssrc->s.h.bpp; s->bpp_index = ssrc->bpp_index; s->pix_fmt = ssrc->pix_fmt; memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx)); @@ -4362,7 +1781,8 @@ AVCodec ff_vp9_decoder = { .init = vp9_decode_init, .close = vp9_decode_free, .decode = vp9_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, + .caps_internal = FF_CODEC_CAP_SLICE_THREAD_HAS_MF, .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), diff --git a/media/ffvpx/libavcodec/vp9.h b/media/ffvpx/libavcodec/vp9.h index df5bd4d85..c8d07ad98 100644 --- a/media/ffvpx/libavcodec/vp9.h +++ b/media/ffvpx/libavcodec/vp9.h @@ -24,42 +24,6 @@ #ifndef AVCODEC_VP9_H #define AVCODEC_VP9_H -#include <stdint.h> - -#include "thread.h" -#include "vp56.h" - -enum BlockLevel { - BL_64X64, - BL_32X32, - BL_16X16, - BL_8X8, -}; - -enum BlockPartition { - PARTITION_NONE, // [ ] <-. - PARTITION_H, // [-] | - PARTITION_V, // [|] | - PARTITION_SPLIT, // [+] --' -}; - -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, -}; - enum TxfmMode { TX_4X4, TX_8X8, @@ -97,115 +61,13 @@ enum IntraPredMode { N_INTRA_PRED_MODES }; -enum InterPredMode { - NEARESTMV = 10, - NEARMV = 11, - ZEROMV = 12, - NEWMV = 13, -}; - enum FilterMode { FILTER_8TAP_SMOOTH, FILTER_8TAP_REGULAR, FILTER_8TAP_SHARP, FILTER_BILINEAR, - FILTER_SWITCHABLE, + N_FILTERS, + FILTER_SWITCHABLE = N_FILTERS, }; -enum CompPredMode { - PRED_SINGLEREF, - PRED_COMPREF, - PRED_SWITCHABLE, -}; - -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; - - AVBufferRef *hwaccel_priv_buf; - void *hwaccel_picture_private; -} VP9Frame; - -typedef struct VP9BitstreamHeader { - // bitstream header - uint8_t profile; - uint8_t keyframe; - uint8_t invisible; - uint8_t errorres; - uint8_t intraonly; - uint8_t resetctx; - uint8_t refreshrefmask; - uint8_t highprecisionmvs; - enum FilterMode filtermode; - uint8_t allowcompinter; - uint8_t refreshctx; - uint8_t parallelmode; - uint8_t framectxid; - uint8_t use_last_frame_mvs; - uint8_t refidx[3]; - uint8_t signbias[3]; - uint8_t fixcompref; - uint8_t varcompref[2]; - struct { - uint8_t level; - int8_t sharpness; - } filter; - struct { - uint8_t enabled; - uint8_t updated; - 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 prob[7]; - uint8_t pred_prob[3]; - 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; - enum TxfmMode txfmmode; - enum CompPredMode comppredmode; - struct { - unsigned log2_tile_cols, log2_tile_rows; - unsigned tile_cols, tile_rows; - } tiling; - - int uncompressed_header_size; - int compressed_header_size; -} VP9BitstreamHeader; - -typedef struct VP9SharedContext { - VP9BitstreamHeader h; - - ThreadFrame refs[8]; -#define CUR_FRAME 0 -#define REF_FRAME_MVPAIR 1 -#define REF_FRAME_SEGMAP 2 - VP9Frame frames[3]; -} VP9SharedContext; - #endif /* AVCODEC_VP9_H */ diff --git a/media/ffvpx/libavcodec/vp9_mc_template.c b/media/ffvpx/libavcodec/vp9_mc_template.c index 38d9a6da9..31e692f36 100644 --- a/media/ffvpx/libavcodec/vp9_mc_template.c +++ b/media/ffvpx/libavcodec/vp9_mc_template.c @@ -27,19 +27,19 @@ (VP56mv) { .x = ROUNDED_DIV(a.x + b.x + c.x + d.x, 4), \ .y = ROUNDED_DIV(a.y + b.y + c.y + d.y, 4) } -static void FN(inter_pred)(AVCodecContext *ctx) +static void FN(inter_pred)(VP9TileData *td) { static const uint8_t bwlog_tab[2][N_BS_SIZES] = { { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, }; - VP9Context *s = ctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; ThreadFrame *tref1 = &s->s.refs[s->s.h.refidx[b->ref[0]]], *tref2; AVFrame *ref1 = tref1->f, *ref2; int w1 = ref1->width, h1 = ref1->height, w2, h2; - ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride; + ptrdiff_t ls_y = td->y_stride, ls_uv = td->uv_stride; int bytesperpixel = BYTES_PER_PIXEL; if (b->comp) { @@ -55,26 +55,26 @@ static void FN(inter_pred)(AVCodecContext *ctx) #if SCALED == 0 if (b->bs == BS_8x4) { - mc_luma_dir(s, mc[3][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[3][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0],,,,, 8, 4, w1, h1, 0); - mc_luma_dir(s, mc[3][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[3][b->filter][0], + td->dst[0] + 4 * ls_y, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0],,,,, 8, 4, w1, h1, 0); w1 = (w1 + s->ss_h) >> s->ss_h; if (s->ss_v) { h1 = (h1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << (3 - s->ss_h), &uvmv,,,,, 8 >> s->ss_h, 4, w1, h1, 0); } else { - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << (3 - s->ss_h), @@ -87,8 +87,8 @@ static void FN(inter_pred)(AVCodecContext *ctx) } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); } - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << (3 - s->ss_h), @@ -96,26 +96,26 @@ static void FN(inter_pred)(AVCodecContext *ctx) } if (b->comp) { - mc_luma_dir(s, mc[3][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[3][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1],,,,, 8, 4, w2, h2, 1); - mc_luma_dir(s, mc[3][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[3][b->filter][1], + td->dst[0] + 4 * ls_y, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1],,,,, 8, 4, w2, h2, 1); w2 = (w2 + s->ss_h) >> s->ss_h; if (s->ss_v) { h2 = (h2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << (3 - s->ss_h), &uvmv,,,,, 8 >> s->ss_h, 4, w2, h2, 1); } else { - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << (3 - s->ss_h), @@ -128,8 +128,8 @@ static void FN(inter_pred)(AVCodecContext *ctx) } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); } - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << (3 - s->ss_h), @@ -137,32 +137,32 @@ static void FN(inter_pred)(AVCodecContext *ctx) } } } else if (b->bs == BS_4x8) { - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0],,,,, 4, 8, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0],,,,, 4, 8, w1, h1, 0); h1 = (h1 + s->ss_v) >> s->ss_v; if (s->ss_h) { w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << 2, &uvmv,,,,, 4, 8 >> s->ss_v, w1, h1, 0); } else { - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << 3, &b->mv[0][0],,,,, 4, 8 >> s->ss_v, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), (col << 3) + 4, @@ -170,32 +170,32 @@ static void FN(inter_pred)(AVCodecContext *ctx) } if (b->comp) { - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1],,,,, 4, 8, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1],,,,, 4, 8, w2, h2, 1); h2 = (h2 + s->ss_v) >> s->ss_v; if (s->ss_h) { w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << 2, &uvmv,,,,, 4, 8 >> s->ss_v, w2, h2, 1); } else { - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << 3, &b->mv[0][1],,,,, 4, 8 >> s->ss_v, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), (col << 3) + 4, @@ -205,25 +205,27 @@ static void FN(inter_pred)(AVCodecContext *ctx) } else #endif { +#if SCALED == 0 av_assert2(b->bs == BS_4x4); +#endif // FIXME if two horizontally adjacent blocks have the same MV, // do a w8 instead of a w4 call - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], + td->dst[0] + 4 * ls_y, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], - s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], + td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, 8, 8, 4, 4, w1, h1, 0); @@ -233,24 +235,24 @@ static void FN(inter_pred)(AVCodecContext *ctx) w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx4(b->mv[0][0], b->mv[1][0], b->mv[2][0], b->mv[3][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 2, &uvmv, 0, 0, 4, 4, 4, 4, w1, h1, 0); } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 3, &uvmv, 0, 0, 8, 4, 4, 4, w1, h1, 0); uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[3][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, (col << 3) + 4, @@ -260,8 +262,8 @@ static void FN(inter_pred)(AVCodecContext *ctx) if (s->ss_h) { w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << 2, @@ -270,35 +272,35 @@ static void FN(inter_pred)(AVCodecContext *ctx) // bottom block // https://code.google.com/p/webm/issues/detail?id=993 uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[2][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << 2, &uvmv, 0, 4, 4, 8, 4, 4, w1, h1, 0); } else { - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv + 4 * bytesperpixel, - s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, + td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, (col << 3) + 4, @@ -307,18 +309,18 @@ static void FN(inter_pred)(AVCodecContext *ctx) } if (b->comp) { - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], + td->dst[0] + 4 * ls_y, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], - s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], + td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, 8, 8, 4, 4, w2, h2, 1); if (s->ss_v) { @@ -327,24 +329,24 @@ static void FN(inter_pred)(AVCodecContext *ctx) w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx4(b->mv[0][1], b->mv[1][1], b->mv[2][1], b->mv[3][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 2, &uvmv, 0, 0, 4, 4, 4, 4, w2, h2, 1); } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 3, &uvmv, 0, 0, 8, 4, 4, 4, w2, h2, 1); uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[3][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, (col << 3) + 4, @@ -354,8 +356,8 @@ static void FN(inter_pred)(AVCodecContext *ctx) if (s->ss_h) { w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << 2, @@ -364,35 +366,35 @@ static void FN(inter_pred)(AVCodecContext *ctx) // bottom block // https://code.google.com/p/webm/issues/detail?id=993 uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[2][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << 2, &uvmv, 0, 4, 4, 8, 4, 4, w2, h2, 1); } else { - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv + 4 * bytesperpixel, - s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, + td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, (col << 3) + 4, @@ -403,29 +405,31 @@ static void FN(inter_pred)(AVCodecContext *ctx) } } else { int bwl = bwlog_tab[0][b->bs]; - int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4; - int uvbw = bwh_tab[s->ss_h][b->bs][0] * 4, uvbh = bwh_tab[s->ss_v][b->bs][1] * 4; + int bw = ff_vp9_bwh_tab[0][b->bs][0] * 4; + int bh = ff_vp9_bwh_tab[0][b->bs][1] * 4; + int uvbw = ff_vp9_bwh_tab[s->ss_h][b->bs][0] * 4; + int uvbh = ff_vp9_bwh_tab[s->ss_v][b->bs][1] * 4; - mc_luma_dir(s, mc[bwl][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[bwl][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, bw, bh, bw, bh, w1, h1, 0); w1 = (w1 + s->ss_h) >> s->ss_h; h1 = (h1 + s->ss_v) >> s->ss_v; - mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << (3 - s->ss_h), &b->mv[0][0], 0, 0, uvbw, uvbh, uvbw, uvbh, w1, h1, 0); if (b->comp) { - mc_luma_dir(s, mc[bwl][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[bwl][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, bw, bh, bw, bh, w2, h2, 1); w2 = (w2 + s->ss_h) >> s->ss_h; h2 = (h2 + s->ss_v) >> s->ss_v; - mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << (3 - s->ss_h), diff --git a/media/ffvpx/libavcodec/vp9block.c b/media/ffvpx/libavcodec/vp9block.c new file mode 100644 index 000000000..1c3f7a722 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9block.c @@ -0,0 +1,1449 @@ +/* + * 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 "libavutil/avassert.h" + +#include "avcodec.h" +#include "internal.h" +#include "videodsp.h" +#include "vp56.h" +#include "vp9.h" +#include "vp9data.h" +#include "vp9dec.h" + +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(VP9TileData *td) +{ + 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 = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col, row7 = td->row7; + enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; + int bw4 = ff_vp9_bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); + int bh4 = ff_vp9_bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; + int have_a = row > 0, have_l = col > td->tile_col_start; + int vref, filter_id; + + if (!s->s.h.segmentation.enabled) { + b->seg_id = 0; + } else if (s->s.h.keyframe || s->s.h.intraonly) { + b->seg_id = !s->s.h.segmentation.update_map ? 0 : + vp8_rac_get_tree(td->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); + } else if (!s->s.h.segmentation.update_map || + (s->s.h.segmentation.temporal && + vp56_rac_get_prob_branchy(td->c, + s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] + + td->left_segpred_ctx[row7]]))) { + if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) { + int pred = 8, x; + uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map; + + if (!s->s.frames[REF_FRAME_SEGMAP].uses_2pass) + ff_thread_await_progress(&s->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(&td->left_segpred_ctx[row7], 1, h4); + } else { + b->seg_id = vp8_rac_get_tree(td->c, ff_vp9_segmentation_tree, + s->s.h.segmentation.prob); + + memset(&s->above_segpred_ctx[col], 0, w4); + memset(&td->left_segpred_ctx[row7], 0, h4); + } + if (s->s.h.segmentation.enabled && + (s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) { + setctx_2d(&s->s.frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col], + bw4, bh4, 8 * s->sb_cols, b->seg_id); + } + + b->skip = s->s.h.segmentation.enabled && + s->s.h.segmentation.feat[b->seg_id].skip_enabled; + if (!b->skip) { + int c = td->left_skip_ctx[row7] + s->above_skip_ctx[col]; + b->skip = vp56_rac_get_prob(td->c, s->prob.p.skip[c]); + td->counts.skip[c][b->skip]++; + } + + if (s->s.h.keyframe || s->s.h.intraonly) { + b->intra = 1; + } else if (s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { + b->intra = !s->s.h.segmentation.feat[b->seg_id].ref_val; + } else { + int c, bit; + + if (have_a && have_l) { + c = s->above_intra_ctx[col] + td->left_intra_ctx[row7]; + c += (c == 2); + } else { + c = have_a ? 2 * s->above_intra_ctx[col] : + have_l ? 2 * td->left_intra_ctx[row7] : 0; + } + bit = vp56_rac_get_prob(td->c, s->prob.p.intra[c]); + td->counts.intra[c][bit]++; + b->intra = !bit; + } + + if ((b->intra || !b->skip) && s->s.h.txfmmode == TX_SWITCHABLE) { + int c; + if (have_a) { + if (have_l) { + c = (s->above_skip_ctx[col] ? max_tx : + s->above_txfm_ctx[col]) + + (td->left_skip_ctx[row7] ? max_tx : + td->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 = td->left_skip_ctx[row7] ? 1 : + (td->left_txfm_ctx[row7] * 2 > max_tx); + } else { + c = 1; + } + switch (max_tx) { + case TX_32X32: + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][0]); + if (b->tx) { + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][1]); + if (b->tx == 2) + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx32p[c][2]); + } + td->counts.tx32p[c][b->tx]++; + break; + case TX_16X16: + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx16p[c][0]); + if (b->tx) + b->tx += vp56_rac_get_prob(td->c, s->prob.p.tx16p[c][1]); + td->counts.tx16p[c][b->tx]++; + break; + case TX_8X8: + b->tx = vp56_rac_get_prob(td->c, s->prob.p.tx8p[c]); + td->counts.tx8p[c][b->tx]++; + break; + case TX_4X4: + b->tx = TX_4X4; + break; + } + } else { + b->tx = FFMIN(max_tx, s->s.h.txfmmode); + } + + if (s->s.h.keyframe || s->s.h.intraonly) { + uint8_t *a = &s->above_mode_ctx[col * 2]; + uint8_t *l = &td->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(td->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[0]][l[0]]); + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_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(td->c, ff_vp9_intramode_tree, + ff_vp9_default_kf_ymode_probs[a[0]][l[1]]); + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_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(td->c, ff_vp9_intramode_tree, + ff_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], ff_vp9_bwh_tab[0][b->bs][0]); + memset(l, b->mode[0], ff_vp9_bwh_tab[0][b->bs][1]); + } + b->uvmode = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + ff_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(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + td->counts.y_mode[0][b->mode[0]]++; + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + td->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(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + td->counts.y_mode[0][b->mode[2]]++; + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[0]); + td->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(td->c, ff_vp9_intramode_tree, + s->prob.p.y_mode[sz]); + b->mode[1] = + b->mode[2] = + b->mode[3] = b->mode[0]; + td->counts.y_mode[sz][b->mode[3]]++; + } + b->uvmode = vp8_rac_get_tree(td->c, ff_vp9_intramode_tree, + s->prob.p.uv_mode[b->mode[3]]); + td->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->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].ref_enabled) { + av_assert2(s->s.h.segmentation.feat[b->seg_id].ref_val != 0); + b->comp = 0; + b->ref[0] = s->s.h.segmentation.feat[b->seg_id].ref_val - 1; + } else { + // read comp_pred flag + if (s->s.h.comppredmode != PRED_SWITCHABLE) { + b->comp = s->s.h.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] && td->left_comp_ctx[row7]) { + c = 4; + } else if (s->above_comp_ctx[col]) { + c = 2 + (td->left_intra_ctx[row7] || + td->left_ref_ctx[row7] == s->s.h.fixcompref); + } else if (td->left_comp_ctx[row7]) { + c = 2 + (s->above_intra_ctx[col] || + s->above_ref_ctx[col] == s->s.h.fixcompref); + } else { + c = (!s->above_intra_ctx[col] && + s->above_ref_ctx[col] == s->s.h.fixcompref) ^ + (!td->left_intra_ctx[row7] && + td->left_ref_ctx[row & 7] == s->s.h.fixcompref); + } + } else { + c = s->above_comp_ctx[col] ? 3 : + (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref); + } + } else if (have_l) { + c = td->left_comp_ctx[row7] ? 3 : + (!td->left_intra_ctx[row7] && td->left_ref_ctx[row7] == s->s.h.fixcompref); + } else { + c = 1; + } + b->comp = vp56_rac_get_prob(td->c, s->prob.p.comp[c]); + td->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->s.h.signbias[s->s.h.fixcompref], var_idx = !fix_idx, c, bit; + + b->ref[fix_idx] = s->s.h.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 (td->left_intra_ctx[row7]) { + c = 2; + } else { + c = 1 + 2 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } + } else if (td->left_intra_ctx[row7]) { + c = 1 + 2 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); + } else { + int refl = td->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; + + if (refl == refa && refa == s->s.h.varcompref[1]) { + c = 0; + } else if (!td->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { + if ((refa == s->s.h.fixcompref && refl == s->s.h.varcompref[0]) || + (refl == s->s.h.fixcompref && refa == s->s.h.varcompref[0])) { + c = 4; + } else { + c = (refa == refl) ? 3 : 1; + } + } else if (!td->left_comp_ctx[row7]) { + if (refa == s->s.h.varcompref[1] && refl != s->s.h.varcompref[1]) { + c = 1; + } else { + c = (refl == s->s.h.varcompref[1] && + refa != s->s.h.varcompref[1]) ? 2 : 4; + } + } else if (!s->above_comp_ctx[col]) { + if (refl == s->s.h.varcompref[1] && refa != s->s.h.varcompref[1]) { + c = 1; + } else { + c = (refa == s->s.h.varcompref[1] && + refl != s->s.h.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->s.h.varcompref[1]); + } else { + c = 3 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); + } + } + } else if (have_l) { + if (td->left_intra_ctx[row7]) { + c = 2; + } else if (td->left_comp_ctx[row7]) { + c = 4 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } else { + c = 3 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(td->c, s->prob.p.comp_ref[c]); + b->ref[var_idx] = s->s.h.varcompref[bit]; + td->counts.comp_ref[c][bit]++; + } else /* single reference */ { + int bit, c; + + if (have_a && !s->above_intra_ctx[col]) { + if (have_l && !td->left_intra_ctx[row7]) { + if (td->left_comp_ctx[row7]) { + if (s->above_comp_ctx[col]) { + c = 1 + (!s->s.h.fixcompref || !td->left_ref_ctx[row7] || + !s->above_ref_ctx[col]); + } else { + c = (3 * !s->above_ref_ctx[col]) + + (!s->s.h.fixcompref || !td->left_ref_ctx[row7]); + } + } else if (s->above_comp_ctx[col]) { + c = (3 * !td->left_ref_ctx[row7]) + + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); + } else { + c = 2 * !td->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->s.h.fixcompref || !s->above_ref_ctx[col]); + } else { + c = 4 * (!s->above_ref_ctx[col]); + } + } else if (have_l && !td->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { + c = 2; + } else if (td->left_comp_ctx[row7]) { + c = 1 + (!s->s.h.fixcompref || !td->left_ref_ctx[row7]); + } else { + c = 4 * (!td->left_ref_ctx[row7]); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(td->c, s->prob.p.single_ref[c][0]); + td->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 (td->left_intra_ctx[row7]) { + if (s->above_intra_ctx[col]) { + c = 2; + } else if (s->above_comp_ctx[col]) { + c = 1 + 2 * (s->s.h.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 (td->left_intra_ctx[row7]) { + c = 2; + } else if (td->left_comp_ctx[row7]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + td->left_ref_ctx[row7] == 1); + } else if (!td->left_ref_ctx[row7]) { + c = 3; + } else { + c = 4 * (td->left_ref_ctx[row7] == 1); + } + } else if (s->above_comp_ctx[col]) { + if (td->left_comp_ctx[row7]) { + if (td->left_ref_ctx[row7] == s->above_ref_ctx[col]) { + c = 3 * (s->s.h.fixcompref == 1 || + td->left_ref_ctx[row7] == 1); + } else { + c = 2; + } + } else if (!td->left_ref_ctx[row7]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + s->above_ref_ctx[col] == 1); + } else { + c = 3 * (td->left_ref_ctx[row7] == 1) + + (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); + } + } else if (td->left_comp_ctx[row7]) { + if (!s->above_ref_ctx[col]) { + c = 1 + 2 * (s->s.h.fixcompref == 1 || + td->left_ref_ctx[row7] == 1); + } else { + c = 3 * (s->above_ref_ctx[col] == 1) + + (s->s.h.fixcompref == 1 || td->left_ref_ctx[row7] == 1); + } + } else if (!s->above_ref_ctx[col]) { + if (!td->left_ref_ctx[row7]) { + c = 3; + } else { + c = 4 * (td->left_ref_ctx[row7] == 1); + } + } else if (!td->left_ref_ctx[row7]) { + c = 4 * (s->above_ref_ctx[col] == 1); + } else { + c = 2 * (td->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->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); + } else { + c = 4 * (s->above_ref_ctx[col] == 1); + } + } + } else if (have_l) { + if (td->left_intra_ctx[row7] || + (!td->left_comp_ctx[row7] && !td->left_ref_ctx[row7])) { + c = 2; + } else if (td->left_comp_ctx[row7]) { + c = 3 * (s->s.h.fixcompref == 1 || td->left_ref_ctx[row7] == 1); + } else { + c = 4 * (td->left_ref_ctx[row7] == 1); + } + } else { + c = 2; + } + bit = vp56_rac_get_prob(td->c, s->prob.p.single_ref[c][1]); + td->counts.single_ref[c][1][bit]++; + b->ref[0] = 1 + bit; + } + } + } + + if (b->bs <= BS_8x8) { + if (s->s.h.segmentation.enabled && s->s.h.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]]] + [td->left_mode_ctx[row7 + off[b->bs]]]; + + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + b->mode[1] = + b->mode[2] = + b->mode[3] = b->mode[0]; + td->counts.mv_mode[c][b->mode[0] - 10]++; + } + } + + if (s->s.h.filtermode == FILTER_SWITCHABLE) { + int c; + + if (have_a && s->above_mode_ctx[col] >= NEARESTMV) { + if (have_l && td->left_mode_ctx[row7] >= NEARESTMV) { + c = s->above_filter_ctx[col] == td->left_filter_ctx[row7] ? + td->left_filter_ctx[row7] : 3; + } else { + c = s->above_filter_ctx[col]; + } + } else if (have_l && td->left_mode_ctx[row7] >= NEARESTMV) { + c = td->left_filter_ctx[row7]; + } else { + c = 3; + } + + filter_id = vp8_rac_get_tree(td->c, ff_vp9_filter_tree, + s->prob.p.filter[c]); + td->counts.filter[c][filter_id]++; + b->filter = ff_vp9_filter_lut[filter_id]; + } else { + b->filter = s->s.h.filtermode; + } + + if (b->bs > BS_8x8) { + int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][td->left_mode_ctx[row7]]; + + b->mode[0] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + td->counts.mv_mode[c][b->mode[0] - 10]++; + ff_vp9_fill_mv(td, b->mv[0], b->mode[0], 0); + + if (b->bs != BS_8x4) { + b->mode[1] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + td->counts.mv_mode[c][b->mode[1] - 10]++; + ff_vp9_fill_mv(td, 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(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + td->counts.mv_mode[c][b->mode[2] - 10]++; + ff_vp9_fill_mv(td, b->mv[2], b->mode[2], 2); + + if (b->bs != BS_8x4) { + b->mode[3] = vp8_rac_get_tree(td->c, ff_vp9_inter_mode_tree, + s->prob.p.mv_mode[c]); + td->counts.mv_mode[c][b->mode[3] - 10]++; + ff_vp9_fill_mv(td, 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 { + ff_vp9_fill_mv(td, 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->s.h.signbias[s->s.h.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 (ff_vp9_bwh_tab[1][b->bs][0]) { +#define SET_CTXS(perf, dir, off, n) \ + do { \ + SPLAT_CTX(perf->dir##_skip_ctx[off], b->skip, n); \ + SPLAT_CTX(perf->dir##_txfm_ctx[off], b->tx, n); \ + SPLAT_CTX(perf->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ + if (!s->s.h.keyframe && !s->s.h.intraonly) { \ + SPLAT_CTX(perf->dir##_intra_ctx[off], b->intra, n); \ + SPLAT_CTX(perf->dir##_comp_ctx[off], b->comp, n); \ + SPLAT_CTX(perf->dir##_mode_ctx[off], b->mode[3], n); \ + if (!b->intra) { \ + SPLAT_CTX(perf->dir##_ref_ctx[off], vref, n); \ + if (s->s.h.filtermode == FILTER_SWITCHABLE) { \ + SPLAT_CTX(perf->dir##_filter_ctx[off], filter_id, n); \ + } \ + } \ + } \ + } while (0) + case 1: SET_CTXS(s, above, col, 1); break; + case 2: SET_CTXS(s, above, col, 2); break; + case 4: SET_CTXS(s, above, col, 4); break; + case 8: SET_CTXS(s, above, col, 8); break; + } + switch (ff_vp9_bwh_tab[1][b->bs][1]) { + case 1: SET_CTXS(td, left, row7, 1); break; + case 2: SET_CTXS(td, left, row7, 2); break; + case 4: SET_CTXS(td, left, row7, 4); break; + case 8: SET_CTXS(td, left, row7, 8); break; + } +#undef SPLAT_CTX +#undef SET_CTXS + + if (!s->s.h.keyframe && !s->s.h.intraonly) { + if (b->bs > BS_8x8) { + int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); + + AV_COPY32(&td->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); + AV_COPY32(&td->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + 1][0], mv0); + AV_WN32A(&td->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(&td->left_mv_ctx[row7 * 2 + n][0], mv0); + AV_WN32A(&td->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; + VP9mvrefPair *mv = &s->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, int16_t *qmul) +{ + int i = 0, band = 0, band_left = band_counts[band]; + const 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 { + 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 = vp56_rac_get_prob(c, 159) + 5; + } else { + val = (vp56_rac_get_prob(c, 165) << 1) + 7; + 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 = (vp56_rac_get_prob(c, 180) << 4) + 35; + 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, (int)((vp8_rac_get(c) ? -val : val) * (unsigned)qmul[!!i]) / 2); + else + STORE_COEF(coef, rc, (vp8_rac_get(c) ? -val : val) * (unsigned)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(VP9TileData *td, 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, + int16_t *qmul) +{ + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b32_8bpp(VP9TileData *td, 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, + int16_t *qmul) +{ + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b_16bpp(VP9TileData *td, 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, + int16_t *qmul) +{ + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 0, 0, td->s->s.h.bpp, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static int decode_coeffs_b32_16bpp(VP9TileData *td, 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, + int16_t *qmul) +{ + return decode_coeffs_b_generic(td->c, coef, n_coeffs, 1, 0, td->s->s.h.bpp, cnt, eob, p, + nnz, scan, nb, band_counts, qmul); +} + +static av_always_inline int decode_coeffs(VP9TileData *td, int is8bitsperpixel) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; + uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; + unsigned (*c)[6][3] = td->counts.coef[b->tx][0 /* y */][!b->intra]; + unsigned (*e)[6][2] = td->counts.eob[b->tx][0 /* y */][!b->intra]; + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, h4 = ff_vp9_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, ret; + int16_t (*qmul)[2] = s->s.h.segmentation.feat[b->seg_id].qmul; + int tx = 4 * s->s.h.lossless + b->tx; + const int16_t * const *yscans = ff_vp9_scans[tx]; + const int16_t (* const * ynbs)[2] = ff_vp9_scans_nb[tx]; + const int16_t *uvscan = ff_vp9_scans[b->uvtx][DCT_DCT]; + const int16_t (*uvnb)[2] = ff_vp9_scans_nb[b->uvtx][DCT_DCT]; + uint8_t *a = &s->above_y_nnz_ctx[col * 2]; + uint8_t *l = &td->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 = ff_vp9_intra_txfm_type[b->mode[mode_index]]; \ + ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ + (td, td->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] = !!ret; \ + total_coeff |= !!ret; \ + if (step >= 4) { \ + AV_WN16A(&td->eob[n], ret); \ + } else { \ + td->eob[n] = ret; \ + } \ + } \ + } + +#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) { \ + ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ + (td, td->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] = !!ret; \ + total_coeff |= !!ret; \ + if (step >= 4) { \ + AV_WN16A(&td->uveob[pl][n], ret); \ + } else { \ + td->uveob[pl][n] = ret; \ + } \ + } \ + } + + p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra]; + c = td->counts.coef[b->uvtx][1 /* uv */][!b->intra]; + e = td->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 = &td->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(VP9TileData *td) +{ + return decode_coeffs(td, 1); +} + +static int decode_coeffs_16bpp(VP9TileData *td) +{ + return decode_coeffs(td, 0); +} + +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); + int l2 = tx + ss_h - 1, step1d; + static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 }; + 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; + } + } +} + +void ff_vp9_decode_block(VP9TileData *td, int row, int col, + VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + enum BlockLevel bl, enum BlockPartition bp) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + enum BlockSize bs = bl * 3 + bp; + int bytesperpixel = s->bytesperpixel; + int w4 = ff_vp9_bwh_tab[1][bs][0], h4 = ff_vp9_bwh_tab[1][bs][1], lvl; + int emu[2]; + AVFrame *f = s->s.frames[CUR_FRAME].tf.f; + + td->row = row; + td->row7 = row & 7; + td->col = col; + td->col7 = col & 7; + + td->min_mv.x = -(128 + col * 64); + td->min_mv.y = -(128 + row * 64); + td->max_mv.x = 128 + (s->cols - col - w4) * 64; + td->max_mv.y = 128 + (s->rows - row - h4) * 64; + + if (s->pass < 2) { + b->bs = bs; + b->bl = bl; + b->bp = bp; + decode_mode(td); + 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(td); + } else { + has_coeffs = decode_coeffs_16bpp(td); + } + if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) { + b->skip = 1; + memset(&s->above_skip_ctx[col], 1, w4); + memset(&td->left_skip_ctx[td->row7], 1, h4); + } + } else { + int row7 = td->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(dir##_y_##var[off * 2], n * 2); \ + if (s->ss_##dir2) { \ + SPLAT_ZERO_CTX(dir##_uv_##var[0][off], n); \ + SPLAT_ZERO_CTX(dir##_uv_##var[1][off], n); \ + } else { \ + SPLAT_ZERO_CTX(dir##_uv_##var[0][off * 2], n * 2); \ + SPLAT_ZERO_CTX(dir##_uv_##var[1][off * 2], n * 2); \ + } \ + } while (0) + + switch (w4) { + case 1: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 1, h); break; + case 2: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 2, h); break; + case 4: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 4, h); break; + case 8: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 8, h); break; + } + switch (h4) { + case 1: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 1, v); break; + case 2: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 2, v); break; + case 4: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 4, v); break; + case 8: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 8, v); break; + } + } + + if (s->pass == 1) { + s->td[0].b++; + s->td[0].block += w4 * h4 * 64 * bytesperpixel; + s->td[0].uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->td[0].uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->td[0].eob += 4 * w4 * h4; + s->td[0].uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + s->td[0].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 * bytesperpixel > f->linesize[0] || + (row + h4) > s->rows; + emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > f->linesize[1] || + (row + h4) > s->rows; + if (emu[0]) { + td->dst[0] = td->tmp_y; + td->y_stride = 128; + } else { + td->dst[0] = f->data[0] + yoff; + td->y_stride = f->linesize[0]; + } + if (emu[1]) { + td->dst[1] = td->tmp_uv[0]; + td->dst[2] = td->tmp_uv[1]; + td->uv_stride = 128; + } else { + td->dst[1] = f->data[1] + uvoff; + td->dst[2] = f->data[2] + uvoff; + td->uv_stride = f->linesize[1]; + } + if (b->intra) { + if (s->s.h.bpp > 8) { + ff_vp9_intra_recon_16bpp(td, yoff, uvoff); + } else { + ff_vp9_intra_recon_8bpp(td, yoff, uvoff); + } + } else { + if (s->s.h.bpp > 8) { + ff_vp9_inter_recon_16bpp(td); + } else { + ff_vp9_inter_recon_8bpp(td); + } + } + 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 * bytesperpixel, f->linesize[0], + td->tmp_y + o * bytesperpixel, 128, h, 0, 0); + o += bw; + } + } + } + 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 * bytesperpixel, f->linesize[1], + td->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); + s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o * bytesperpixel, f->linesize[2], + td->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); + o += bw; + } + } + } + + // pick filter level and find edges to apply filter to + if (s->s.h.filter.level && + (lvl = s->s.h.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 = td->col7, row7 = td->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->pass == 2) { + s->td[0].b++; + s->td[0].block += w4 * h4 * 64 * bytesperpixel; + s->td[0].uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->td[0].uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->td[0].eob += 4 * w4 * h4; + s->td[0].uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + s->td[0].uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + } +} diff --git a/media/ffvpx/libavcodec/vp9data.c b/media/ffvpx/libavcodec/vp9data.c new file mode 100644 index 000000000..7af8a97b1 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9data.c @@ -0,0 +1,2247 @@ +/* + * 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 "vp9.h" +#include "vp9data.h" + +const uint8_t ff_vp9_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 }, + } +}; + +const int8_t ff_vp9_partition_tree[3][2] = { + { -PARTITION_NONE, 1 }, // '0' + { -PARTITION_H, 2 }, // '10' + { -PARTITION_V, -PARTITION_SPLIT }, // '110', '111' +}; + +const uint8_t ff_vp9_default_kf_partition_probs[4][4][3] = { + { /* 64x64 -> 32x32 */ + { 174, 35, 49 } /* a/l both not split */, + { 68, 11, 27 } /* a split, l not split */, + { 57, 15, 9 } /* l split, a not split */, + { 12, 3, 3 } /* a/l both split */ + }, { /* 32x32 -> 16x16 */ + { 150, 40, 39 } /* a/l both not split */, + { 78, 12, 26 } /* a split, l not split */, + { 67, 33, 11 } /* l split, a not split */, + { 24, 7, 5 } /* a/l both split */, + }, { /* 16x16 -> 8x8 */ + { 149, 53, 53 } /* a/l both not split */, + { 94, 20, 48 } /* a split, l not split */, + { 83, 53, 24 } /* l split, a not split */, + { 52, 18, 18 } /* a/l both split */, + }, { /* 8x8 -> 4x4 */ + { 158, 97, 94 } /* a/l both not split */, + { 93, 24, 99 } /* a split, l not split */, + { 85, 119, 44 } /* l split, a not split */, + { 62, 59, 67 } /* a/l both split */, + }, +}; + +const int8_t ff_vp9_segmentation_tree[7][2] = { + { 1, 2 }, + { 3, 4 }, + { 5, 6 }, + { -0, -1 }, // '00x' + { -2, -3 }, // '01x' + { -4, -5 }, // '10x' + { -6, -7 }, // '11x' +}; + +const int8_t ff_vp9_intramode_tree[9][2] = { + { -DC_PRED, 1 }, // '0' + { -TM_VP8_PRED, 2 }, // '10' + { -VERT_PRED, 3 }, // '110' + { 4, 6 }, + { -HOR_PRED, 5 }, // '11100' + { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x' + { -DIAG_DOWN_LEFT_PRED, 7 }, // '11110' + { -VERT_LEFT_PRED, 8 }, // '111110' + { -HOR_DOWN_PRED, -HOR_UP_PRED }, // '111111x' +}; + +const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9] = { + { /* above = v */ + { 43, 46, 168, 134, 107, 128, 69, 142, 92 } /* left = v */, + { 44, 29, 68, 159, 201, 177, 50, 57, 77 } /* left = h */, + { 63, 36, 126, 146, 123, 158, 60, 90, 96 } /* left = dc */, + { 58, 38, 76, 114, 97, 172, 78, 133, 92 } /* left = d45 */, + { 46, 41, 76, 140, 63, 184, 69, 112, 57 } /* left = d135 */, + { 38, 32, 85, 140, 46, 112, 54, 151, 133 } /* left = d117 */, + { 39, 27, 61, 131, 110, 175, 44, 75, 136 } /* left = d153 */, + { 47, 35, 80, 100, 74, 143, 64, 163, 74 } /* left = d63 */, + { 52, 30, 74, 113, 130, 175, 51, 64, 58 } /* left = d27 */, + { 36, 61, 116, 114, 128, 162, 80, 125, 82 } /* left = tm */ + }, { /* above = h */ + { 55, 44, 68, 166, 179, 192, 57, 57, 108 } /* left = v */, + { 42, 26, 11, 199, 241, 228, 23, 15, 85 } /* left = h */, + { 82, 26, 26, 171, 208, 204, 44, 32, 105 } /* left = dc */, + { 68, 42, 19, 131, 160, 199, 55, 52, 83 } /* left = d45 */, + { 58, 50, 25, 139, 115, 232, 39, 52, 118 } /* left = d135 */, + { 50, 35, 33, 153, 104, 162, 64, 59, 131 } /* left = d117 */, + { 44, 24, 16, 150, 177, 202, 33, 19, 156 } /* left = d153 */, + { 53, 49, 21, 110, 116, 168, 59, 80, 76 } /* left = d63 */, + { 55, 27, 12, 153, 203, 218, 26, 27, 49 } /* left = d27 */, + { 38, 72, 19, 168, 203, 212, 50, 50, 107 } /* left = tm */ + }, { /* above = dc */ + { 92, 45, 102, 136, 116, 180, 74, 90, 100 } /* left = v */, + { 73, 32, 19, 187, 222, 215, 46, 34, 100 } /* left = h */, + { 137, 30, 42, 148, 151, 207, 70, 52, 91 } /* left = dc */, + { 91, 30, 32, 116, 121, 186, 93, 86, 94 } /* left = d45 */, + { 72, 35, 36, 149, 68, 206, 68, 63, 105 } /* left = d135 */, + { 73, 31, 28, 138, 57, 124, 55, 122, 151 } /* left = d117 */, + { 67, 23, 21, 140, 126, 197, 40, 37, 171 } /* left = d153 */, + { 74, 32, 27, 107, 86, 160, 63, 134, 102 } /* left = d63 */, + { 86, 27, 28, 128, 154, 212, 45, 43, 53 } /* left = d27 */, + { 59, 67, 44, 140, 161, 202, 78, 67, 119 } /* left = tm */ + }, { /* above = d45 */ + { 59, 38, 83, 112, 103, 162, 98, 136, 90 } /* left = v */, + { 62, 30, 23, 158, 200, 207, 59, 57, 50 } /* left = h */, + { 103, 26, 36, 129, 132, 201, 83, 80, 93 } /* left = dc */, + { 67, 30, 29, 84, 86, 191, 102, 91, 59 } /* left = d45 */, + { 60, 32, 33, 112, 71, 220, 64, 89, 104 } /* left = d135 */, + { 53, 26, 34, 130, 56, 149, 84, 120, 103 } /* left = d117 */, + { 53, 21, 23, 133, 109, 210, 56, 77, 172 } /* left = d153 */, + { 61, 29, 29, 93, 97, 165, 83, 175, 162 } /* left = d63 */, + { 77, 19, 29, 112, 142, 228, 55, 66, 36 } /* left = d27 */, + { 47, 47, 43, 114, 137, 181, 100, 99, 95 } /* left = tm */ + }, { /* above = d135 */ + { 53, 40, 55, 139, 69, 183, 61, 80, 110 } /* left = v */, + { 40, 29, 19, 161, 180, 207, 43, 24, 91 } /* left = h */, + { 69, 23, 29, 128, 83, 199, 46, 44, 101 } /* left = dc */, + { 60, 34, 19, 105, 61, 198, 53, 64, 89 } /* left = d45 */, + { 52, 31, 22, 158, 40, 209, 58, 62, 89 } /* left = d135 */, + { 44, 31, 29, 147, 46, 158, 56, 102, 198 } /* left = d117 */, + { 35, 19, 12, 135, 87, 209, 41, 45, 167 } /* left = d153 */, + { 51, 38, 25, 113, 58, 164, 70, 93, 97 } /* left = d63 */, + { 55, 25, 21, 118, 95, 215, 38, 39, 66 } /* left = d27 */, + { 47, 54, 34, 146, 108, 203, 72, 103, 151 } /* left = tm */ + }, { /* above = d117 */ + { 46, 27, 80, 150, 55, 124, 55, 121, 135 } /* left = v */, + { 36, 23, 27, 165, 149, 166, 54, 64, 118 } /* left = h */, + { 64, 19, 37, 156, 66, 138, 49, 95, 133 } /* left = dc */, + { 53, 21, 36, 131, 63, 163, 60, 109, 81 } /* left = d45 */, + { 40, 26, 35, 154, 40, 185, 51, 97, 123 } /* left = d135 */, + { 35, 19, 34, 179, 19, 97, 48, 129, 124 } /* left = d117 */, + { 36, 20, 26, 136, 62, 164, 33, 77, 154 } /* left = d153 */, + { 45, 26, 28, 129, 45, 129, 49, 147, 123 } /* left = d63 */, + { 45, 18, 32, 130, 90, 157, 40, 79, 91 } /* left = d27 */, + { 38, 44, 51, 136, 74, 162, 57, 97, 121 } /* left = tm */ + }, { /* above = d153 */ + { 56, 39, 58, 133, 117, 173, 48, 53, 187 } /* left = v */, + { 35, 21, 12, 161, 212, 207, 20, 23, 145 } /* left = h */, + { 75, 17, 22, 136, 138, 185, 32, 34, 166 } /* left = dc */, + { 56, 29, 19, 117, 109, 181, 55, 68, 112 } /* left = d45 */, + { 47, 29, 17, 153, 64, 220, 59, 51, 114 } /* left = d135 */, + { 46, 16, 24, 136, 76, 147, 41, 64, 172 } /* left = d117 */, + { 34, 17, 11, 108, 152, 187, 13, 15, 209 } /* left = d153 */, + { 55, 30, 18, 122, 79, 179, 44, 88, 116 } /* left = d63 */, + { 51, 24, 14, 115, 133, 209, 32, 26, 104 } /* left = d27 */, + { 37, 49, 25, 129, 168, 164, 41, 54, 148 } /* left = tm */ + }, { /* above = d63 */ + { 48, 34, 86, 101, 92, 146, 78, 179, 134 } /* left = v */, + { 47, 22, 24, 138, 187, 178, 68, 69, 59 } /* left = h */, + { 78, 23, 39, 111, 117, 170, 74, 124, 94 } /* left = dc */, + { 56, 25, 33, 105, 112, 187, 95, 177, 129 } /* left = d45 */, + { 48, 31, 27, 114, 63, 183, 82, 116, 56 } /* left = d135 */, + { 43, 28, 37, 121, 63, 123, 61, 192, 169 } /* left = d117 */, + { 42, 17, 24, 109, 97, 177, 56, 76, 122 } /* left = d153 */, + { 46, 23, 32, 74, 86, 150, 67, 183, 88 } /* left = d63 */, + { 58, 18, 28, 105, 139, 182, 70, 92, 63 } /* left = d27 */, + { 36, 38, 48, 92, 122, 165, 88, 137, 91 } /* left = tm */ + }, { /* above = d27 */ + { 62, 44, 61, 123, 105, 189, 48, 57, 64 } /* left = v */, + { 47, 25, 17, 175, 222, 220, 24, 30, 86 } /* left = h */, + { 82, 22, 32, 127, 143, 213, 39, 41, 70 } /* left = dc */, + { 68, 36, 17, 106, 102, 206, 59, 74, 74 } /* left = d45 */, + { 57, 39, 23, 151, 68, 216, 55, 63, 58 } /* left = d135 */, + { 49, 30, 35, 141, 70, 168, 82, 40, 115 } /* left = d117 */, + { 51, 25, 15, 136, 129, 202, 38, 35, 139 } /* left = d153 */, + { 59, 39, 19, 114, 75, 180, 77, 104, 42 } /* left = d63 */, + { 68, 26, 16, 111, 141, 215, 29, 28, 28 } /* left = d27 */, + { 40, 61, 26, 126, 152, 206, 61, 59, 93 } /* left = tm */ + }, { /* above = tm */ + { 44, 78, 115, 132, 119, 173, 71, 112, 93 } /* left = v */, + { 39, 38, 21, 184, 227, 206, 42, 32, 64 } /* left = h */, + { 65, 70, 60, 155, 159, 199, 61, 60, 81 } /* left = dc */, + { 58, 47, 36, 124, 137, 193, 80, 82, 78 } /* left = d45 */, + { 49, 50, 35, 144, 95, 205, 63, 78, 59 } /* left = d135 */, + { 41, 53, 52, 148, 71, 142, 65, 128, 51 } /* left = d117 */, + { 40, 36, 28, 143, 143, 202, 40, 55, 137 } /* left = d153 */, + { 42, 44, 44, 104, 105, 164, 64, 130, 80 } /* left = d63 */, + { 52, 34, 29, 129, 183, 227, 42, 35, 43 } /* left = d27 */, + { 43, 81, 53, 140, 169, 204, 68, 84, 72 } /* left = tm */ + } +}; + +const uint8_t ff_vp9_default_kf_uvmode_probs[10][9] = { + { 118, 15, 123, 148, 131, 101, 44, 93, 131 } /* y = v */, + { 113, 12, 23, 188, 226, 142, 26, 32, 125 } /* y = h */, + { 144, 11, 54, 157, 195, 130, 46, 58, 108 } /* y = dc */, + { 120, 11, 50, 123, 163, 135, 64, 77, 103 } /* y = d45 */, + { 113, 9, 36, 155, 111, 157, 32, 44, 161 } /* y = d135 */, + { 116, 9, 55, 176, 76, 96, 37, 61, 149 } /* y = d117 */, + { 115, 9, 28, 141, 161, 167, 21, 25, 193 } /* y = d153 */, + { 116, 12, 64, 120, 140, 125, 49, 115, 121 } /* y = d63 */, + { 120, 12, 32, 145, 195, 142, 32, 38, 86 } /* y = d27 */, + { 102, 19, 66, 162, 182, 122, 35, 59, 128 } /* y = tm */ +}; + +const int8_t ff_vp9_inter_mode_tree[3][2] = { + { -ZEROMV, 1 }, // '0' + { -NEARESTMV, 2 }, // '10' + { -NEARMV, -NEWMV }, // '11x' +}; + +const int8_t ff_vp9_filter_tree[2][2] = { + { -0, 1 }, // '0' + { -1, -2 }, // '1x' +}; + +const enum FilterMode ff_vp9_filter_lut[3] = { + FILTER_8TAP_REGULAR, + FILTER_8TAP_SMOOTH, + FILTER_8TAP_SHARP, +}; + +const int16_t ff_vp9_dc_qlookup[3][256] = { + { + 4, 8, 8, 9, 10, 11, 12, 12, + 13, 14, 15, 16, 17, 18, 19, 19, + 20, 21, 22, 23, 24, 25, 26, 26, + 27, 28, 29, 30, 31, 32, 32, 33, + 34, 35, 36, 37, 38, 38, 39, 40, + 41, 42, 43, 43, 44, 45, 46, 47, + 48, 48, 49, 50, 51, 52, 53, 53, + 54, 55, 56, 57, 57, 58, 59, 60, + 61, 62, 62, 63, 64, 65, 66, 66, + 67, 68, 69, 70, 70, 71, 72, 73, + 74, 74, 75, 76, 77, 78, 78, 79, + 80, 81, 81, 82, 83, 84, 85, 85, + 87, 88, 90, 92, 93, 95, 96, 98, + 99, 101, 102, 104, 105, 107, 108, 110, + 111, 113, 114, 116, 117, 118, 120, 121, + 123, 125, 127, 129, 131, 134, 136, 138, + 140, 142, 144, 146, 148, 150, 152, 154, + 156, 158, 161, 164, 166, 169, 172, 174, + 177, 180, 182, 185, 187, 190, 192, 195, + 199, 202, 205, 208, 211, 214, 217, 220, + 223, 226, 230, 233, 237, 240, 243, 247, + 250, 253, 257, 261, 265, 269, 272, 276, + 280, 284, 288, 292, 296, 300, 304, 309, + 313, 317, 322, 326, 330, 335, 340, 344, + 349, 354, 359, 364, 369, 374, 379, 384, + 389, 395, 400, 406, 411, 417, 423, 429, + 435, 441, 447, 454, 461, 467, 475, 482, + 489, 497, 505, 513, 522, 530, 539, 549, + 559, 569, 579, 590, 602, 614, 626, 640, + 654, 668, 684, 700, 717, 736, 755, 775, + 796, 819, 843, 869, 896, 925, 955, 988, + 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336, + }, { + 4, 9, 10, 13, 15, 17, 20, 22, + 25, 28, 31, 34, 37, 40, 43, 47, + 50, 53, 57, 60, 64, 68, 71, 75, + 78, 82, 86, 90, 93, 97, 101, 105, + 109, 113, 116, 120, 124, 128, 132, 136, + 140, 143, 147, 151, 155, 159, 163, 166, + 170, 174, 178, 182, 185, 189, 193, 197, + 200, 204, 208, 212, 215, 219, 223, 226, + 230, 233, 237, 241, 244, 248, 251, 255, + 259, 262, 266, 269, 273, 276, 280, 283, + 287, 290, 293, 297, 300, 304, 307, 310, + 314, 317, 321, 324, 327, 331, 334, 337, + 343, 350, 356, 362, 369, 375, 381, 387, + 394, 400, 406, 412, 418, 424, 430, 436, + 442, 448, 454, 460, 466, 472, 478, 484, + 490, 499, 507, 516, 525, 533, 542, 550, + 559, 567, 576, 584, 592, 601, 609, 617, + 625, 634, 644, 655, 666, 676, 687, 698, + 708, 718, 729, 739, 749, 759, 770, 782, + 795, 807, 819, 831, 844, 856, 868, 880, + 891, 906, 920, 933, 947, 961, 975, 988, + 1001, 1015, 1030, 1045, 1061, 1076, 1090, 1105, + 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, + 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, + 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, + 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, + 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, + 1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197, + 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, + 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102, + 3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, + 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347, + }, { + 4, 12, 18, 25, 33, 41, 50, 60, + 70, 80, 91, 103, 115, 127, 140, 153, + 166, 180, 194, 208, 222, 237, 251, 266, + 281, 296, 312, 327, 343, 358, 374, 390, + 405, 421, 437, 453, 469, 484, 500, 516, + 532, 548, 564, 580, 596, 611, 627, 643, + 659, 674, 690, 706, 721, 737, 752, 768, + 783, 798, 814, 829, 844, 859, 874, 889, + 904, 919, 934, 949, 964, 978, 993, 1008, + 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122, + 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, + 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, + 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, + 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741, + 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, + 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199, + 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, + 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788, + 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, + 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517, + 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, + 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, + 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, + 5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517, + 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, + 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, + 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, + 7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788, + 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, + 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, + 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, + 16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387, + } +}; + +const int16_t ff_vp9_ac_qlookup[3][256] = { + { + 4, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, + 104, 106, 108, 110, 112, 114, 116, 118, + 120, 122, 124, 126, 128, 130, 132, 134, + 136, 138, 140, 142, 144, 146, 148, 150, + 152, 155, 158, 161, 164, 167, 170, 173, + 176, 179, 182, 185, 188, 191, 194, 197, + 200, 203, 207, 211, 215, 219, 223, 227, + 231, 235, 239, 243, 247, 251, 255, 260, + 265, 270, 275, 280, 285, 290, 295, 300, + 305, 311, 317, 323, 329, 335, 341, 347, + 353, 359, 366, 373, 380, 387, 394, 401, + 408, 416, 424, 432, 440, 448, 456, 465, + 474, 483, 492, 501, 510, 520, 530, 540, + 550, 560, 571, 582, 593, 604, 615, 627, + 639, 651, 663, 676, 689, 702, 715, 729, + 743, 757, 771, 786, 801, 816, 832, 848, + 864, 881, 898, 915, 933, 951, 969, 988, + 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, + 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, + 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, + 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, + }, { + 4, 9, 11, 13, 16, 18, 21, 24, + 27, 30, 33, 37, 40, 44, 48, 51, + 55, 59, 63, 67, 71, 75, 79, 83, + 88, 92, 96, 100, 105, 109, 114, 118, + 122, 127, 131, 136, 140, 145, 149, 154, + 158, 163, 168, 172, 177, 181, 186, 190, + 195, 199, 204, 208, 213, 217, 222, 226, + 231, 235, 240, 244, 249, 253, 258, 262, + 267, 271, 275, 280, 284, 289, 293, 297, + 302, 306, 311, 315, 319, 324, 328, 332, + 337, 341, 345, 349, 354, 358, 362, 367, + 371, 375, 379, 384, 388, 392, 396, 401, + 409, 417, 425, 433, 441, 449, 458, 466, + 474, 482, 490, 498, 506, 514, 523, 531, + 539, 547, 555, 563, 571, 579, 588, 596, + 604, 616, 628, 640, 652, 664, 676, 688, + 700, 713, 725, 737, 749, 761, 773, 785, + 797, 809, 825, 841, 857, 873, 889, 905, + 922, 938, 954, 970, 986, 1002, 1018, 1038, + 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, + 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, + 1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603, + 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, + 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, + 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, + 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, + 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, + 3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952, + 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, + 4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372, + 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, + 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312, + }, { + 4, 13, 19, 27, 35, 44, 54, 64, + 75, 87, 99, 112, 126, 139, 154, 168, + 183, 199, 214, 230, 247, 263, 280, 297, + 314, 331, 349, 366, 384, 402, 420, 438, + 456, 475, 493, 511, 530, 548, 567, 586, + 604, 623, 642, 660, 679, 698, 716, 735, + 753, 772, 791, 809, 828, 846, 865, 884, + 902, 920, 939, 957, 976, 994, 1012, 1030, + 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, + 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317, + 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, + 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, + 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, + 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118, + 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, + 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750, + 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, + 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619, + 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, + 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791, + 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, + 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, + 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, + 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635, + 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, + 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, + 11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565, + 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, + 16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414, + 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, + 21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070, + 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247, + } +}; + +const enum TxfmType ff_vp9_intra_txfm_type[14] = { + [VERT_PRED] = ADST_DCT, + [HOR_PRED] = DCT_ADST, + [DC_PRED] = DCT_DCT, + [DIAG_DOWN_LEFT_PRED] = DCT_DCT, + [DIAG_DOWN_RIGHT_PRED] = ADST_ADST, + [VERT_RIGHT_PRED] = ADST_DCT, + [HOR_DOWN_PRED] = DCT_ADST, + [VERT_LEFT_PRED] = ADST_DCT, + [HOR_UP_PRED] = DCT_ADST, + [TM_VP8_PRED] = ADST_ADST, + [NEARESTMV] = DCT_DCT, + [NEARMV] = DCT_DCT, + [ZEROMV] = DCT_DCT, + [NEWMV] = DCT_DCT, +}; + +const int16_t ff_vp9_default_scan_4x4[16] = { + 0, 1, 4, 5, + 2, 8, 3, 6, + 12, 9, 7, 10, + 13, 11, 14, 15, +}; + +const int16_t ff_vp9_col_scan_4x4[16] = { + 0, 1, 2, 4, + 3, 5, 6, 8, + 7, 9, 10, 12, + 13, 11, 14, 15, +}; + +const int16_t ff_vp9_row_scan_4x4[16] = { + 0, 4, 1, 8, + 5, 12, 9, 2, + 6, 13, 3, 10, + 7, 14, 11, 15, +}; + +const int16_t ff_vp9_default_scan_8x8[64] = { + 0, 1, 8, 2, 9, 16, 10, 3, + 17, 24, 18, 11, 4, 25, 32, 19, + 12, 26, 5, 33, 20, 27, 40, 13, + 34, 6, 41, 28, 21, 35, 42, 48, + 14, 7, 36, 29, 43, 56, 49, 22, + 15, 37, 50, 44, 57, 30, 23, 51, + 45, 58, 38, 31, 52, 59, 39, 46, + 53, 60, 47, 54, 61, 55, 62, 63, +}; + +const int16_t ff_vp9_col_scan_8x8[64] = { + 0, 1, 2, 8, 3, 9, 4, 10, + 16, 5, 11, 17, 12, 18, 6, 24, + 19, 13, 25, 7, 26, 20, 32, 14, + 27, 21, 33, 28, 34, 15, 22, 35, + 40, 29, 41, 36, 23, 30, 42, 37, + 48, 43, 31, 44, 49, 38, 50, 56, + 45, 39, 51, 57, 52, 46, 58, 53, + 59, 47, 60, 54, 61, 55, 62, 63, +}; + +const int16_t ff_vp9_row_scan_8x8[64] = { + 0, 8, 16, 1, 9, 24, 2, 17, + 32, 10, 25, 3, 40, 18, 11, 33, + 26, 19, 4, 48, 41, 34, 12, 27, + 56, 20, 5, 42, 35, 13, 49, 28, + 6, 21, 43, 36, 14, 50, 29, 57, + 7, 44, 22, 37, 51, 15, 58, 30, + 23, 45, 52, 38, 59, 31, 46, 53, + 39, 60, 47, 61, 54, 62, 55, 63, +}; + +const int16_t ff_vp9_default_scan_16x16[256] = { + 0, 1, 16, 2, 17, 32, 3, 18, 33, 48, 4, 34, 19, 49, 20, 5, + 35, 64, 50, 36, 65, 21, 6, 51, 80, 66, 37, 22, 52, 7, 81, 67, + 38, 82, 53, 23, 96, 68, 8, 83, 97, 54, 39, 69, 112, 24, 98, 84, + 70, 55, 9, 40, 85, 99, 113, 128, 25, 114, 100, 71, 86, 56, 10, 41, + 115, 101, 129, 116, 72, 87, 26, 130, 144, 102, 57, 11, 42, 117, 131, 145, + 88, 103, 27, 73, 132, 118, 146, 58, 160, 12, 43, 133, 147, 104, 89, 119, + 161, 74, 148, 134, 28, 162, 59, 13, 176, 120, 149, 90, 135, 105, 163, 44, + 75, 177, 164, 29, 150, 121, 136, 178, 165, 14, 106, 60, 91, 151, 45, 179, + 192, 137, 166, 122, 76, 180, 152, 30, 61, 15, 107, 167, 181, 193, 92, 208, + 46, 138, 123, 153, 194, 77, 168, 182, 31, 195, 209, 183, 108, 139, 62, 154, + 47, 196, 93, 169, 210, 197, 224, 124, 184, 211, 78, 109, 170, 155, 63, 198, + 212, 185, 225, 240, 140, 94, 199, 125, 79, 213, 226, 171, 186, 156, 214, 200, + 110, 227, 141, 95, 241, 215, 228, 201, 126, 242, 187, 172, 157, 229, 111, 216, + 243, 142, 202, 230, 127, 217, 244, 173, 188, 231, 158, 203, 143, 245, 218, 232, + 189, 246, 159, 174, 233, 247, 219, 204, 175, 190, 248, 234, 205, 220, 249, 191, + 235, 221, 250, 206, 222, 251, 236, 207, 237, 223, 252, 238, 253, 239, 254, 255, +}; + +const int16_t ff_vp9_col_scan_16x16[256] = { + 0, 1, 2, 3, 16, 4, 17, 5, 18, 6, 19, 32, 20, 7, 33, 21, + 34, 8, 35, 22, 48, 36, 9, 49, 23, 50, 37, 10, 38, 51, 24, 64, + 52, 11, 65, 39, 25, 53, 66, 54, 40, 67, 12, 80, 26, 68, 55, 81, + 41, 69, 13, 27, 82, 56, 70, 83, 42, 14, 84, 96, 71, 28, 57, 85, + 97, 15, 72, 98, 43, 86, 58, 99, 29, 87, 100, 112, 73, 44, 101, 59, + 30, 113, 88, 114, 74, 128, 102, 45, 31, 115, 60, 103, 89, 116, 75, 129, + 117, 46, 104, 90, 61, 130, 118, 131, 132, 105, 76, 47, 119, 144, 91, 62, + 133, 106, 145, 120, 146, 134, 77, 147, 121, 92, 135, 148, 63, 107, 136, 122, + 93, 149, 160, 78, 150, 137, 108, 161, 162, 151, 123, 79, 138, 163, 152, 94, + 164, 109, 165, 153, 124, 139, 176, 166, 95, 177, 167, 110, 154, 178, 125, 179, + 140, 168, 155, 111, 180, 192, 181, 169, 141, 126, 182, 193, 194, 156, 183, 170, + 195, 127, 142, 196, 184, 208, 197, 157, 171, 143, 185, 198, 209, 199, 210, 172, + 158, 186, 211, 224, 212, 200, 240, 159, 213, 225, 187, 201, 173, 226, 214, 215, + 227, 202, 228, 188, 241, 216, 174, 229, 242, 203, 243, 217, 230, 175, 189, 244, + 231, 204, 218, 232, 245, 219, 246, 190, 233, 205, 191, 247, 234, 248, 220, 206, + 249, 235, 221, 207, 250, 236, 222, 251, 223, 237, 238, 252, 239, 253, 254, 255, +}; + +const int16_t ff_vp9_row_scan_16x16[256] = { + 0, 16, 32, 1, 48, 17, 64, 33, 2, 80, 18, 49, 96, 34, 3, 65, + 19, 112, 50, 81, 35, 4, 128, 66, 20, 97, 51, 82, 5, 144, 36, 67, + 113, 98, 21, 52, 160, 83, 129, 37, 68, 6, 114, 176, 99, 53, 22, 84, + 145, 38, 69, 130, 7, 115, 192, 100, 54, 23, 85, 161, 146, 131, 39, 70, + 208, 116, 8, 101, 177, 55, 86, 24, 162, 147, 132, 71, 224, 117, 40, 102, + 9, 148, 56, 87, 193, 163, 240, 133, 178, 25, 118, 72, 41, 103, 164, 10, + 149, 88, 134, 209, 179, 57, 119, 194, 26, 73, 165, 150, 104, 42, 135, 11, + 180, 120, 89, 225, 195, 58, 27, 210, 151, 181, 166, 74, 43, 105, 12, 136, + 90, 59, 241, 121, 28, 196, 167, 211, 152, 44, 182, 137, 75, 13, 226, 106, + 122, 60, 197, 91, 168, 29, 183, 153, 14, 76, 212, 138, 45, 107, 15, 198, + 92, 227, 169, 30, 123, 154, 61, 242, 184, 213, 139, 46, 77, 31, 108, 170, + 199, 185, 124, 228, 93, 155, 214, 62, 140, 243, 78, 47, 200, 109, 186, 171, + 201, 94, 63, 215, 229, 156, 79, 125, 141, 110, 216, 187, 172, 244, 202, 230, + 217, 95, 157, 126, 245, 111, 142, 231, 188, 127, 158, 218, 173, 232, 246, 233, + 203, 143, 247, 174, 189, 159, 219, 204, 248, 234, 249, 175, 190, 220, 205, 250, + 235, 191, 221, 251, 236, 206, 252, 222, 207, 237, 223, 253, 238, 254, 239, 255, +}; + +const int16_t ff_vp9_default_scan_32x32[1024] = { + 0, 1, 32, 2, 33, 64, 3, 34, 65, 4, 96, 35, 66, 5, 36, 97, 67, 128, 98, 68, 37, 6, 129, 99, 7, 160, 69, 38, 130, 100, 161, 131, + 39, 70, 8, 101, 162, 132, 192, 71, 40, 9, 102, 163, 133, 193, 72, 224, 103, 41, 164, 10, 194, 134, 165, 73, 104, 135, 225, 42, 195, 11, 256, 166, + 226, 196, 74, 105, 136, 43, 12, 167, 197, 227, 257, 75, 106, 137, 228, 44, 198, 168, 258, 288, 13, 229, 76, 107, 199, 138, 259, 169, 289, 45, 230, 260, + 200, 108, 14, 170, 139, 320, 290, 77, 231, 261, 46, 201, 140, 291, 109, 232, 321, 262, 171, 78, 292, 15, 322, 202, 263, 352, 172, 293, 233, 141, 323, 110, + 47, 203, 264, 234, 294, 353, 324, 16, 79, 204, 265, 295, 325, 173, 354, 142, 235, 384, 48, 296, 111, 266, 355, 326, 80, 17, 205, 236, 174, 356, 385, 327, + 143, 297, 267, 357, 386, 112, 49, 328, 298, 206, 416, 237, 358, 387, 81, 175, 18, 329, 359, 388, 299, 330, 389, 113, 417, 238, 360, 50, 207, 418, 390, 331, + 19, 448, 361, 82, 419, 391, 239, 51, 362, 420, 114, 449, 480, 421, 83, 363, 450, 422, 512, 451, 423, 115, 452, 481, 453, 482, 454, 544, 483, 455, 513, 484, + 514, 485, 515, 486, 545, 576, 487, 546, 547, 608, 577, 578, 579, 609, 610, 611, 20, 144, 268, 392, 516, 640, 21, 52, 145, 176, 269, 300, 393, 424, 517, 548, + 641, 672, 22, 53, 84, 146, 177, 208, 270, 301, 332, 394, 425, 456, 518, 549, 580, 642, 673, 704, 23, 54, 85, 116, 147, 178, 209, 240, 271, 302, 333, 364, + 395, 426, 457, 488, 519, 550, 581, 612, 643, 674, 705, 736, 55, 86, 117, 179, 210, 241, 303, 334, 365, 427, 458, 489, 551, 582, 613, 675, 706, 737, 87, 118, + 211, 242, 335, 366, 459, 490, 583, 614, 707, 738, 119, 243, 367, 491, 615, 739, 24, 148, 272, 396, 520, 644, 768, 25, 56, 149, 180, 273, 304, 397, 428, 521, + 552, 645, 676, 769, 800, 26, 57, 88, 150, 181, 212, 274, 305, 336, 398, 429, 460, 522, 553, 584, 646, 677, 708, 770, 801, 832, 27, 58, 89, 120, 151, 182, + 213, 244, 275, 306, 337, 368, 399, 430, 461, 492, 523, 554, 585, 616, 647, 678, 709, 740, 771, 802, 833, 864, 59, 90, 121, 183, 214, 245, 307, 338, 369, 431, + 462, 493, 555, 586, 617, 679, 710, 741, 803, 834, 865, 91, 122, 215, 246, 339, 370, 463, 494, 587, 618, 711, 742, 835, 866, 123, 247, 371, 495, 619, 743, 867, + 28, 152, 276, 400, 524, 648, 772, 896, 29, 60, 153, 184, 277, 308, 401, 432, 525, 556, 649, 680, 773, 804, 897, 928, 30, 61, 92, 154, 185, 216, 278, 309, + 340, 402, 433, 464, 526, 557, 588, 650, 681, 712, 774, 805, 836, 898, 929, 960, 31, 62, 93, 124, 155, 186, 217, 248, 279, 310, 341, 372, 403, 434, 465, 496, + 527, 558, 589, 620, 651, 682, 713, 744, 775, 806, 837, 868, 899, 930, 961, 992, 63, 94, 125, 187, 218, 249, 311, 342, 373, 435, 466, 497, 559, 590, 621, 683, + 714, 745, 807, 838, 869, 931, 962, 993, 95, 126, 219, 250, 343, 374, 467, 498, 591, 622, 715, 746, 839, 870, 963, 994, 127, 251, 375, 499, 623, 747, 871, 995, + 156, 280, 404, 528, 652, 776, 900, 157, 188, 281, 312, 405, 436, 529, 560, 653, 684, 777, 808, 901, 932, 158, 189, 220, 282, 313, 344, 406, 437, 468, 530, 561, + 592, 654, 685, 716, 778, 809, 840, 902, 933, 964, 159, 190, 221, 252, 283, 314, 345, 376, 407, 438, 469, 500, 531, 562, 593, 624, 655, 686, 717, 748, 779, 810, + 841, 872, 903, 934, 965, 996, 191, 222, 253, 315, 346, 377, 439, 470, 501, 563, 594, 625, 687, 718, 749, 811, 842, 873, 935, 966, 997, 223, 254, 347, 378, 471, + 502, 595, 626, 719, 750, 843, 874, 967, 998, 255, 379, 503, 627, 751, 875, 999, 284, 408, 532, 656, 780, 904, 285, 316, 409, 440, 533, 564, 657, 688, 781, 812, + 905, 936, 286, 317, 348, 410, 441, 472, 534, 565, 596, 658, 689, 720, 782, 813, 844, 906, 937, 968, 287, 318, 349, 380, 411, 442, 473, 504, 535, 566, 597, 628, + 659, 690, 721, 752, 783, 814, 845, 876, 907, 938, 969, 1000, 319, 350, 381, 443, 474, 505, 567, 598, 629, 691, 722, 753, 815, 846, 877, 939, 970, 1001, 351, 382, + 475, 506, 599, 630, 723, 754, 847, 878, 971, 1002, 383, 507, 631, 755, 879, 1003, 412, 536, 660, 784, 908, 413, 444, 537, 568, 661, 692, 785, 816, 909, 940, 414, + 445, 476, 538, 569, 600, 662, 693, 724, 786, 817, 848, 910, 941, 972, 415, 446, 477, 508, 539, 570, 601, 632, 663, 694, 725, 756, 787, 818, 849, 880, 911, 942, + 973, 1004, 447, 478, 509, 571, 602, 633, 695, 726, 757, 819, 850, 881, 943, 974, 1005, 479, 510, 603, 634, 727, 758, 851, 882, 975, 1006, 511, 635, 759, 883, 1007, + 540, 664, 788, 912, 541, 572, 665, 696, 789, 820, 913, 944, 542, 573, 604, 666, 697, 728, 790, 821, 852, 914, 945, 976, 543, 574, 605, 636, 667, 698, 729, 760, + 791, 822, 853, 884, 915, 946, 977, 1008, 575, 606, 637, 699, 730, 761, 823, 854, 885, 947, 978, 1009, 607, 638, 731, 762, 855, 886, 979, 1010, 639, 763, 887, 1011, + 668, 792, 916, 669, 700, 793, 824, 917, 948, 670, 701, 732, 794, 825, 856, 918, 949, 980, 671, 702, 733, 764, 795, 826, 857, 888, 919, 950, 981, 1012, 703, 734, + 765, 827, 858, 889, 951, 982, 1013, 735, 766, 859, 890, 983, 1014, 767, 891, 1015, 796, 920, 797, 828, 921, 952, 798, 829, 860, 922, 953, 984, 799, 830, 861, 892, + 923, 954, 985, 1016, 831, 862, 893, 955, 986, 1017, 863, 894, 987, 1018, 895, 1019, 924, 925, 956, 926, 957, 988, 927, 958, 989, 1020, 959, 990, 1021, 991, 1022, 1023, +}; + +const int16_t * const ff_vp9_scans[5][4] = { + { + ff_vp9_default_scan_4x4, ff_vp9_col_scan_4x4, + ff_vp9_row_scan_4x4, ff_vp9_default_scan_4x4 + }, { + ff_vp9_default_scan_8x8, ff_vp9_col_scan_8x8, + ff_vp9_row_scan_8x8, ff_vp9_default_scan_8x8 + }, { + ff_vp9_default_scan_16x16, ff_vp9_col_scan_16x16, + ff_vp9_row_scan_16x16, ff_vp9_default_scan_16x16 + }, { + ff_vp9_default_scan_32x32, ff_vp9_default_scan_32x32, + ff_vp9_default_scan_32x32, ff_vp9_default_scan_32x32 + }, { // lossless + ff_vp9_default_scan_4x4, ff_vp9_default_scan_4x4, + ff_vp9_default_scan_4x4, ff_vp9_default_scan_4x4 + } +}; + +const int16_t ff_vp9_default_scan_4x4_nb[16][2] = { + { 0, 0 }, { 0, 0 }, { 4, 1 }, { 1, 1 }, + { 4, 4 }, { 2, 2 }, { 5, 2 }, { 8, 8 }, + { 8, 5 }, { 6, 3 }, { 9, 6 }, { 12, 9 }, + { 10, 7 }, { 13, 10 }, { 14, 11 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_4x4_nb[16][2] = { + { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, + { 4, 4 }, { 5, 5 }, { 4, 4 }, { 6, 6 }, + { 8, 8 }, { 9, 9 }, { 8, 8 }, { 12, 12 }, + { 10, 10 }, { 13, 13 }, { 14, 14 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_4x4_nb[16][2] = { + { 0, 0 }, { 0, 0 }, { 4, 4 }, { 1, 1 }, + { 8, 8 }, { 5, 5 }, { 1, 1 }, { 2, 2 }, + { 9, 9 }, { 2, 2 }, { 6, 6 }, { 3, 3 }, + { 10, 10 }, { 7, 7 }, { 11, 11 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_8x8_nb[64][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 8, 1 }, + { 8, 8 }, { 9, 2 }, { 2, 2 }, { 16, 9 }, + { 16, 16 }, { 17, 10 }, { 10, 3 }, { 3, 3 }, + { 24, 17 }, { 24, 24 }, { 18, 11 }, { 11, 4 }, + { 25, 18 }, { 4, 4 }, { 32, 25 }, { 19, 12 }, + { 26, 19 }, { 32, 32 }, { 12, 5 }, { 33, 26 }, + { 5, 5 }, { 40, 33 }, { 27, 20 }, { 20, 13 }, + { 34, 27 }, { 41, 34 }, { 40, 40 }, { 13, 6 }, + { 6, 6 }, { 35, 28 }, { 28, 21 }, { 42, 35 }, + { 48, 48 }, { 48, 41 }, { 21, 14 }, { 14, 7 }, + { 36, 29 }, { 49, 42 }, { 43, 36 }, { 56, 49 }, + { 29, 22 }, { 22, 15 }, { 50, 43 }, { 44, 37 }, + { 57, 50 }, { 37, 30 }, { 30, 23 }, { 51, 44 }, + { 58, 51 }, { 38, 31 }, { 45, 38 }, { 52, 45 }, + { 59, 52 }, { 46, 39 }, { 53, 46 }, { 60, 53 }, + { 54, 47 }, { 61, 54 }, { 62, 55 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_8x8_nb[64][2] = { + { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, + { 8, 8 }, { 3, 3 }, { 9, 9 }, { 8, 8 }, + { 4, 4 }, { 10, 10 }, { 16, 16 }, { 11, 11 }, + { 17, 17 }, { 5, 5 }, { 16, 16 }, { 18, 18 }, + { 12, 12 }, { 24, 24 }, { 6, 6 }, { 25, 25 }, + { 19, 19 }, { 24, 24 }, { 13, 13 }, { 26, 26 }, + { 20, 20 }, { 32, 32 }, { 27, 27 }, { 33, 33 }, + { 14, 14 }, { 21, 21 }, { 34, 34 }, { 32, 32 }, + { 28, 28 }, { 40, 40 }, { 35, 35 }, { 22, 22 }, + { 29, 29 }, { 41, 41 }, { 36, 36 }, { 40, 40 }, + { 42, 42 }, { 30, 30 }, { 43, 43 }, { 48, 48 }, + { 37, 37 }, { 49, 49 }, { 48, 48 }, { 44, 44 }, + { 38, 38 }, { 50, 50 }, { 56, 56 }, { 51, 51 }, + { 45, 45 }, { 57, 57 }, { 52, 52 }, { 58, 58 }, + { 46, 46 }, { 59, 59 }, { 53, 53 }, { 60, 60 }, + { 54, 54 }, { 61, 61 }, { 62, 62 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_8x8_nb[64][2] = { + { 0, 0 }, { 8, 8 }, { 0, 0 }, { 1, 1 }, + { 16, 16 }, { 1, 1 }, { 9, 9 }, { 24, 24 }, + { 2, 2 }, { 17, 17 }, { 2, 2 }, { 32, 32 }, + { 10, 10 }, { 3, 3 }, { 25, 25 }, { 18, 18 }, + { 11, 11 }, { 3, 3 }, { 40, 40 }, { 33, 33 }, + { 26, 26 }, { 4, 4 }, { 19, 19 }, { 48, 48 }, + { 12, 12 }, { 4, 4 }, { 34, 34 }, { 27, 27 }, + { 5, 5 }, { 41, 41 }, { 20, 20 }, { 5, 5 }, + { 13, 13 }, { 35, 35 }, { 28, 28 }, { 6, 6 }, + { 42, 42 }, { 21, 21 }, { 49, 49 }, { 6, 6 }, + { 36, 36 }, { 14, 14 }, { 29, 29 }, { 43, 43 }, + { 7, 7 }, { 50, 50 }, { 22, 22 }, { 15, 15 }, + { 37, 37 }, { 44, 44 }, { 30, 30 }, { 51, 51 }, + { 23, 23 }, { 38, 38 }, { 45, 45 }, { 31, 31 }, + { 52, 52 }, { 39, 39 }, { 53, 53 }, { 46, 46 }, + { 54, 54 }, { 47, 47 }, { 55, 55 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_16x16_nb[256][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 16, 1 }, + { 16, 16 }, { 2, 2 }, { 17, 2 }, { 32, 17 }, + { 32, 32 }, { 3, 3 }, { 33, 18 }, { 18, 3 }, + { 48, 33 }, { 19, 4 }, { 4, 4 }, { 34, 19 }, + { 48, 48 }, { 49, 34 }, { 35, 20 }, { 64, 49 }, + { 20, 5 }, { 5, 5 }, { 50, 35 }, { 64, 64 }, + { 65, 50 }, { 36, 21 }, { 21, 6 }, { 51, 36 }, + { 6, 6 }, { 80, 65 }, { 66, 51 }, { 37, 22 }, + { 81, 66 }, { 52, 37 }, { 22, 7 }, { 80, 80 }, + { 67, 52 }, { 7, 7 }, { 82, 67 }, { 96, 81 }, + { 53, 38 }, { 38, 23 }, { 68, 53 }, { 96, 96 }, + { 23, 8 }, { 97, 82 }, { 83, 68 }, { 69, 54 }, + { 54, 39 }, { 8, 8 }, { 39, 24 }, { 84, 69 }, + { 98, 83 }, { 112, 97 }, { 112, 112 }, { 24, 9 }, + { 113, 98 }, { 99, 84 }, { 70, 55 }, { 85, 70 }, + { 55, 40 }, { 9, 9 }, { 40, 25 }, { 114, 99 }, + { 100, 85 }, { 128, 113 }, { 115, 100 }, { 71, 56 }, + { 86, 71 }, { 25, 10 }, { 129, 114 }, { 128, 128 }, + { 101, 86 }, { 56, 41 }, { 10, 10 }, { 41, 26 }, + { 116, 101 }, { 130, 115 }, { 144, 129 }, { 87, 72 }, + { 102, 87 }, { 26, 11 }, { 72, 57 }, { 131, 116 }, + { 117, 102 }, { 145, 130 }, { 57, 42 }, { 144, 144 }, + { 11, 11 }, { 42, 27 }, { 132, 117 }, { 146, 131 }, + { 103, 88 }, { 88, 73 }, { 118, 103 }, { 160, 145 }, + { 73, 58 }, { 147, 132 }, { 133, 118 }, { 27, 12 }, + { 161, 146 }, { 58, 43 }, { 12, 12 }, { 160, 160 }, + { 119, 104 }, { 148, 133 }, { 89, 74 }, { 134, 119 }, + { 104, 89 }, { 162, 147 }, { 43, 28 }, { 74, 59 }, + { 176, 161 }, { 163, 148 }, { 28, 13 }, { 149, 134 }, + { 120, 105 }, { 135, 120 }, { 177, 162 }, { 164, 149 }, + { 13, 13 }, { 105, 90 }, { 59, 44 }, { 90, 75 }, + { 150, 135 }, { 44, 29 }, { 178, 163 }, { 176, 176 }, + { 136, 121 }, { 165, 150 }, { 121, 106 }, { 75, 60 }, + { 179, 164 }, { 151, 136 }, { 29, 14 }, { 60, 45 }, + { 14, 14 }, { 106, 91 }, { 166, 151 }, { 180, 165 }, + { 192, 177 }, { 91, 76 }, { 192, 192 }, { 45, 30 }, + { 137, 122 }, { 122, 107 }, { 152, 137 }, { 193, 178 }, + { 76, 61 }, { 167, 152 }, { 181, 166 }, { 30, 15 }, + { 194, 179 }, { 208, 193 }, { 182, 167 }, { 107, 92 }, + { 138, 123 }, { 61, 46 }, { 153, 138 }, { 46, 31 }, + { 195, 180 }, { 92, 77 }, { 168, 153 }, { 209, 194 }, + { 196, 181 }, { 208, 208 }, { 123, 108 }, { 183, 168 }, + { 210, 195 }, { 77, 62 }, { 108, 93 }, { 169, 154 }, + { 154, 139 }, { 62, 47 }, { 197, 182 }, { 211, 196 }, + { 184, 169 }, { 224, 209 }, { 224, 224 }, { 139, 124 }, + { 93, 78 }, { 198, 183 }, { 124, 109 }, { 78, 63 }, + { 212, 197 }, { 225, 210 }, { 170, 155 }, { 185, 170 }, + { 155, 140 }, { 213, 198 }, { 199, 184 }, { 109, 94 }, + { 226, 211 }, { 140, 125 }, { 94, 79 }, { 240, 225 }, + { 214, 199 }, { 227, 212 }, { 200, 185 }, { 125, 110 }, + { 241, 226 }, { 186, 171 }, { 171, 156 }, { 156, 141 }, + { 228, 213 }, { 110, 95 }, { 215, 200 }, { 242, 227 }, + { 141, 126 }, { 201, 186 }, { 229, 214 }, { 126, 111 }, + { 216, 201 }, { 243, 228 }, { 172, 157 }, { 187, 172 }, + { 230, 215 }, { 157, 142 }, { 202, 187 }, { 142, 127 }, + { 244, 229 }, { 217, 202 }, { 231, 216 }, { 188, 173 }, + { 245, 230 }, { 158, 143 }, { 173, 158 }, { 232, 217 }, + { 246, 231 }, { 218, 203 }, { 203, 188 }, { 174, 159 }, + { 189, 174 }, { 247, 232 }, { 233, 218 }, { 204, 189 }, + { 219, 204 }, { 248, 233 }, { 190, 175 }, { 234, 219 }, + { 220, 205 }, { 249, 234 }, { 205, 190 }, { 221, 206 }, + { 250, 235 }, { 235, 220 }, { 206, 191 }, { 236, 221 }, + { 222, 207 }, { 251, 236 }, { 237, 222 }, { 252, 237 }, + { 238, 223 }, { 253, 238 }, { 254, 239 }, { 0, 0 }, +}; + +const int16_t ff_vp9_col_scan_16x16_nb[256][2] = { + { 0, 0 }, { 1, 1 }, { 2, 2 }, { 0, 0 }, + { 3, 3 }, { 16, 16 }, { 4, 4 }, { 17, 17 }, + { 5, 5 }, { 18, 18 }, { 16, 16 }, { 19, 19 }, + { 6, 6 }, { 32, 32 }, { 20, 20 }, { 33, 33 }, + { 7, 7 }, { 34, 34 }, { 21, 21 }, { 32, 32 }, + { 35, 35 }, { 8, 8 }, { 48, 48 }, { 22, 22 }, + { 49, 49 }, { 36, 36 }, { 9, 9 }, { 37, 37 }, + { 50, 50 }, { 23, 23 }, { 48, 48 }, { 51, 51 }, + { 10, 10 }, { 64, 64 }, { 38, 38 }, { 24, 24 }, + { 52, 52 }, { 65, 65 }, { 53, 53 }, { 39, 39 }, + { 66, 66 }, { 11, 11 }, { 64, 64 }, { 25, 25 }, + { 67, 67 }, { 54, 54 }, { 80, 80 }, { 40, 40 }, + { 68, 68 }, { 12, 12 }, { 26, 26 }, { 81, 81 }, + { 55, 55 }, { 69, 69 }, { 82, 82 }, { 41, 41 }, + { 13, 13 }, { 83, 83 }, { 80, 80 }, { 70, 70 }, + { 27, 27 }, { 56, 56 }, { 84, 84 }, { 96, 96 }, + { 14, 14 }, { 71, 71 }, { 97, 97 }, { 42, 42 }, + { 85, 85 }, { 57, 57 }, { 98, 98 }, { 28, 28 }, + { 86, 86 }, { 99, 99 }, { 96, 96 }, { 72, 72 }, + { 43, 43 }, { 100, 100 }, { 58, 58 }, { 29, 29 }, + { 112, 112 }, { 87, 87 }, { 113, 113 }, { 73, 73 }, + { 112, 112 }, { 101, 101 }, { 44, 44 }, { 30, 30 }, + { 114, 114 }, { 59, 59 }, { 102, 102 }, { 88, 88 }, + { 115, 115 }, { 74, 74 }, { 128, 128 }, { 116, 116 }, + { 45, 45 }, { 103, 103 }, { 89, 89 }, { 60, 60 }, + { 129, 129 }, { 117, 117 }, { 130, 130 }, { 131, 131 }, + { 104, 104 }, { 75, 75 }, { 46, 46 }, { 118, 118 }, + { 128, 128 }, { 90, 90 }, { 61, 61 }, { 132, 132 }, + { 105, 105 }, { 144, 144 }, { 119, 119 }, { 145, 145 }, + { 133, 133 }, { 76, 76 }, { 146, 146 }, { 120, 120 }, + { 91, 91 }, { 134, 134 }, { 147, 147 }, { 62, 62 }, + { 106, 106 }, { 135, 135 }, { 121, 121 }, { 92, 92 }, + { 148, 148 }, { 144, 144 }, { 77, 77 }, { 149, 149 }, + { 136, 136 }, { 107, 107 }, { 160, 160 }, { 161, 161 }, + { 150, 150 }, { 122, 122 }, { 78, 78 }, { 137, 137 }, + { 162, 162 }, { 151, 151 }, { 93, 93 }, { 163, 163 }, + { 108, 108 }, { 164, 164 }, { 152, 152 }, { 123, 123 }, + { 138, 138 }, { 160, 160 }, { 165, 165 }, { 94, 94 }, + { 176, 176 }, { 166, 166 }, { 109, 109 }, { 153, 153 }, + { 177, 177 }, { 124, 124 }, { 178, 178 }, { 139, 139 }, + { 167, 167 }, { 154, 154 }, { 110, 110 }, { 179, 179 }, + { 176, 176 }, { 180, 180 }, { 168, 168 }, { 140, 140 }, + { 125, 125 }, { 181, 181 }, { 192, 192 }, { 193, 193 }, + { 155, 155 }, { 182, 182 }, { 169, 169 }, { 194, 194 }, + { 126, 126 }, { 141, 141 }, { 195, 195 }, { 183, 183 }, + { 192, 192 }, { 196, 196 }, { 156, 156 }, { 170, 170 }, + { 142, 142 }, { 184, 184 }, { 197, 197 }, { 208, 208 }, + { 198, 198 }, { 209, 209 }, { 171, 171 }, { 157, 157 }, + { 185, 185 }, { 210, 210 }, { 208, 208 }, { 211, 211 }, + { 199, 199 }, { 224, 224 }, { 158, 158 }, { 212, 212 }, + { 224, 224 }, { 186, 186 }, { 200, 200 }, { 172, 172 }, + { 225, 225 }, { 213, 213 }, { 214, 214 }, { 226, 226 }, + { 201, 201 }, { 227, 227 }, { 187, 187 }, { 240, 240 }, + { 215, 215 }, { 173, 173 }, { 228, 228 }, { 241, 241 }, + { 202, 202 }, { 242, 242 }, { 216, 216 }, { 229, 229 }, + { 174, 174 }, { 188, 188 }, { 243, 243 }, { 230, 230 }, + { 203, 203 }, { 217, 217 }, { 231, 231 }, { 244, 244 }, + { 218, 218 }, { 245, 245 }, { 189, 189 }, { 232, 232 }, + { 204, 204 }, { 190, 190 }, { 246, 246 }, { 233, 233 }, + { 247, 247 }, { 219, 219 }, { 205, 205 }, { 248, 248 }, + { 234, 234 }, { 220, 220 }, { 206, 206 }, { 249, 249 }, + { 235, 235 }, { 221, 221 }, { 250, 250 }, { 222, 222 }, + { 236, 236 }, { 237, 237 }, { 251, 251 }, { 238, 238 }, + { 252, 252 }, { 253, 253 }, { 254, 254 }, { 0, 0 }, +}; + +const int16_t ff_vp9_row_scan_16x16_nb[256][2] = { + { 0, 0 }, { 16, 16 }, { 0, 0 }, { 32, 32 }, + { 1, 1 }, { 48, 48 }, { 17, 17 }, { 1, 1 }, + { 64, 64 }, { 2, 2 }, { 33, 33 }, { 80, 80 }, + { 18, 18 }, { 2, 2 }, { 49, 49 }, { 3, 3 }, + { 96, 96 }, { 34, 34 }, { 65, 65 }, { 19, 19 }, + { 3, 3 }, { 112, 112 }, { 50, 50 }, { 4, 4 }, + { 81, 81 }, { 35, 35 }, { 66, 66 }, { 4, 4 }, + { 128, 128 }, { 20, 20 }, { 51, 51 }, { 97, 97 }, + { 82, 82 }, { 5, 5 }, { 36, 36 }, { 144, 144 }, + { 67, 67 }, { 113, 113 }, { 21, 21 }, { 52, 52 }, + { 5, 5 }, { 98, 98 }, { 160, 160 }, { 83, 83 }, + { 37, 37 }, { 6, 6 }, { 68, 68 }, { 129, 129 }, + { 22, 22 }, { 53, 53 }, { 114, 114 }, { 6, 6 }, + { 99, 99 }, { 176, 176 }, { 84, 84 }, { 38, 38 }, + { 7, 7 }, { 69, 69 }, { 145, 145 }, { 130, 130 }, + { 115, 115 }, { 23, 23 }, { 54, 54 }, { 192, 192 }, + { 100, 100 }, { 7, 7 }, { 85, 85 }, { 161, 161 }, + { 39, 39 }, { 70, 70 }, { 8, 8 }, { 146, 146 }, + { 131, 131 }, { 116, 116 }, { 55, 55 }, { 208, 208 }, + { 101, 101 }, { 24, 24 }, { 86, 86 }, { 8, 8 }, + { 132, 132 }, { 40, 40 }, { 71, 71 }, { 177, 177 }, + { 147, 147 }, { 224, 224 }, { 117, 117 }, { 162, 162 }, + { 9, 9 }, { 102, 102 }, { 56, 56 }, { 25, 25 }, + { 87, 87 }, { 148, 148 }, { 9, 9 }, { 133, 133 }, + { 72, 72 }, { 118, 118 }, { 193, 193 }, { 163, 163 }, + { 41, 41 }, { 103, 103 }, { 178, 178 }, { 10, 10 }, + { 57, 57 }, { 149, 149 }, { 134, 134 }, { 88, 88 }, + { 26, 26 }, { 119, 119 }, { 10, 10 }, { 164, 164 }, + { 104, 104 }, { 73, 73 }, { 209, 209 }, { 179, 179 }, + { 42, 42 }, { 11, 11 }, { 194, 194 }, { 135, 135 }, + { 165, 165 }, { 150, 150 }, { 58, 58 }, { 27, 27 }, + { 89, 89 }, { 11, 11 }, { 120, 120 }, { 74, 74 }, + { 43, 43 }, { 225, 225 }, { 105, 105 }, { 12, 12 }, + { 180, 180 }, { 151, 151 }, { 195, 195 }, { 136, 136 }, + { 28, 28 }, { 166, 166 }, { 121, 121 }, { 59, 59 }, + { 12, 12 }, { 210, 210 }, { 90, 90 }, { 106, 106 }, + { 44, 44 }, { 181, 181 }, { 75, 75 }, { 152, 152 }, + { 13, 13 }, { 167, 167 }, { 137, 137 }, { 13, 13 }, + { 60, 60 }, { 196, 196 }, { 122, 122 }, { 29, 29 }, + { 91, 91 }, { 14, 14 }, { 182, 182 }, { 76, 76 }, + { 211, 211 }, { 153, 153 }, { 14, 14 }, { 107, 107 }, + { 138, 138 }, { 45, 45 }, { 226, 226 }, { 168, 168 }, + { 197, 197 }, { 123, 123 }, { 30, 30 }, { 61, 61 }, + { 15, 15 }, { 92, 92 }, { 154, 154 }, { 183, 183 }, + { 169, 169 }, { 108, 108 }, { 212, 212 }, { 77, 77 }, + { 139, 139 }, { 198, 198 }, { 46, 46 }, { 124, 124 }, + { 227, 227 }, { 62, 62 }, { 31, 31 }, { 184, 184 }, + { 93, 93 }, { 170, 170 }, { 155, 155 }, { 185, 185 }, + { 78, 78 }, { 47, 47 }, { 199, 199 }, { 213, 213 }, + { 140, 140 }, { 63, 63 }, { 109, 109 }, { 125, 125 }, + { 94, 94 }, { 200, 200 }, { 171, 171 }, { 156, 156 }, + { 228, 228 }, { 186, 186 }, { 214, 214 }, { 201, 201 }, + { 79, 79 }, { 141, 141 }, { 110, 110 }, { 229, 229 }, + { 95, 95 }, { 126, 126 }, { 215, 215 }, { 172, 172 }, + { 111, 111 }, { 142, 142 }, { 202, 202 }, { 157, 157 }, + { 216, 216 }, { 230, 230 }, { 217, 217 }, { 187, 187 }, + { 127, 127 }, { 231, 231 }, { 158, 158 }, { 173, 173 }, + { 143, 143 }, { 203, 203 }, { 188, 188 }, { 232, 232 }, + { 218, 218 }, { 233, 233 }, { 159, 159 }, { 174, 174 }, + { 204, 204 }, { 189, 189 }, { 234, 234 }, { 219, 219 }, + { 175, 175 }, { 205, 205 }, { 235, 235 }, { 220, 220 }, + { 190, 190 }, { 236, 236 }, { 206, 206 }, { 191, 191 }, + { 221, 221 }, { 207, 207 }, { 237, 237 }, { 222, 222 }, + { 238, 238 }, { 223, 223 }, { 239, 239 }, { 0, 0 }, +}; + +const int16_t ff_vp9_default_scan_32x32_nb[1024][2] = { + { 0, 0 }, { 0, 0 }, { 1, 1 }, { 32, 1 }, + { 32, 32 }, { 2, 2 }, { 33, 2 }, { 64, 33 }, + { 3, 3 }, { 64, 64 }, { 34, 3 }, { 65, 34 }, + { 4, 4 }, { 35, 4 }, { 96, 65 }, { 66, 35 }, + { 96, 96 }, { 97, 66 }, { 67, 36 }, { 36, 5 }, + { 5, 5 }, { 128, 97 }, { 98, 67 }, { 6, 6 }, + { 128, 128 }, { 68, 37 }, { 37, 6 }, { 129, 98 }, + { 99, 68 }, { 160, 129 }, { 130, 99 }, { 38, 7 }, + { 69, 38 }, { 7, 7 }, { 100, 69 }, { 161, 130 }, + { 131, 100 }, { 160, 160 }, { 70, 39 }, { 39, 8 }, + { 8, 8 }, { 101, 70 }, { 162, 131 }, { 132, 101 }, + { 192, 161 }, { 71, 40 }, { 192, 192 }, { 102, 71 }, + { 40, 9 }, { 163, 132 }, { 9, 9 }, { 193, 162 }, + { 133, 102 }, { 164, 133 }, { 72, 41 }, { 103, 72 }, + { 134, 103 }, { 224, 193 }, { 41, 10 }, { 194, 163 }, + { 10, 10 }, { 224, 224 }, { 165, 134 }, { 225, 194 }, + { 195, 164 }, { 73, 42 }, { 104, 73 }, { 135, 104 }, + { 42, 11 }, { 11, 11 }, { 166, 135 }, { 196, 165 }, + { 226, 195 }, { 256, 225 }, { 74, 43 }, { 105, 74 }, + { 136, 105 }, { 227, 196 }, { 43, 12 }, { 197, 166 }, + { 167, 136 }, { 257, 226 }, { 256, 256 }, { 12, 12 }, + { 228, 197 }, { 75, 44 }, { 106, 75 }, { 198, 167 }, + { 137, 106 }, { 258, 227 }, { 168, 137 }, { 288, 257 }, + { 44, 13 }, { 229, 198 }, { 259, 228 }, { 199, 168 }, + { 107, 76 }, { 13, 13 }, { 169, 138 }, { 138, 107 }, + { 288, 288 }, { 289, 258 }, { 76, 45 }, { 230, 199 }, + { 260, 229 }, { 45, 14 }, { 200, 169 }, { 139, 108 }, + { 290, 259 }, { 108, 77 }, { 231, 200 }, { 320, 289 }, + { 261, 230 }, { 170, 139 }, { 77, 46 }, { 291, 260 }, + { 14, 14 }, { 321, 290 }, { 201, 170 }, { 262, 231 }, + { 320, 320 }, { 171, 140 }, { 292, 261 }, { 232, 201 }, + { 140, 109 }, { 322, 291 }, { 109, 78 }, { 46, 15 }, + { 202, 171 }, { 263, 232 }, { 233, 202 }, { 293, 262 }, + { 352, 321 }, { 323, 292 }, { 15, 15 }, { 78, 47 }, + { 203, 172 }, { 264, 233 }, { 294, 263 }, { 324, 293 }, + { 172, 141 }, { 353, 322 }, { 141, 110 }, { 234, 203 }, + { 352, 352 }, { 47, 16 }, { 295, 264 }, { 110, 79 }, + { 265, 234 }, { 354, 323 }, { 325, 294 }, { 79, 48 }, + { 16, 16 }, { 204, 173 }, { 235, 204 }, { 173, 142 }, + { 355, 324 }, { 384, 353 }, { 326, 295 }, { 142, 111 }, + { 296, 265 }, { 266, 235 }, { 356, 325 }, { 385, 354 }, + { 111, 80 }, { 48, 17 }, { 327, 296 }, { 297, 266 }, + { 205, 174 }, { 384, 384 }, { 236, 205 }, { 357, 326 }, + { 386, 355 }, { 80, 49 }, { 174, 143 }, { 17, 17 }, + { 328, 297 }, { 358, 327 }, { 387, 356 }, { 298, 267 }, + { 329, 298 }, { 388, 357 }, { 112, 81 }, { 416, 385 }, + { 237, 206 }, { 359, 328 }, { 49, 18 }, { 206, 175 }, + { 417, 386 }, { 389, 358 }, { 330, 299 }, { 18, 18 }, + { 416, 416 }, { 360, 329 }, { 81, 50 }, { 418, 387 }, + { 390, 359 }, { 238, 207 }, { 50, 19 }, { 361, 330 }, + { 419, 388 }, { 113, 82 }, { 448, 417 }, { 448, 448 }, + { 420, 389 }, { 82, 51 }, { 362, 331 }, { 449, 418 }, + { 421, 390 }, { 480, 480 }, { 450, 419 }, { 422, 391 }, + { 114, 83 }, { 451, 420 }, { 480, 449 }, { 452, 421 }, + { 481, 450 }, { 453, 422 }, { 512, 512 }, { 482, 451 }, + { 454, 423 }, { 512, 481 }, { 483, 452 }, { 513, 482 }, + { 484, 453 }, { 514, 483 }, { 485, 454 }, { 544, 513 }, + { 544, 544 }, { 486, 455 }, { 545, 514 }, { 546, 515 }, + { 576, 576 }, { 576, 545 }, { 577, 546 }, { 578, 547 }, + { 608, 577 }, { 609, 578 }, { 610, 579 }, { 19, 19 }, + { 143, 112 }, { 267, 236 }, { 391, 360 }, { 515, 484 }, + { 608, 608 }, { 20, 20 }, { 51, 20 }, { 144, 113 }, + { 175, 144 }, { 268, 237 }, { 299, 268 }, { 392, 361 }, + { 423, 392 }, { 516, 485 }, { 547, 516 }, { 640, 609 }, + { 640, 640 }, { 21, 21 }, { 52, 21 }, { 83, 52 }, + { 145, 114 }, { 176, 145 }, { 207, 176 }, { 269, 238 }, + { 300, 269 }, { 331, 300 }, { 393, 362 }, { 424, 393 }, + { 455, 424 }, { 517, 486 }, { 548, 517 }, { 579, 548 }, + { 641, 610 }, { 672, 641 }, { 672, 672 }, { 22, 22 }, + { 53, 22 }, { 84, 53 }, { 115, 84 }, { 146, 115 }, + { 177, 146 }, { 208, 177 }, { 239, 208 }, { 270, 239 }, + { 301, 270 }, { 332, 301 }, { 363, 332 }, { 394, 363 }, + { 425, 394 }, { 456, 425 }, { 487, 456 }, { 518, 487 }, + { 549, 518 }, { 580, 549 }, { 611, 580 }, { 642, 611 }, + { 673, 642 }, { 704, 673 }, { 704, 704 }, { 54, 23 }, + { 85, 54 }, { 116, 85 }, { 178, 147 }, { 209, 178 }, + { 240, 209 }, { 302, 271 }, { 333, 302 }, { 364, 333 }, + { 426, 395 }, { 457, 426 }, { 488, 457 }, { 550, 519 }, + { 581, 550 }, { 612, 581 }, { 674, 643 }, { 705, 674 }, + { 736, 705 }, { 86, 55 }, { 117, 86 }, { 210, 179 }, + { 241, 210 }, { 334, 303 }, { 365, 334 }, { 458, 427 }, + { 489, 458 }, { 582, 551 }, { 613, 582 }, { 706, 675 }, + { 737, 706 }, { 118, 87 }, { 242, 211 }, { 366, 335 }, + { 490, 459 }, { 614, 583 }, { 738, 707 }, { 23, 23 }, + { 147, 116 }, { 271, 240 }, { 395, 364 }, { 519, 488 }, + { 643, 612 }, { 736, 736 }, { 24, 24 }, { 55, 24 }, + { 148, 117 }, { 179, 148 }, { 272, 241 }, { 303, 272 }, + { 396, 365 }, { 427, 396 }, { 520, 489 }, { 551, 520 }, + { 644, 613 }, { 675, 644 }, { 768, 737 }, { 768, 768 }, + { 25, 25 }, { 56, 25 }, { 87, 56 }, { 149, 118 }, + { 180, 149 }, { 211, 180 }, { 273, 242 }, { 304, 273 }, + { 335, 304 }, { 397, 366 }, { 428, 397 }, { 459, 428 }, + { 521, 490 }, { 552, 521 }, { 583, 552 }, { 645, 614 }, + { 676, 645 }, { 707, 676 }, { 769, 738 }, { 800, 769 }, + { 800, 800 }, { 26, 26 }, { 57, 26 }, { 88, 57 }, + { 119, 88 }, { 150, 119 }, { 181, 150 }, { 212, 181 }, + { 243, 212 }, { 274, 243 }, { 305, 274 }, { 336, 305 }, + { 367, 336 }, { 398, 367 }, { 429, 398 }, { 460, 429 }, + { 491, 460 }, { 522, 491 }, { 553, 522 }, { 584, 553 }, + { 615, 584 }, { 646, 615 }, { 677, 646 }, { 708, 677 }, + { 739, 708 }, { 770, 739 }, { 801, 770 }, { 832, 801 }, + { 832, 832 }, { 58, 27 }, { 89, 58 }, { 120, 89 }, + { 182, 151 }, { 213, 182 }, { 244, 213 }, { 306, 275 }, + { 337, 306 }, { 368, 337 }, { 430, 399 }, { 461, 430 }, + { 492, 461 }, { 554, 523 }, { 585, 554 }, { 616, 585 }, + { 678, 647 }, { 709, 678 }, { 740, 709 }, { 802, 771 }, + { 833, 802 }, { 864, 833 }, { 90, 59 }, { 121, 90 }, + { 214, 183 }, { 245, 214 }, { 338, 307 }, { 369, 338 }, + { 462, 431 }, { 493, 462 }, { 586, 555 }, { 617, 586 }, + { 710, 679 }, { 741, 710 }, { 834, 803 }, { 865, 834 }, + { 122, 91 }, { 246, 215 }, { 370, 339 }, { 494, 463 }, + { 618, 587 }, { 742, 711 }, { 866, 835 }, { 27, 27 }, + { 151, 120 }, { 275, 244 }, { 399, 368 }, { 523, 492 }, + { 647, 616 }, { 771, 740 }, { 864, 864 }, { 28, 28 }, + { 59, 28 }, { 152, 121 }, { 183, 152 }, { 276, 245 }, + { 307, 276 }, { 400, 369 }, { 431, 400 }, { 524, 493 }, + { 555, 524 }, { 648, 617 }, { 679, 648 }, { 772, 741 }, + { 803, 772 }, { 896, 865 }, { 896, 896 }, { 29, 29 }, + { 60, 29 }, { 91, 60 }, { 153, 122 }, { 184, 153 }, + { 215, 184 }, { 277, 246 }, { 308, 277 }, { 339, 308 }, + { 401, 370 }, { 432, 401 }, { 463, 432 }, { 525, 494 }, + { 556, 525 }, { 587, 556 }, { 649, 618 }, { 680, 649 }, + { 711, 680 }, { 773, 742 }, { 804, 773 }, { 835, 804 }, + { 897, 866 }, { 928, 897 }, { 928, 928 }, { 30, 30 }, + { 61, 30 }, { 92, 61 }, { 123, 92 }, { 154, 123 }, + { 185, 154 }, { 216, 185 }, { 247, 216 }, { 278, 247 }, + { 309, 278 }, { 340, 309 }, { 371, 340 }, { 402, 371 }, + { 433, 402 }, { 464, 433 }, { 495, 464 }, { 526, 495 }, + { 557, 526 }, { 588, 557 }, { 619, 588 }, { 650, 619 }, + { 681, 650 }, { 712, 681 }, { 743, 712 }, { 774, 743 }, + { 805, 774 }, { 836, 805 }, { 867, 836 }, { 898, 867 }, + { 929, 898 }, { 960, 929 }, { 960, 960 }, { 62, 31 }, + { 93, 62 }, { 124, 93 }, { 186, 155 }, { 217, 186 }, + { 248, 217 }, { 310, 279 }, { 341, 310 }, { 372, 341 }, + { 434, 403 }, { 465, 434 }, { 496, 465 }, { 558, 527 }, + { 589, 558 }, { 620, 589 }, { 682, 651 }, { 713, 682 }, + { 744, 713 }, { 806, 775 }, { 837, 806 }, { 868, 837 }, + { 930, 899 }, { 961, 930 }, { 992, 961 }, { 94, 63 }, + { 125, 94 }, { 218, 187 }, { 249, 218 }, { 342, 311 }, + { 373, 342 }, { 466, 435 }, { 497, 466 }, { 590, 559 }, + { 621, 590 }, { 714, 683 }, { 745, 714 }, { 838, 807 }, + { 869, 838 }, { 962, 931 }, { 993, 962 }, { 126, 95 }, + { 250, 219 }, { 374, 343 }, { 498, 467 }, { 622, 591 }, + { 746, 715 }, { 870, 839 }, { 994, 963 }, { 155, 124 }, + { 279, 248 }, { 403, 372 }, { 527, 496 }, { 651, 620 }, + { 775, 744 }, { 899, 868 }, { 156, 125 }, { 187, 156 }, + { 280, 249 }, { 311, 280 }, { 404, 373 }, { 435, 404 }, + { 528, 497 }, { 559, 528 }, { 652, 621 }, { 683, 652 }, + { 776, 745 }, { 807, 776 }, { 900, 869 }, { 931, 900 }, + { 157, 126 }, { 188, 157 }, { 219, 188 }, { 281, 250 }, + { 312, 281 }, { 343, 312 }, { 405, 374 }, { 436, 405 }, + { 467, 436 }, { 529, 498 }, { 560, 529 }, { 591, 560 }, + { 653, 622 }, { 684, 653 }, { 715, 684 }, { 777, 746 }, + { 808, 777 }, { 839, 808 }, { 901, 870 }, { 932, 901 }, + { 963, 932 }, { 158, 127 }, { 189, 158 }, { 220, 189 }, + { 251, 220 }, { 282, 251 }, { 313, 282 }, { 344, 313 }, + { 375, 344 }, { 406, 375 }, { 437, 406 }, { 468, 437 }, + { 499, 468 }, { 530, 499 }, { 561, 530 }, { 592, 561 }, + { 623, 592 }, { 654, 623 }, { 685, 654 }, { 716, 685 }, + { 747, 716 }, { 778, 747 }, { 809, 778 }, { 840, 809 }, + { 871, 840 }, { 902, 871 }, { 933, 902 }, { 964, 933 }, + { 995, 964 }, { 190, 159 }, { 221, 190 }, { 252, 221 }, + { 314, 283 }, { 345, 314 }, { 376, 345 }, { 438, 407 }, + { 469, 438 }, { 500, 469 }, { 562, 531 }, { 593, 562 }, + { 624, 593 }, { 686, 655 }, { 717, 686 }, { 748, 717 }, + { 810, 779 }, { 841, 810 }, { 872, 841 }, { 934, 903 }, + { 965, 934 }, { 996, 965 }, { 222, 191 }, { 253, 222 }, + { 346, 315 }, { 377, 346 }, { 470, 439 }, { 501, 470 }, + { 594, 563 }, { 625, 594 }, { 718, 687 }, { 749, 718 }, + { 842, 811 }, { 873, 842 }, { 966, 935 }, { 997, 966 }, + { 254, 223 }, { 378, 347 }, { 502, 471 }, { 626, 595 }, + { 750, 719 }, { 874, 843 }, { 998, 967 }, { 283, 252 }, + { 407, 376 }, { 531, 500 }, { 655, 624 }, { 779, 748 }, + { 903, 872 }, { 284, 253 }, { 315, 284 }, { 408, 377 }, + { 439, 408 }, { 532, 501 }, { 563, 532 }, { 656, 625 }, + { 687, 656 }, { 780, 749 }, { 811, 780 }, { 904, 873 }, + { 935, 904 }, { 285, 254 }, { 316, 285 }, { 347, 316 }, + { 409, 378 }, { 440, 409 }, { 471, 440 }, { 533, 502 }, + { 564, 533 }, { 595, 564 }, { 657, 626 }, { 688, 657 }, + { 719, 688 }, { 781, 750 }, { 812, 781 }, { 843, 812 }, + { 905, 874 }, { 936, 905 }, { 967, 936 }, { 286, 255 }, + { 317, 286 }, { 348, 317 }, { 379, 348 }, { 410, 379 }, + { 441, 410 }, { 472, 441 }, { 503, 472 }, { 534, 503 }, + { 565, 534 }, { 596, 565 }, { 627, 596 }, { 658, 627 }, + { 689, 658 }, { 720, 689 }, { 751, 720 }, { 782, 751 }, + { 813, 782 }, { 844, 813 }, { 875, 844 }, { 906, 875 }, + { 937, 906 }, { 968, 937 }, { 999, 968 }, { 318, 287 }, + { 349, 318 }, { 380, 349 }, { 442, 411 }, { 473, 442 }, + { 504, 473 }, { 566, 535 }, { 597, 566 }, { 628, 597 }, + { 690, 659 }, { 721, 690 }, { 752, 721 }, { 814, 783 }, + { 845, 814 }, { 876, 845 }, { 938, 907 }, { 969, 938 }, + { 1000, 969 }, { 350, 319 }, { 381, 350 }, { 474, 443 }, + { 505, 474 }, { 598, 567 }, { 629, 598 }, { 722, 691 }, + { 753, 722 }, { 846, 815 }, { 877, 846 }, { 970, 939 }, + { 1001, 970 }, { 382, 351 }, { 506, 475 }, { 630, 599 }, + { 754, 723 }, { 878, 847 }, { 1002, 971 }, { 411, 380 }, + { 535, 504 }, { 659, 628 }, { 783, 752 }, { 907, 876 }, + { 412, 381 }, { 443, 412 }, { 536, 505 }, { 567, 536 }, + { 660, 629 }, { 691, 660 }, { 784, 753 }, { 815, 784 }, + { 908, 877 }, { 939, 908 }, { 413, 382 }, { 444, 413 }, + { 475, 444 }, { 537, 506 }, { 568, 537 }, { 599, 568 }, + { 661, 630 }, { 692, 661 }, { 723, 692 }, { 785, 754 }, + { 816, 785 }, { 847, 816 }, { 909, 878 }, { 940, 909 }, + { 971, 940 }, { 414, 383 }, { 445, 414 }, { 476, 445 }, + { 507, 476 }, { 538, 507 }, { 569, 538 }, { 600, 569 }, + { 631, 600 }, { 662, 631 }, { 693, 662 }, { 724, 693 }, + { 755, 724 }, { 786, 755 }, { 817, 786 }, { 848, 817 }, + { 879, 848 }, { 910, 879 }, { 941, 910 }, { 972, 941 }, + { 1003, 972 }, { 446, 415 }, { 477, 446 }, { 508, 477 }, + { 570, 539 }, { 601, 570 }, { 632, 601 }, { 694, 663 }, + { 725, 694 }, { 756, 725 }, { 818, 787 }, { 849, 818 }, + { 880, 849 }, { 942, 911 }, { 973, 942 }, { 1004, 973 }, + { 478, 447 }, { 509, 478 }, { 602, 571 }, { 633, 602 }, + { 726, 695 }, { 757, 726 }, { 850, 819 }, { 881, 850 }, + { 974, 943 }, { 1005, 974 }, { 510, 479 }, { 634, 603 }, + { 758, 727 }, { 882, 851 }, { 1006, 975 }, { 539, 508 }, + { 663, 632 }, { 787, 756 }, { 911, 880 }, { 540, 509 }, + { 571, 540 }, { 664, 633 }, { 695, 664 }, { 788, 757 }, + { 819, 788 }, { 912, 881 }, { 943, 912 }, { 541, 510 }, + { 572, 541 }, { 603, 572 }, { 665, 634 }, { 696, 665 }, + { 727, 696 }, { 789, 758 }, { 820, 789 }, { 851, 820 }, + { 913, 882 }, { 944, 913 }, { 975, 944 }, { 542, 511 }, + { 573, 542 }, { 604, 573 }, { 635, 604 }, { 666, 635 }, + { 697, 666 }, { 728, 697 }, { 759, 728 }, { 790, 759 }, + { 821, 790 }, { 852, 821 }, { 883, 852 }, { 914, 883 }, + { 945, 914 }, { 976, 945 }, { 1007, 976 }, { 574, 543 }, + { 605, 574 }, { 636, 605 }, { 698, 667 }, { 729, 698 }, + { 760, 729 }, { 822, 791 }, { 853, 822 }, { 884, 853 }, + { 946, 915 }, { 977, 946 }, { 1008, 977 }, { 606, 575 }, + { 637, 606 }, { 730, 699 }, { 761, 730 }, { 854, 823 }, + { 885, 854 }, { 978, 947 }, { 1009, 978 }, { 638, 607 }, + { 762, 731 }, { 886, 855 }, { 1010, 979 }, { 667, 636 }, + { 791, 760 }, { 915, 884 }, { 668, 637 }, { 699, 668 }, + { 792, 761 }, { 823, 792 }, { 916, 885 }, { 947, 916 }, + { 669, 638 }, { 700, 669 }, { 731, 700 }, { 793, 762 }, + { 824, 793 }, { 855, 824 }, { 917, 886 }, { 948, 917 }, + { 979, 948 }, { 670, 639 }, { 701, 670 }, { 732, 701 }, + { 763, 732 }, { 794, 763 }, { 825, 794 }, { 856, 825 }, + { 887, 856 }, { 918, 887 }, { 949, 918 }, { 980, 949 }, + { 1011, 980 }, { 702, 671 }, { 733, 702 }, { 764, 733 }, + { 826, 795 }, { 857, 826 }, { 888, 857 }, { 950, 919 }, + { 981, 950 }, { 1012, 981 }, { 734, 703 }, { 765, 734 }, + { 858, 827 }, { 889, 858 }, { 982, 951 }, { 1013, 982 }, + { 766, 735 }, { 890, 859 }, { 1014, 983 }, { 795, 764 }, + { 919, 888 }, { 796, 765 }, { 827, 796 }, { 920, 889 }, + { 951, 920 }, { 797, 766 }, { 828, 797 }, { 859, 828 }, + { 921, 890 }, { 952, 921 }, { 983, 952 }, { 798, 767 }, + { 829, 798 }, { 860, 829 }, { 891, 860 }, { 922, 891 }, + { 953, 922 }, { 984, 953 }, { 1015, 984 }, { 830, 799 }, + { 861, 830 }, { 892, 861 }, { 954, 923 }, { 985, 954 }, + { 1016, 985 }, { 862, 831 }, { 893, 862 }, { 986, 955 }, + { 1017, 986 }, { 894, 863 }, { 1018, 987 }, { 923, 892 }, + { 924, 893 }, { 955, 924 }, { 925, 894 }, { 956, 925 }, + { 987, 956 }, { 926, 895 }, { 957, 926 }, { 988, 957 }, + { 1019, 988 }, { 958, 927 }, { 989, 958 }, { 1020, 989 }, + { 990, 959 }, { 1021, 990 }, { 1022, 991 }, { 0, 0 }, +}; + +const int16_t (* const ff_vp9_scans_nb[5][4])[2] = { + { + ff_vp9_default_scan_4x4_nb, ff_vp9_col_scan_4x4_nb, + ff_vp9_row_scan_4x4_nb, ff_vp9_default_scan_4x4_nb + }, { + ff_vp9_default_scan_8x8_nb, ff_vp9_col_scan_8x8_nb, + ff_vp9_row_scan_8x8_nb, ff_vp9_default_scan_8x8_nb + }, { + ff_vp9_default_scan_16x16_nb, ff_vp9_col_scan_16x16_nb, + ff_vp9_row_scan_16x16_nb, ff_vp9_default_scan_16x16_nb + }, { + ff_vp9_default_scan_32x32_nb, ff_vp9_default_scan_32x32_nb, + ff_vp9_default_scan_32x32_nb, ff_vp9_default_scan_32x32_nb + }, { // lossless + ff_vp9_default_scan_4x4_nb, ff_vp9_default_scan_4x4_nb, + ff_vp9_default_scan_4x4_nb, ff_vp9_default_scan_4x4_nb + } +}; + +const uint8_t ff_vp9_model_pareto8[256][8] = { + { 6, 86, 128, 11, 87, 42, 91, 52 }, + { 3, 86, 128, 6, 86, 23, 88, 29 }, + { 6, 86, 128, 11, 87, 42, 91, 52 }, + { 9, 86, 129, 17, 88, 61, 94, 76 }, + { 12, 86, 129, 22, 88, 77, 97, 93 }, + { 15, 87, 129, 28, 89, 93, 100, 110 }, + { 17, 87, 129, 33, 90, 105, 103, 123 }, + { 20, 88, 130, 38, 91, 118, 106, 136 }, + { 23, 88, 130, 43, 91, 128, 108, 146 }, + { 26, 89, 131, 48, 92, 139, 111, 156 }, + { 28, 89, 131, 53, 93, 147, 114, 163 }, + { 31, 90, 131, 58, 94, 156, 117, 171 }, + { 34, 90, 131, 62, 94, 163, 119, 177 }, + { 37, 90, 132, 66, 95, 171, 122, 184 }, + { 39, 90, 132, 70, 96, 177, 124, 189 }, + { 42, 91, 132, 75, 97, 183, 127, 194 }, + { 44, 91, 132, 79, 97, 188, 129, 198 }, + { 47, 92, 133, 83, 98, 193, 132, 202 }, + { 49, 92, 133, 86, 99, 197, 134, 205 }, + { 52, 93, 133, 90, 100, 201, 137, 208 }, + { 54, 93, 133, 94, 100, 204, 139, 211 }, + { 57, 94, 134, 98, 101, 208, 142, 214 }, + { 59, 94, 134, 101, 102, 211, 144, 216 }, + { 62, 94, 135, 105, 103, 214, 146, 218 }, + { 64, 94, 135, 108, 103, 216, 148, 220 }, + { 66, 95, 135, 111, 104, 219, 151, 222 }, + { 68, 95, 135, 114, 105, 221, 153, 223 }, + { 71, 96, 136, 117, 106, 224, 155, 225 }, + { 73, 96, 136, 120, 106, 225, 157, 226 }, + { 76, 97, 136, 123, 107, 227, 159, 228 }, + { 78, 97, 136, 126, 108, 229, 160, 229 }, + { 80, 98, 137, 129, 109, 231, 162, 231 }, + { 82, 98, 137, 131, 109, 232, 164, 232 }, + { 84, 98, 138, 134, 110, 234, 166, 233 }, + { 86, 98, 138, 137, 111, 235, 168, 234 }, + { 89, 99, 138, 140, 112, 236, 170, 235 }, + { 91, 99, 138, 142, 112, 237, 171, 235 }, + { 93, 100, 139, 145, 113, 238, 173, 236 }, + { 95, 100, 139, 147, 114, 239, 174, 237 }, + { 97, 101, 140, 149, 115, 240, 176, 238 }, + { 99, 101, 140, 151, 115, 241, 177, 238 }, + { 101, 102, 140, 154, 116, 242, 179, 239 }, + { 103, 102, 140, 156, 117, 242, 180, 239 }, + { 105, 103, 141, 158, 118, 243, 182, 240 }, + { 107, 103, 141, 160, 118, 243, 183, 240 }, + { 109, 104, 141, 162, 119, 244, 185, 241 }, + { 111, 104, 141, 164, 119, 244, 186, 241 }, + { 113, 104, 142, 166, 120, 245, 187, 242 }, + { 114, 104, 142, 168, 121, 245, 188, 242 }, + { 116, 105, 143, 170, 122, 246, 190, 243 }, + { 118, 105, 143, 171, 122, 246, 191, 243 }, + { 120, 106, 143, 173, 123, 247, 192, 244 }, + { 121, 106, 143, 175, 124, 247, 193, 244 }, + { 123, 107, 144, 177, 125, 248, 195, 244 }, + { 125, 107, 144, 178, 125, 248, 196, 244 }, + { 127, 108, 145, 180, 126, 249, 197, 245 }, + { 128, 108, 145, 181, 127, 249, 198, 245 }, + { 130, 109, 145, 183, 128, 249, 199, 245 }, + { 132, 109, 145, 184, 128, 249, 200, 245 }, + { 134, 110, 146, 186, 129, 250, 201, 246 }, + { 135, 110, 146, 187, 130, 250, 202, 246 }, + { 137, 111, 147, 189, 131, 251, 203, 246 }, + { 138, 111, 147, 190, 131, 251, 204, 246 }, + { 140, 112, 147, 192, 132, 251, 205, 247 }, + { 141, 112, 147, 193, 132, 251, 206, 247 }, + { 143, 113, 148, 194, 133, 251, 207, 247 }, + { 144, 113, 148, 195, 134, 251, 207, 247 }, + { 146, 114, 149, 197, 135, 252, 208, 248 }, + { 147, 114, 149, 198, 135, 252, 209, 248 }, + { 149, 115, 149, 199, 136, 252, 210, 248 }, + { 150, 115, 149, 200, 137, 252, 210, 248 }, + { 152, 115, 150, 201, 138, 252, 211, 248 }, + { 153, 115, 150, 202, 138, 252, 212, 248 }, + { 155, 116, 151, 204, 139, 253, 213, 249 }, + { 156, 116, 151, 205, 139, 253, 213, 249 }, + { 158, 117, 151, 206, 140, 253, 214, 249 }, + { 159, 117, 151, 207, 141, 253, 215, 249 }, + { 161, 118, 152, 208, 142, 253, 216, 249 }, + { 162, 118, 152, 209, 142, 253, 216, 249 }, + { 163, 119, 153, 210, 143, 253, 217, 249 }, + { 164, 119, 153, 211, 143, 253, 217, 249 }, + { 166, 120, 153, 212, 144, 254, 218, 250 }, + { 167, 120, 153, 212, 145, 254, 219, 250 }, + { 168, 121, 154, 213, 146, 254, 220, 250 }, + { 169, 121, 154, 214, 146, 254, 220, 250 }, + { 171, 122, 155, 215, 147, 254, 221, 250 }, + { 172, 122, 155, 216, 147, 254, 221, 250 }, + { 173, 123, 155, 217, 148, 254, 222, 250 }, + { 174, 123, 155, 217, 149, 254, 222, 250 }, + { 176, 124, 156, 218, 150, 254, 223, 250 }, + { 177, 124, 156, 219, 150, 254, 223, 250 }, + { 178, 125, 157, 220, 151, 254, 224, 251 }, + { 179, 125, 157, 220, 151, 254, 224, 251 }, + { 180, 126, 157, 221, 152, 254, 225, 251 }, + { 181, 126, 157, 221, 152, 254, 225, 251 }, + { 183, 127, 158, 222, 153, 254, 226, 251 }, + { 184, 127, 158, 223, 154, 254, 226, 251 }, + { 185, 128, 159, 224, 155, 255, 227, 251 }, + { 186, 128, 159, 224, 155, 255, 227, 251 }, + { 187, 129, 160, 225, 156, 255, 228, 251 }, + { 188, 130, 160, 225, 156, 255, 228, 251 }, + { 189, 131, 160, 226, 157, 255, 228, 251 }, + { 190, 131, 160, 226, 158, 255, 228, 251 }, + { 191, 132, 161, 227, 159, 255, 229, 251 }, + { 192, 132, 161, 227, 159, 255, 229, 251 }, + { 193, 133, 162, 228, 160, 255, 230, 252 }, + { 194, 133, 162, 229, 160, 255, 230, 252 }, + { 195, 134, 163, 230, 161, 255, 231, 252 }, + { 196, 134, 163, 230, 161, 255, 231, 252 }, + { 197, 135, 163, 231, 162, 255, 231, 252 }, + { 198, 135, 163, 231, 162, 255, 231, 252 }, + { 199, 136, 164, 232, 163, 255, 232, 252 }, + { 200, 136, 164, 232, 164, 255, 232, 252 }, + { 201, 137, 165, 233, 165, 255, 233, 252 }, + { 201, 137, 165, 233, 165, 255, 233, 252 }, + { 202, 138, 166, 233, 166, 255, 233, 252 }, + { 203, 138, 166, 233, 166, 255, 233, 252 }, + { 204, 139, 166, 234, 167, 255, 234, 252 }, + { 205, 139, 166, 234, 167, 255, 234, 252 }, + { 206, 140, 167, 235, 168, 255, 235, 252 }, + { 206, 140, 167, 235, 168, 255, 235, 252 }, + { 207, 141, 168, 236, 169, 255, 235, 252 }, + { 208, 141, 168, 236, 170, 255, 235, 252 }, + { 209, 142, 169, 237, 171, 255, 236, 252 }, + { 209, 143, 169, 237, 171, 255, 236, 252 }, + { 210, 144, 169, 237, 172, 255, 236, 252 }, + { 211, 144, 169, 237, 172, 255, 236, 252 }, + { 212, 145, 170, 238, 173, 255, 237, 252 }, + { 213, 145, 170, 238, 173, 255, 237, 252 }, + { 214, 146, 171, 239, 174, 255, 237, 253 }, + { 214, 146, 171, 239, 174, 255, 237, 253 }, + { 215, 147, 172, 240, 175, 255, 238, 253 }, + { 215, 147, 172, 240, 175, 255, 238, 253 }, + { 216, 148, 173, 240, 176, 255, 238, 253 }, + { 217, 148, 173, 240, 176, 255, 238, 253 }, + { 218, 149, 173, 241, 177, 255, 239, 253 }, + { 218, 149, 173, 241, 178, 255, 239, 253 }, + { 219, 150, 174, 241, 179, 255, 239, 253 }, + { 219, 151, 174, 241, 179, 255, 239, 253 }, + { 220, 152, 175, 242, 180, 255, 240, 253 }, + { 221, 152, 175, 242, 180, 255, 240, 253 }, + { 222, 153, 176, 242, 181, 255, 240, 253 }, + { 222, 153, 176, 242, 181, 255, 240, 253 }, + { 223, 154, 177, 243, 182, 255, 240, 253 }, + { 223, 154, 177, 243, 182, 255, 240, 253 }, + { 224, 155, 178, 244, 183, 255, 241, 253 }, + { 224, 155, 178, 244, 183, 255, 241, 253 }, + { 225, 156, 178, 244, 184, 255, 241, 253 }, + { 225, 157, 178, 244, 184, 255, 241, 253 }, + { 226, 158, 179, 244, 185, 255, 242, 253 }, + { 227, 158, 179, 244, 185, 255, 242, 253 }, + { 228, 159, 180, 245, 186, 255, 242, 253 }, + { 228, 159, 180, 245, 186, 255, 242, 253 }, + { 229, 160, 181, 245, 187, 255, 242, 253 }, + { 229, 160, 181, 245, 187, 255, 242, 253 }, + { 230, 161, 182, 246, 188, 255, 243, 253 }, + { 230, 162, 182, 246, 188, 255, 243, 253 }, + { 231, 163, 183, 246, 189, 255, 243, 253 }, + { 231, 163, 183, 246, 189, 255, 243, 253 }, + { 232, 164, 184, 247, 190, 255, 243, 253 }, + { 232, 164, 184, 247, 190, 255, 243, 253 }, + { 233, 165, 185, 247, 191, 255, 244, 253 }, + { 233, 165, 185, 247, 191, 255, 244, 253 }, + { 234, 166, 185, 247, 192, 255, 244, 253 }, + { 234, 167, 185, 247, 192, 255, 244, 253 }, + { 235, 168, 186, 248, 193, 255, 244, 253 }, + { 235, 168, 186, 248, 193, 255, 244, 253 }, + { 236, 169, 187, 248, 194, 255, 244, 253 }, + { 236, 169, 187, 248, 194, 255, 244, 253 }, + { 236, 170, 188, 248, 195, 255, 245, 253 }, + { 236, 170, 188, 248, 195, 255, 245, 253 }, + { 237, 171, 189, 249, 196, 255, 245, 254 }, + { 237, 172, 189, 249, 196, 255, 245, 254 }, + { 238, 173, 190, 249, 197, 255, 245, 254 }, + { 238, 173, 190, 249, 197, 255, 245, 254 }, + { 239, 174, 191, 249, 198, 255, 245, 254 }, + { 239, 174, 191, 249, 198, 255, 245, 254 }, + { 240, 175, 192, 249, 199, 255, 246, 254 }, + { 240, 176, 192, 249, 199, 255, 246, 254 }, + { 240, 177, 193, 250, 200, 255, 246, 254 }, + { 240, 177, 193, 250, 200, 255, 246, 254 }, + { 241, 178, 194, 250, 201, 255, 246, 254 }, + { 241, 178, 194, 250, 201, 255, 246, 254 }, + { 242, 179, 195, 250, 202, 255, 246, 254 }, + { 242, 180, 195, 250, 202, 255, 246, 254 }, + { 242, 181, 196, 250, 203, 255, 247, 254 }, + { 242, 181, 196, 250, 203, 255, 247, 254 }, + { 243, 182, 197, 251, 204, 255, 247, 254 }, + { 243, 183, 197, 251, 204, 255, 247, 254 }, + { 244, 184, 198, 251, 205, 255, 247, 254 }, + { 244, 184, 198, 251, 205, 255, 247, 254 }, + { 244, 185, 199, 251, 206, 255, 247, 254 }, + { 244, 185, 199, 251, 206, 255, 247, 254 }, + { 245, 186, 200, 251, 207, 255, 247, 254 }, + { 245, 187, 200, 251, 207, 255, 247, 254 }, + { 246, 188, 201, 252, 207, 255, 248, 254 }, + { 246, 188, 201, 252, 207, 255, 248, 254 }, + { 246, 189, 202, 252, 208, 255, 248, 254 }, + { 246, 190, 202, 252, 208, 255, 248, 254 }, + { 247, 191, 203, 252, 209, 255, 248, 254 }, + { 247, 191, 203, 252, 209, 255, 248, 254 }, + { 247, 192, 204, 252, 210, 255, 248, 254 }, + { 247, 193, 204, 252, 210, 255, 248, 254 }, + { 248, 194, 205, 252, 211, 255, 248, 254 }, + { 248, 194, 205, 252, 211, 255, 248, 254 }, + { 248, 195, 206, 252, 212, 255, 249, 254 }, + { 248, 196, 206, 252, 212, 255, 249, 254 }, + { 249, 197, 207, 253, 213, 255, 249, 254 }, + { 249, 197, 207, 253, 213, 255, 249, 254 }, + { 249, 198, 208, 253, 214, 255, 249, 254 }, + { 249, 199, 209, 253, 214, 255, 249, 254 }, + { 250, 200, 210, 253, 215, 255, 249, 254 }, + { 250, 200, 210, 253, 215, 255, 249, 254 }, + { 250, 201, 211, 253, 215, 255, 249, 254 }, + { 250, 202, 211, 253, 215, 255, 249, 254 }, + { 250, 203, 212, 253, 216, 255, 249, 254 }, + { 250, 203, 212, 253, 216, 255, 249, 254 }, + { 251, 204, 213, 253, 217, 255, 250, 254 }, + { 251, 205, 213, 253, 217, 255, 250, 254 }, + { 251, 206, 214, 254, 218, 255, 250, 254 }, + { 251, 206, 215, 254, 218, 255, 250, 254 }, + { 252, 207, 216, 254, 219, 255, 250, 254 }, + { 252, 208, 216, 254, 219, 255, 250, 254 }, + { 252, 209, 217, 254, 220, 255, 250, 254 }, + { 252, 210, 217, 254, 220, 255, 250, 254 }, + { 252, 211, 218, 254, 221, 255, 250, 254 }, + { 252, 212, 218, 254, 221, 255, 250, 254 }, + { 253, 213, 219, 254, 222, 255, 250, 254 }, + { 253, 213, 220, 254, 222, 255, 250, 254 }, + { 253, 214, 221, 254, 223, 255, 250, 254 }, + { 253, 215, 221, 254, 223, 255, 250, 254 }, + { 253, 216, 222, 254, 224, 255, 251, 254 }, + { 253, 217, 223, 254, 224, 255, 251, 254 }, + { 253, 218, 224, 254, 225, 255, 251, 254 }, + { 253, 219, 224, 254, 225, 255, 251, 254 }, + { 254, 220, 225, 254, 225, 255, 251, 254 }, + { 254, 221, 226, 254, 225, 255, 251, 254 }, + { 254, 222, 227, 255, 226, 255, 251, 254 }, + { 254, 223, 227, 255, 226, 255, 251, 254 }, + { 254, 224, 228, 255, 227, 255, 251, 254 }, + { 254, 225, 229, 255, 227, 255, 251, 254 }, + { 254, 226, 230, 255, 228, 255, 251, 254 }, + { 254, 227, 230, 255, 229, 255, 251, 254 }, + { 255, 228, 231, 255, 230, 255, 251, 254 }, + { 255, 229, 232, 255, 230, 255, 251, 254 }, + { 255, 230, 233, 255, 231, 255, 252, 254 }, + { 255, 231, 234, 255, 231, 255, 252, 254 }, + { 255, 232, 235, 255, 232, 255, 252, 254 }, + { 255, 233, 236, 255, 232, 255, 252, 254 }, + { 255, 235, 237, 255, 233, 255, 252, 254 }, + { 255, 236, 238, 255, 234, 255, 252, 254 }, + { 255, 238, 240, 255, 235, 255, 252, 255 }, + { 255, 239, 241, 255, 235, 255, 252, 254 }, + { 255, 241, 243, 255, 236, 255, 252, 254 }, + { 255, 243, 245, 255, 237, 255, 252, 254 }, + { 255, 246, 247, 255, 239, 255, 253, 255 }, +}; + +const ProbContext ff_vp9_default_probs = { + { /* y_mode */ + { 65, 32, 18, 144, 162, 194, 41, 51, 98 } /* bsize < 8x8 */, + { 132, 68, 18, 165, 217, 196, 45, 40, 78 } /* bsize < 16x16 */, + { 173, 80, 19, 176, 240, 193, 64, 35, 46 } /* bsize < 32x32 */, + { 221, 135, 38, 194, 248, 121, 96, 85, 29 } /* bsize >= 32x32 */ + }, { /* uv_mode */ + { 48, 12, 154, 155, 139, 90, 34, 117, 119 } /* y = v */, + { 67, 6, 25, 204, 243, 158, 13, 21, 96 } /* y = h */, + { 120, 7, 76, 176, 208, 126, 28, 54, 103 } /* y = dc */, + { 97, 5, 44, 131, 176, 139, 48, 68, 97 } /* y = d45 */, + { 83, 5, 42, 156, 111, 152, 26, 49, 152 } /* y = d135 */, + { 80, 5, 58, 178, 74, 83, 33, 62, 145 } /* y = d117 */, + { 86, 5, 32, 154, 192, 168, 14, 22, 163 } /* y = d153 */, + { 77, 7, 64, 116, 132, 122, 37, 126, 120 } /* y = d63 */, + { 85, 5, 32, 156, 216, 148, 19, 29, 73 } /* y = d27 */, + { 101, 21, 107, 181, 192, 103, 19, 67, 125 } /* y = tm */ + }, { /* filter */ + { 235, 162, }, + { 36, 255, }, + { 34, 3, }, + { 149, 144, }, + }, { /* mv_mode */ + { 2, 173, 34 }, // 0 = both zero mv + { 7, 145, 85 }, // 1 = one zero mv + one a predicted mv + { 7, 166, 63 }, // 2 = two predicted mvs + { 7, 94, 66 }, // 3 = one predicted/zero and one new mv + { 8, 64, 46 }, // 4 = two new mvs + { 17, 81, 31 }, // 5 = one intra neighbor + x + { 25, 29, 30 }, // 6 = two intra neighbors + }, { /* intra */ + 9, 102, 187, 225 + }, { /* comp */ + 239, 183, 119, 96, 41 + }, { /* single_ref */ + { 33, 16 }, + { 77, 74 }, + { 142, 142 }, + { 172, 170 }, + { 238, 247 } + }, { /* comp_ref */ + 50, 126, 123, 221, 226 + }, { /* tx32p */ + { 3, 136, 37, }, + { 5, 52, 13, }, + }, { /* tx16p */ + { 20, 152, }, + { 15, 101, }, + }, { /* tx8p */ + 100, 66 + }, { /* skip */ + 192, 128, 64 + }, { /* mv_joint */ + 32, 64, 96 + }, { + { /* mv vertical component */ + 128, /* sign */ + { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, /* class */ + 216, /* class0 */ + { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ + { /* class0_fp */ + { 128, 128, 64 }, + { 96, 112, 64 } + }, + { 64, 96, 64 }, /* fp */ + 160, /* class0_hp bit */ + 128, /* hp */ + }, { /* mv horizontal component */ + 128, /* sign */ + { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, /* class */ + 208, /* class0 */ + { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ + { /* class0_fp */ + { 128, 128, 64 }, + { 96, 112, 64 } + }, + { 64, 96, 64 }, /* fp */ + 160, /* class0_hp bit */ + 128, /* hp */ + } + }, { /* partition */ + { /* 64x64 -> 32x32 */ + { 222, 34, 30 } /* a/l both not split */, + { 72, 16, 44 } /* a split, l not split */, + { 58, 32, 12 } /* l split, a not split */, + { 10, 7, 6 } /* a/l both split */, + }, { /* 32x32 -> 16x16 */ + { 177, 58, 59 } /* a/l both not split */, + { 68, 26, 63 } /* a split, l not split */, + { 52, 79, 25 } /* l split, a not split */, + { 17, 14, 12 } /* a/l both split */, + }, { /* 16x16 -> 8x8 */ + { 174, 73, 87 } /* a/l both not split */, + { 92, 41, 83 } /* a split, l not split */, + { 82, 99, 50 } /* l split, a not split */, + { 53, 39, 39 } /* a/l both split */, + }, { /* 8x8 -> 4x4 */ + { 199, 122, 141 } /* a/l both not split */, + { 147, 63, 159 } /* a split, l not split */, + { 148, 133, 118 } /* l split, a not split */, + { 121, 104, 114 } /* a/l both split */, + } + }, +}; + +const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3] = { + { /* tx = 4x4 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 195, 29, 183 }, + { 84, 49, 136 }, + { 8, 42, 71 } + }, { /* Coeff Band 1 */ + { 31, 107, 169 }, + { 35, 99, 159 }, + { 17, 82, 140 }, + { 8, 66, 114 }, + { 2, 44, 76 }, + { 1, 19, 32 } + }, { /* Coeff Band 2 */ + { 40, 132, 201 }, + { 29, 114, 187 }, + { 13, 91, 157 }, + { 7, 75, 127 }, + { 3, 58, 95 }, + { 1, 28, 47 } + }, { /* Coeff Band 3 */ + { 69, 142, 221 }, + { 42, 122, 201 }, + { 15, 91, 159 }, + { 6, 67, 121 }, + { 1, 42, 77 }, + { 1, 17, 31 } + }, { /* Coeff Band 4 */ + { 102, 148, 228 }, + { 67, 117, 204 }, + { 17, 82, 154 }, + { 6, 59, 114 }, + { 2, 39, 75 }, + { 1, 15, 29 } + }, { /* Coeff Band 5 */ + { 156, 57, 233 }, + { 119, 57, 212 }, + { 58, 48, 163 }, + { 29, 40, 124 }, + { 12, 30, 81 }, + { 3, 12, 31 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 191, 107, 226 }, + { 124, 117, 204 }, + { 25, 99, 155 } + }, { /* Coeff Band 1 */ + { 29, 148, 210 }, + { 37, 126, 194 }, + { 8, 93, 157 }, + { 2, 68, 118 }, + { 1, 39, 69 }, + { 1, 17, 33 } + }, { /* Coeff Band 2 */ + { 41, 151, 213 }, + { 27, 123, 193 }, + { 3, 82, 144 }, + { 1, 58, 105 }, + { 1, 32, 60 }, + { 1, 13, 26 } + }, { /* Coeff Band 3 */ + { 59, 159, 220 }, + { 23, 126, 198 }, + { 4, 88, 151 }, + { 1, 66, 114 }, + { 1, 38, 71 }, + { 1, 18, 34 } + }, { /* Coeff Band 4 */ + { 114, 136, 232 }, + { 51, 114, 207 }, + { 11, 83, 155 }, + { 3, 56, 105 }, + { 1, 33, 65 }, + { 1, 17, 34 } + }, { /* Coeff Band 5 */ + { 149, 65, 234 }, + { 121, 57, 215 }, + { 61, 49, 166 }, + { 28, 36, 114 }, + { 12, 25, 76 }, + { 3, 16, 42 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 214, 49, 220 }, + { 132, 63, 188 }, + { 42, 65, 137 } + }, { /* Coeff Band 1 */ + { 85, 137, 221 }, + { 104, 131, 216 }, + { 49, 111, 192 }, + { 21, 87, 155 }, + { 2, 49, 87 }, + { 1, 16, 28 } + }, { /* Coeff Band 2 */ + { 89, 163, 230 }, + { 90, 137, 220 }, + { 29, 100, 183 }, + { 10, 70, 135 }, + { 2, 42, 81 }, + { 1, 17, 33 } + }, { /* Coeff Band 3 */ + { 108, 167, 237 }, + { 55, 133, 222 }, + { 15, 97, 179 }, + { 4, 72, 135 }, + { 1, 45, 85 }, + { 1, 19, 38 } + }, { /* Coeff Band 4 */ + { 124, 146, 240 }, + { 66, 124, 224 }, + { 17, 88, 175 }, + { 4, 58, 122 }, + { 1, 36, 75 }, + { 1, 18, 37 } + }, { /* Coeff Band 5 */ + { 141, 79, 241 }, + { 126, 70, 227 }, + { 66, 58, 182 }, + { 30, 44, 136 }, + { 12, 34, 96 }, + { 2, 20, 47 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 229, 99, 249 }, + { 143, 111, 235 }, + { 46, 109, 192 } + }, { /* Coeff Band 1 */ + { 82, 158, 236 }, + { 94, 146, 224 }, + { 25, 117, 191 }, + { 9, 87, 149 }, + { 3, 56, 99 }, + { 1, 33, 57 } + }, { /* Coeff Band 2 */ + { 83, 167, 237 }, + { 68, 145, 222 }, + { 10, 103, 177 }, + { 2, 72, 131 }, + { 1, 41, 79 }, + { 1, 20, 39 } + }, { /* Coeff Band 3 */ + { 99, 167, 239 }, + { 47, 141, 224 }, + { 10, 104, 178 }, + { 2, 73, 133 }, + { 1, 44, 85 }, + { 1, 22, 47 } + }, { /* Coeff Band 4 */ + { 127, 145, 243 }, + { 71, 129, 228 }, + { 17, 93, 177 }, + { 3, 61, 124 }, + { 1, 41, 84 }, + { 1, 21, 52 } + }, { /* Coeff Band 5 */ + { 157, 78, 244 }, + { 140, 72, 231 }, + { 69, 58, 184 }, + { 31, 44, 137 }, + { 14, 38, 105 }, + { 8, 23, 61 } + } + } + } + }, { /* tx = 8x8 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 125, 34, 187 }, + { 52, 41, 133 }, + { 6, 31, 56 } + }, { /* Coeff Band 1 */ + { 37, 109, 153 }, + { 51, 102, 147 }, + { 23, 87, 128 }, + { 8, 67, 101 }, + { 1, 41, 63 }, + { 1, 19, 29 } + }, { /* Coeff Band 2 */ + { 31, 154, 185 }, + { 17, 127, 175 }, + { 6, 96, 145 }, + { 2, 73, 114 }, + { 1, 51, 82 }, + { 1, 28, 45 } + }, { /* Coeff Band 3 */ + { 23, 163, 200 }, + { 10, 131, 185 }, + { 2, 93, 148 }, + { 1, 67, 111 }, + { 1, 41, 69 }, + { 1, 14, 24 } + }, { /* Coeff Band 4 */ + { 29, 176, 217 }, + { 12, 145, 201 }, + { 3, 101, 156 }, + { 1, 69, 111 }, + { 1, 39, 63 }, + { 1, 14, 23 } + }, { /* Coeff Band 5 */ + { 57, 192, 233 }, + { 25, 154, 215 }, + { 6, 109, 167 }, + { 3, 78, 118 }, + { 1, 48, 69 }, + { 1, 21, 29 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 202, 105, 245 }, + { 108, 106, 216 }, + { 18, 90, 144 } + }, { /* Coeff Band 1 */ + { 33, 172, 219 }, + { 64, 149, 206 }, + { 14, 117, 177 }, + { 5, 90, 141 }, + { 2, 61, 95 }, + { 1, 37, 57 } + }, { /* Coeff Band 2 */ + { 33, 179, 220 }, + { 11, 140, 198 }, + { 1, 89, 148 }, + { 1, 60, 104 }, + { 1, 33, 57 }, + { 1, 12, 21 } + }, { /* Coeff Band 3 */ + { 30, 181, 221 }, + { 8, 141, 198 }, + { 1, 87, 145 }, + { 1, 58, 100 }, + { 1, 31, 55 }, + { 1, 12, 20 } + }, { /* Coeff Band 4 */ + { 32, 186, 224 }, + { 7, 142, 198 }, + { 1, 86, 143 }, + { 1, 58, 100 }, + { 1, 31, 55 }, + { 1, 12, 22 } + }, { /* Coeff Band 5 */ + { 57, 192, 227 }, + { 20, 143, 204 }, + { 3, 96, 154 }, + { 1, 68, 112 }, + { 1, 42, 69 }, + { 1, 19, 32 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 212, 35, 215 }, + { 113, 47, 169 }, + { 29, 48, 105 } + }, { /* Coeff Band 1 */ + { 74, 129, 203 }, + { 106, 120, 203 }, + { 49, 107, 178 }, + { 19, 84, 144 }, + { 4, 50, 84 }, + { 1, 15, 25 } + }, { /* Coeff Band 2 */ + { 71, 172, 217 }, + { 44, 141, 209 }, + { 15, 102, 173 }, + { 6, 76, 133 }, + { 2, 51, 89 }, + { 1, 24, 42 } + }, { /* Coeff Band 3 */ + { 64, 185, 231 }, + { 31, 148, 216 }, + { 8, 103, 175 }, + { 3, 74, 131 }, + { 1, 46, 81 }, + { 1, 18, 30 } + }, { /* Coeff Band 4 */ + { 65, 196, 235 }, + { 25, 157, 221 }, + { 5, 105, 174 }, + { 1, 67, 120 }, + { 1, 38, 69 }, + { 1, 15, 30 } + }, { /* Coeff Band 5 */ + { 65, 204, 238 }, + { 30, 156, 224 }, + { 7, 107, 177 }, + { 2, 70, 124 }, + { 1, 42, 73 }, + { 1, 18, 34 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 225, 86, 251 }, + { 144, 104, 235 }, + { 42, 99, 181 } + }, { /* Coeff Band 1 */ + { 85, 175, 239 }, + { 112, 165, 229 }, + { 29, 136, 200 }, + { 12, 103, 162 }, + { 6, 77, 123 }, + { 2, 53, 84 } + }, { /* Coeff Band 2 */ + { 75, 183, 239 }, + { 30, 155, 221 }, + { 3, 106, 171 }, + { 1, 74, 128 }, + { 1, 44, 76 }, + { 1, 17, 28 } + }, { /* Coeff Band 3 */ + { 73, 185, 240 }, + { 27, 159, 222 }, + { 2, 107, 172 }, + { 1, 75, 127 }, + { 1, 42, 73 }, + { 1, 17, 29 } + }, { /* Coeff Band 4 */ + { 62, 190, 238 }, + { 21, 159, 222 }, + { 2, 107, 172 }, + { 1, 72, 122 }, + { 1, 40, 71 }, + { 1, 18, 32 } + }, { /* Coeff Band 5 */ + { 61, 199, 240 }, + { 27, 161, 226 }, + { 4, 113, 180 }, + { 1, 76, 129 }, + { 1, 46, 80 }, + { 1, 23, 41 } + } + } + } + }, { /* tx = 16x16 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 7, 27, 153 }, + { 5, 30, 95 }, + { 1, 16, 30 } + }, { /* Coeff Band 1 */ + { 50, 75, 127 }, + { 57, 75, 124 }, + { 27, 67, 108 }, + { 10, 54, 86 }, + { 1, 33, 52 }, + { 1, 12, 18 } + }, { /* Coeff Band 2 */ + { 43, 125, 151 }, + { 26, 108, 148 }, + { 7, 83, 122 }, + { 2, 59, 89 }, + { 1, 38, 60 }, + { 1, 17, 27 } + }, { /* Coeff Band 3 */ + { 23, 144, 163 }, + { 13, 112, 154 }, + { 2, 75, 117 }, + { 1, 50, 81 }, + { 1, 31, 51 }, + { 1, 14, 23 } + }, { /* Coeff Band 4 */ + { 18, 162, 185 }, + { 6, 123, 171 }, + { 1, 78, 125 }, + { 1, 51, 86 }, + { 1, 31, 54 }, + { 1, 14, 23 } + }, { /* Coeff Band 5 */ + { 15, 199, 227 }, + { 3, 150, 204 }, + { 1, 91, 146 }, + { 1, 55, 95 }, + { 1, 30, 53 }, + { 1, 11, 20 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 19, 55, 240 }, + { 19, 59, 196 }, + { 3, 52, 105 } + }, { /* Coeff Band 1 */ + { 41, 166, 207 }, + { 104, 153, 199 }, + { 31, 123, 181 }, + { 14, 101, 152 }, + { 5, 72, 106 }, + { 1, 36, 52 } + }, { /* Coeff Band 2 */ + { 35, 176, 211 }, + { 12, 131, 190 }, + { 2, 88, 144 }, + { 1, 60, 101 }, + { 1, 36, 60 }, + { 1, 16, 28 } + }, { /* Coeff Band 3 */ + { 28, 183, 213 }, + { 8, 134, 191 }, + { 1, 86, 142 }, + { 1, 56, 96 }, + { 1, 30, 53 }, + { 1, 12, 20 } + }, { /* Coeff Band 4 */ + { 20, 190, 215 }, + { 4, 135, 192 }, + { 1, 84, 139 }, + { 1, 53, 91 }, + { 1, 28, 49 }, + { 1, 11, 20 } + }, { /* Coeff Band 5 */ + { 13, 196, 216 }, + { 2, 137, 192 }, + { 1, 86, 143 }, + { 1, 57, 99 }, + { 1, 32, 56 }, + { 1, 13, 24 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 211, 29, 217 }, + { 96, 47, 156 }, + { 22, 43, 87 } + }, { /* Coeff Band 1 */ + { 78, 120, 193 }, + { 111, 116, 186 }, + { 46, 102, 164 }, + { 15, 80, 128 }, + { 2, 49, 76 }, + { 1, 18, 28 } + }, { /* Coeff Band 2 */ + { 71, 161, 203 }, + { 42, 132, 192 }, + { 10, 98, 150 }, + { 3, 69, 109 }, + { 1, 44, 70 }, + { 1, 18, 29 } + }, { /* Coeff Band 3 */ + { 57, 186, 211 }, + { 30, 140, 196 }, + { 4, 93, 146 }, + { 1, 62, 102 }, + { 1, 38, 65 }, + { 1, 16, 27 } + }, { /* Coeff Band 4 */ + { 47, 199, 217 }, + { 14, 145, 196 }, + { 1, 88, 142 }, + { 1, 57, 98 }, + { 1, 36, 62 }, + { 1, 15, 26 } + }, { /* Coeff Band 5 */ + { 26, 219, 229 }, + { 5, 155, 207 }, + { 1, 94, 151 }, + { 1, 60, 104 }, + { 1, 36, 62 }, + { 1, 16, 28 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 233, 29, 248 }, + { 146, 47, 220 }, + { 43, 52, 140 } + }, { /* Coeff Band 1 */ + { 100, 163, 232 }, + { 179, 161, 222 }, + { 63, 142, 204 }, + { 37, 113, 174 }, + { 26, 89, 137 }, + { 18, 68, 97 } + }, { /* Coeff Band 2 */ + { 85, 181, 230 }, + { 32, 146, 209 }, + { 7, 100, 164 }, + { 3, 71, 121 }, + { 1, 45, 77 }, + { 1, 18, 30 } + }, { /* Coeff Band 3 */ + { 65, 187, 230 }, + { 20, 148, 207 }, + { 2, 97, 159 }, + { 1, 68, 116 }, + { 1, 40, 70 }, + { 1, 14, 29 } + }, { /* Coeff Band 4 */ + { 40, 194, 227 }, + { 8, 147, 204 }, + { 1, 94, 155 }, + { 1, 65, 112 }, + { 1, 39, 66 }, + { 1, 14, 26 } + }, { /* Coeff Band 5 */ + { 16, 208, 228 }, + { 3, 151, 207 }, + { 1, 98, 160 }, + { 1, 67, 117 }, + { 1, 41, 74 }, + { 1, 17, 31 } + } + } + } + }, { /* tx = 32x32 */ + { /* block Type 0 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 17, 38, 140 }, + { 7, 34, 80 }, + { 1, 17, 29 } + }, { /* Coeff Band 1 */ + { 37, 75, 128 }, + { 41, 76, 128 }, + { 26, 66, 116 }, + { 12, 52, 94 }, + { 2, 32, 55 }, + { 1, 10, 16 } + }, { /* Coeff Band 2 */ + { 50, 127, 154 }, + { 37, 109, 152 }, + { 16, 82, 121 }, + { 5, 59, 85 }, + { 1, 35, 54 }, + { 1, 13, 20 } + }, { /* Coeff Band 3 */ + { 40, 142, 167 }, + { 17, 110, 157 }, + { 2, 71, 112 }, + { 1, 44, 72 }, + { 1, 27, 45 }, + { 1, 11, 17 } + }, { /* Coeff Band 4 */ + { 30, 175, 188 }, + { 9, 124, 169 }, + { 1, 74, 116 }, + { 1, 48, 78 }, + { 1, 30, 49 }, + { 1, 11, 18 } + }, { /* Coeff Band 5 */ + { 10, 222, 223 }, + { 2, 150, 194 }, + { 1, 83, 128 }, + { 1, 48, 79 }, + { 1, 27, 45 }, + { 1, 11, 17 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 36, 41, 235 }, + { 29, 36, 193 }, + { 10, 27, 111 } + }, { /* Coeff Band 1 */ + { 85, 165, 222 }, + { 177, 162, 215 }, + { 110, 135, 195 }, + { 57, 113, 168 }, + { 23, 83, 120 }, + { 10, 49, 61 } + }, { /* Coeff Band 2 */ + { 85, 190, 223 }, + { 36, 139, 200 }, + { 5, 90, 146 }, + { 1, 60, 103 }, + { 1, 38, 65 }, + { 1, 18, 30 } + }, { /* Coeff Band 3 */ + { 72, 202, 223 }, + { 23, 141, 199 }, + { 2, 86, 140 }, + { 1, 56, 97 }, + { 1, 36, 61 }, + { 1, 16, 27 } + }, { /* Coeff Band 4 */ + { 55, 218, 225 }, + { 13, 145, 200 }, + { 1, 86, 141 }, + { 1, 57, 99 }, + { 1, 35, 61 }, + { 1, 13, 22 } + }, { /* Coeff Band 5 */ + { 15, 235, 212 }, + { 1, 132, 184 }, + { 1, 84, 139 }, + { 1, 57, 97 }, + { 1, 34, 56 }, + { 1, 14, 23 } + } + } + }, { /* block Type 1 */ + { /* Intra */ + { /* Coeff Band 0 */ + { 181, 21, 201 }, + { 61, 37, 123 }, + { 10, 38, 71 } + }, { /* Coeff Band 1 */ + { 47, 106, 172 }, + { 95, 104, 173 }, + { 42, 93, 159 }, + { 18, 77, 131 }, + { 4, 50, 81 }, + { 1, 17, 23 } + }, { /* Coeff Band 2 */ + { 62, 147, 199 }, + { 44, 130, 189 }, + { 28, 102, 154 }, + { 18, 75, 115 }, + { 2, 44, 65 }, + { 1, 12, 19 } + }, { /* Coeff Band 3 */ + { 55, 153, 210 }, + { 24, 130, 194 }, + { 3, 93, 146 }, + { 1, 61, 97 }, + { 1, 31, 50 }, + { 1, 10, 16 } + }, { /* Coeff Band 4 */ + { 49, 186, 223 }, + { 17, 148, 204 }, + { 1, 96, 142 }, + { 1, 53, 83 }, + { 1, 26, 44 }, + { 1, 11, 17 } + }, { /* Coeff Band 5 */ + { 13, 217, 212 }, + { 2, 136, 180 }, + { 1, 78, 124 }, + { 1, 50, 83 }, + { 1, 29, 49 }, + { 1, 14, 23 } + } + }, { /* Inter */ + { /* Coeff Band 0 */ + { 197, 13, 247 }, + { 82, 17, 222 }, + { 25, 17, 162 } + }, { /* Coeff Band 1 */ + { 126, 186, 247 }, + { 234, 191, 243 }, + { 176, 177, 234 }, + { 104, 158, 220 }, + { 66, 128, 186 }, + { 55, 90, 137 } + }, { /* Coeff Band 2 */ + { 111, 197, 242 }, + { 46, 158, 219 }, + { 9, 104, 171 }, + { 2, 65, 125 }, + { 1, 44, 80 }, + { 1, 17, 91 } + }, { /* Coeff Band 3 */ + { 104, 208, 245 }, + { 39, 168, 224 }, + { 3, 109, 162 }, + { 1, 79, 124 }, + { 1, 50, 102 }, + { 1, 43, 102 } + }, { /* Coeff Band 4 */ + { 84, 220, 246 }, + { 31, 177, 231 }, + { 2, 115, 180 }, + { 1, 79, 134 }, + { 1, 55, 77 }, + { 1, 60, 79 } + }, { /* Coeff Band 5 */ + { 43, 243, 240 }, + { 8, 180, 217 }, + { 1, 115, 166 }, + { 1, 84, 121 }, + { 1, 51, 67 }, + { 1, 16, 6 } + } + } + } + } +}; + +const int8_t ff_vp9_mv_joint_tree[3][2] = { + { -MV_JOINT_ZERO, 1 }, // '0' + { -MV_JOINT_H, 2 }, // '10' + { -MV_JOINT_V, -MV_JOINT_HV }, // '11x' +}; + +const int8_t ff_vp9_mv_class_tree[10][2] = { + { -0, 1 }, // '0' + { -1, 2 }, // '10' + { 3, 4 }, + { -2, -3 }, // '110x' + { 5, 6 }, + { -4, -5 }, // '1110x' + { -6, 7 }, // '11110' + { 8, 9 }, + { -7, -8 }, // '111110x' + { -9, -10 }, // '111111x' +}; + +const int8_t ff_vp9_mv_fp_tree[3][2] = { + { -0, 1 }, // '0' + { -1, 2 }, // '10' + { -2, -3 }, // '11x' +}; diff --git a/media/ffvpx/libavcodec/vp9data.h b/media/ffvpx/libavcodec/vp9data.h index cb12e7e94..086dbdec0 100644 --- a/media/ffvpx/libavcodec/vp9data.h +++ b/media/ffvpx/libavcodec/vp9data.h @@ -24,2254 +24,48 @@ #include <stdint.h> -#include "vp9.h" - -static const int8_t vp9_partition_tree[3][2] = { - { -PARTITION_NONE, 1 }, // '0' - { -PARTITION_H, 2 }, // '10' - { -PARTITION_V, -PARTITION_SPLIT }, // '110', '111' -}; - -static const uint8_t vp9_default_kf_partition_probs[4][4][3] = { - { /* 64x64 -> 32x32 */ - { 174, 35, 49 } /* a/l both not split */, - { 68, 11, 27 } /* a split, l not split */, - { 57, 15, 9 } /* l split, a not split */, - { 12, 3, 3 } /* a/l both split */ - }, { /* 32x32 -> 16x16 */ - { 150, 40, 39 } /* a/l both not split */, - { 78, 12, 26 } /* a split, l not split */, - { 67, 33, 11 } /* l split, a not split */, - { 24, 7, 5 } /* a/l both split */, - }, { /* 16x16 -> 8x8 */ - { 149, 53, 53 } /* a/l both not split */, - { 94, 20, 48 } /* a split, l not split */, - { 83, 53, 24 } /* l split, a not split */, - { 52, 18, 18 } /* a/l both split */, - }, { /* 8x8 -> 4x4 */ - { 158, 97, 94 } /* a/l both not split */, - { 93, 24, 99 } /* a split, l not split */, - { 85, 119, 44 } /* l split, a not split */, - { 62, 59, 67 } /* a/l both split */, - }, -}; - -static const int8_t vp9_segmentation_tree[7][2] = { - { 1, 2 }, - { 3, 4 }, - { 5, 6 }, - { -0, -1 }, // '00x' - { -2, -3 }, // '01x' - { -4, -5 }, // '10x' - { -6, -7 }, // '11x' -}; - -static const int8_t vp9_intramode_tree[9][2] = { - { -DC_PRED, 1 }, // '0' - { -TM_VP8_PRED, 2 }, // '10' - { -VERT_PRED, 3 }, // '110' - { 4, 6 }, - { -HOR_PRED, 5 }, // '11100' - { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x' - { -DIAG_DOWN_LEFT_PRED, 7 }, // '11110' - { -VERT_LEFT_PRED, 8 }, // '111110' - { -HOR_DOWN_PRED, -HOR_UP_PRED }, // '111111x' -}; - -static const uint8_t vp9_default_kf_ymode_probs[10][10][9] = { - { /* above = v */ - { 43, 46, 168, 134, 107, 128, 69, 142, 92 } /* left = v */, - { 44, 29, 68, 159, 201, 177, 50, 57, 77 } /* left = h */, - { 63, 36, 126, 146, 123, 158, 60, 90, 96 } /* left = dc */, - { 58, 38, 76, 114, 97, 172, 78, 133, 92 } /* left = d45 */, - { 46, 41, 76, 140, 63, 184, 69, 112, 57 } /* left = d135 */, - { 38, 32, 85, 140, 46, 112, 54, 151, 133 } /* left = d117 */, - { 39, 27, 61, 131, 110, 175, 44, 75, 136 } /* left = d153 */, - { 47, 35, 80, 100, 74, 143, 64, 163, 74 } /* left = d63 */, - { 52, 30, 74, 113, 130, 175, 51, 64, 58 } /* left = d27 */, - { 36, 61, 116, 114, 128, 162, 80, 125, 82 } /* left = tm */ - }, { /* above = h */ - { 55, 44, 68, 166, 179, 192, 57, 57, 108 } /* left = v */, - { 42, 26, 11, 199, 241, 228, 23, 15, 85 } /* left = h */, - { 82, 26, 26, 171, 208, 204, 44, 32, 105 } /* left = dc */, - { 68, 42, 19, 131, 160, 199, 55, 52, 83 } /* left = d45 */, - { 58, 50, 25, 139, 115, 232, 39, 52, 118 } /* left = d135 */, - { 50, 35, 33, 153, 104, 162, 64, 59, 131 } /* left = d117 */, - { 44, 24, 16, 150, 177, 202, 33, 19, 156 } /* left = d153 */, - { 53, 49, 21, 110, 116, 168, 59, 80, 76 } /* left = d63 */, - { 55, 27, 12, 153, 203, 218, 26, 27, 49 } /* left = d27 */, - { 38, 72, 19, 168, 203, 212, 50, 50, 107 } /* left = tm */ - }, { /* above = dc */ - { 92, 45, 102, 136, 116, 180, 74, 90, 100 } /* left = v */, - { 73, 32, 19, 187, 222, 215, 46, 34, 100 } /* left = h */, - { 137, 30, 42, 148, 151, 207, 70, 52, 91 } /* left = dc */, - { 91, 30, 32, 116, 121, 186, 93, 86, 94 } /* left = d45 */, - { 72, 35, 36, 149, 68, 206, 68, 63, 105 } /* left = d135 */, - { 73, 31, 28, 138, 57, 124, 55, 122, 151 } /* left = d117 */, - { 67, 23, 21, 140, 126, 197, 40, 37, 171 } /* left = d153 */, - { 74, 32, 27, 107, 86, 160, 63, 134, 102 } /* left = d63 */, - { 86, 27, 28, 128, 154, 212, 45, 43, 53 } /* left = d27 */, - { 59, 67, 44, 140, 161, 202, 78, 67, 119 } /* left = tm */ - }, { /* above = d45 */ - { 59, 38, 83, 112, 103, 162, 98, 136, 90 } /* left = v */, - { 62, 30, 23, 158, 200, 207, 59, 57, 50 } /* left = h */, - { 103, 26, 36, 129, 132, 201, 83, 80, 93 } /* left = dc */, - { 67, 30, 29, 84, 86, 191, 102, 91, 59 } /* left = d45 */, - { 60, 32, 33, 112, 71, 220, 64, 89, 104 } /* left = d135 */, - { 53, 26, 34, 130, 56, 149, 84, 120, 103 } /* left = d117 */, - { 53, 21, 23, 133, 109, 210, 56, 77, 172 } /* left = d153 */, - { 61, 29, 29, 93, 97, 165, 83, 175, 162 } /* left = d63 */, - { 77, 19, 29, 112, 142, 228, 55, 66, 36 } /* left = d27 */, - { 47, 47, 43, 114, 137, 181, 100, 99, 95 } /* left = tm */ - }, { /* above = d135 */ - { 53, 40, 55, 139, 69, 183, 61, 80, 110 } /* left = v */, - { 40, 29, 19, 161, 180, 207, 43, 24, 91 } /* left = h */, - { 69, 23, 29, 128, 83, 199, 46, 44, 101 } /* left = dc */, - { 60, 34, 19, 105, 61, 198, 53, 64, 89 } /* left = d45 */, - { 52, 31, 22, 158, 40, 209, 58, 62, 89 } /* left = d135 */, - { 44, 31, 29, 147, 46, 158, 56, 102, 198 } /* left = d117 */, - { 35, 19, 12, 135, 87, 209, 41, 45, 167 } /* left = d153 */, - { 51, 38, 25, 113, 58, 164, 70, 93, 97 } /* left = d63 */, - { 55, 25, 21, 118, 95, 215, 38, 39, 66 } /* left = d27 */, - { 47, 54, 34, 146, 108, 203, 72, 103, 151 } /* left = tm */ - }, { /* above = d117 */ - { 46, 27, 80, 150, 55, 124, 55, 121, 135 } /* left = v */, - { 36, 23, 27, 165, 149, 166, 54, 64, 118 } /* left = h */, - { 64, 19, 37, 156, 66, 138, 49, 95, 133 } /* left = dc */, - { 53, 21, 36, 131, 63, 163, 60, 109, 81 } /* left = d45 */, - { 40, 26, 35, 154, 40, 185, 51, 97, 123 } /* left = d135 */, - { 35, 19, 34, 179, 19, 97, 48, 129, 124 } /* left = d117 */, - { 36, 20, 26, 136, 62, 164, 33, 77, 154 } /* left = d153 */, - { 45, 26, 28, 129, 45, 129, 49, 147, 123 } /* left = d63 */, - { 45, 18, 32, 130, 90, 157, 40, 79, 91 } /* left = d27 */, - { 38, 44, 51, 136, 74, 162, 57, 97, 121 } /* left = tm */ - }, { /* above = d153 */ - { 56, 39, 58, 133, 117, 173, 48, 53, 187 } /* left = v */, - { 35, 21, 12, 161, 212, 207, 20, 23, 145 } /* left = h */, - { 75, 17, 22, 136, 138, 185, 32, 34, 166 } /* left = dc */, - { 56, 29, 19, 117, 109, 181, 55, 68, 112 } /* left = d45 */, - { 47, 29, 17, 153, 64, 220, 59, 51, 114 } /* left = d135 */, - { 46, 16, 24, 136, 76, 147, 41, 64, 172 } /* left = d117 */, - { 34, 17, 11, 108, 152, 187, 13, 15, 209 } /* left = d153 */, - { 55, 30, 18, 122, 79, 179, 44, 88, 116 } /* left = d63 */, - { 51, 24, 14, 115, 133, 209, 32, 26, 104 } /* left = d27 */, - { 37, 49, 25, 129, 168, 164, 41, 54, 148 } /* left = tm */ - }, { /* above = d63 */ - { 48, 34, 86, 101, 92, 146, 78, 179, 134 } /* left = v */, - { 47, 22, 24, 138, 187, 178, 68, 69, 59 } /* left = h */, - { 78, 23, 39, 111, 117, 170, 74, 124, 94 } /* left = dc */, - { 56, 25, 33, 105, 112, 187, 95, 177, 129 } /* left = d45 */, - { 48, 31, 27, 114, 63, 183, 82, 116, 56 } /* left = d135 */, - { 43, 28, 37, 121, 63, 123, 61, 192, 169 } /* left = d117 */, - { 42, 17, 24, 109, 97, 177, 56, 76, 122 } /* left = d153 */, - { 46, 23, 32, 74, 86, 150, 67, 183, 88 } /* left = d63 */, - { 58, 18, 28, 105, 139, 182, 70, 92, 63 } /* left = d27 */, - { 36, 38, 48, 92, 122, 165, 88, 137, 91 } /* left = tm */ - }, { /* above = d27 */ - { 62, 44, 61, 123, 105, 189, 48, 57, 64 } /* left = v */, - { 47, 25, 17, 175, 222, 220, 24, 30, 86 } /* left = h */, - { 82, 22, 32, 127, 143, 213, 39, 41, 70 } /* left = dc */, - { 68, 36, 17, 106, 102, 206, 59, 74, 74 } /* left = d45 */, - { 57, 39, 23, 151, 68, 216, 55, 63, 58 } /* left = d135 */, - { 49, 30, 35, 141, 70, 168, 82, 40, 115 } /* left = d117 */, - { 51, 25, 15, 136, 129, 202, 38, 35, 139 } /* left = d153 */, - { 59, 39, 19, 114, 75, 180, 77, 104, 42 } /* left = d63 */, - { 68, 26, 16, 111, 141, 215, 29, 28, 28 } /* left = d27 */, - { 40, 61, 26, 126, 152, 206, 61, 59, 93 } /* left = tm */ - }, { /* above = tm */ - { 44, 78, 115, 132, 119, 173, 71, 112, 93 } /* left = v */, - { 39, 38, 21, 184, 227, 206, 42, 32, 64 } /* left = h */, - { 65, 70, 60, 155, 159, 199, 61, 60, 81 } /* left = dc */, - { 58, 47, 36, 124, 137, 193, 80, 82, 78 } /* left = d45 */, - { 49, 50, 35, 144, 95, 205, 63, 78, 59 } /* left = d135 */, - { 41, 53, 52, 148, 71, 142, 65, 128, 51 } /* left = d117 */, - { 40, 36, 28, 143, 143, 202, 40, 55, 137 } /* left = d153 */, - { 42, 44, 44, 104, 105, 164, 64, 130, 80 } /* left = d63 */, - { 52, 34, 29, 129, 183, 227, 42, 35, 43 } /* left = d27 */, - { 43, 81, 53, 140, 169, 204, 68, 84, 72 } /* left = tm */ - } -}; - -static const uint8_t vp9_default_kf_uvmode_probs[10][9] = { - { 118, 15, 123, 148, 131, 101, 44, 93, 131 } /* y = v */, - { 113, 12, 23, 188, 226, 142, 26, 32, 125 } /* y = h */, - { 144, 11, 54, 157, 195, 130, 46, 58, 108 } /* y = dc */, - { 120, 11, 50, 123, 163, 135, 64, 77, 103 } /* y = d45 */, - { 113, 9, 36, 155, 111, 157, 32, 44, 161 } /* y = d135 */, - { 116, 9, 55, 176, 76, 96, 37, 61, 149 } /* y = d117 */, - { 115, 9, 28, 141, 161, 167, 21, 25, 193 } /* y = d153 */, - { 116, 12, 64, 120, 140, 125, 49, 115, 121 } /* y = d63 */, - { 120, 12, 32, 145, 195, 142, 32, 38, 86 } /* y = d27 */, - { 102, 19, 66, 162, 182, 122, 35, 59, 128 } /* y = tm */ -}; - -static const int8_t vp9_inter_mode_tree[3][2] = { - { -ZEROMV, 1 }, // '0' - { -NEARESTMV, 2 }, // '10' - { -NEARMV, -NEWMV }, // '11x' -}; - -static const int8_t vp9_filter_tree[2][2] = { - { -0, 1 }, // '0' - { -1, -2 }, // '1x' -}; - -static const enum FilterMode vp9_filter_lut[3] = { - FILTER_8TAP_REGULAR, - FILTER_8TAP_SMOOTH, - FILTER_8TAP_SHARP, -}; - -static const int16_t vp9_dc_qlookup[3][256] = { - { - 4, 8, 8, 9, 10, 11, 12, 12, - 13, 14, 15, 16, 17, 18, 19, 19, - 20, 21, 22, 23, 24, 25, 26, 26, - 27, 28, 29, 30, 31, 32, 32, 33, - 34, 35, 36, 37, 38, 38, 39, 40, - 41, 42, 43, 43, 44, 45, 46, 47, - 48, 48, 49, 50, 51, 52, 53, 53, - 54, 55, 56, 57, 57, 58, 59, 60, - 61, 62, 62, 63, 64, 65, 66, 66, - 67, 68, 69, 70, 70, 71, 72, 73, - 74, 74, 75, 76, 77, 78, 78, 79, - 80, 81, 81, 82, 83, 84, 85, 85, - 87, 88, 90, 92, 93, 95, 96, 98, - 99, 101, 102, 104, 105, 107, 108, 110, - 111, 113, 114, 116, 117, 118, 120, 121, - 123, 125, 127, 129, 131, 134, 136, 138, - 140, 142, 144, 146, 148, 150, 152, 154, - 156, 158, 161, 164, 166, 169, 172, 174, - 177, 180, 182, 185, 187, 190, 192, 195, - 199, 202, 205, 208, 211, 214, 217, 220, - 223, 226, 230, 233, 237, 240, 243, 247, - 250, 253, 257, 261, 265, 269, 272, 276, - 280, 284, 288, 292, 296, 300, 304, 309, - 313, 317, 322, 326, 330, 335, 340, 344, - 349, 354, 359, 364, 369, 374, 379, 384, - 389, 395, 400, 406, 411, 417, 423, 429, - 435, 441, 447, 454, 461, 467, 475, 482, - 489, 497, 505, 513, 522, 530, 539, 549, - 559, 569, 579, 590, 602, 614, 626, 640, - 654, 668, 684, 700, 717, 736, 755, 775, - 796, 819, 843, 869, 896, 925, 955, 988, - 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336, - }, { - 4, 9, 10, 13, 15, 17, 20, 22, - 25, 28, 31, 34, 37, 40, 43, 47, - 50, 53, 57, 60, 64, 68, 71, 75, - 78, 82, 86, 90, 93, 97, 101, 105, - 109, 113, 116, 120, 124, 128, 132, 136, - 140, 143, 147, 151, 155, 159, 163, 166, - 170, 174, 178, 182, 185, 189, 193, 197, - 200, 204, 208, 212, 215, 219, 223, 226, - 230, 233, 237, 241, 244, 248, 251, 255, - 259, 262, 266, 269, 273, 276, 280, 283, - 287, 290, 293, 297, 300, 304, 307, 310, - 314, 317, 321, 324, 327, 331, 334, 337, - 343, 350, 356, 362, 369, 375, 381, 387, - 394, 400, 406, 412, 418, 424, 430, 436, - 442, 448, 454, 460, 466, 472, 478, 484, - 490, 499, 507, 516, 525, 533, 542, 550, - 559, 567, 576, 584, 592, 601, 609, 617, - 625, 634, 644, 655, 666, 676, 687, 698, - 708, 718, 729, 739, 749, 759, 770, 782, - 795, 807, 819, 831, 844, 856, 868, 880, - 891, 906, 920, 933, 947, 961, 975, 988, - 1001, 1015, 1030, 1045, 1061, 1076, 1090, 1105, - 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, - 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, - 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, - 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, - 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, - 1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197, - 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, - 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102, - 3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, - 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347, - }, { - 4, 12, 18, 25, 33, 41, 50, 60, - 70, 80, 91, 103, 115, 127, 140, 153, - 166, 180, 194, 208, 222, 237, 251, 266, - 281, 296, 312, 327, 343, 358, 374, 390, - 405, 421, 437, 453, 469, 484, 500, 516, - 532, 548, 564, 580, 596, 611, 627, 643, - 659, 674, 690, 706, 721, 737, 752, 768, - 783, 798, 814, 829, 844, 859, 874, 889, - 904, 919, 934, 949, 964, 978, 993, 1008, - 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122, - 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, - 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, - 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, - 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741, - 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, - 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199, - 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, - 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788, - 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, - 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517, - 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, - 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, - 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, - 5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517, - 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, - 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, - 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, - 7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788, - 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, - 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, - 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, - 16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387, - } -}; - -static const int16_t vp9_ac_qlookup[3][256] = { - { - 4, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, - 104, 106, 108, 110, 112, 114, 116, 118, - 120, 122, 124, 126, 128, 130, 132, 134, - 136, 138, 140, 142, 144, 146, 148, 150, - 152, 155, 158, 161, 164, 167, 170, 173, - 176, 179, 182, 185, 188, 191, 194, 197, - 200, 203, 207, 211, 215, 219, 223, 227, - 231, 235, 239, 243, 247, 251, 255, 260, - 265, 270, 275, 280, 285, 290, 295, 300, - 305, 311, 317, 323, 329, 335, 341, 347, - 353, 359, 366, 373, 380, 387, 394, 401, - 408, 416, 424, 432, 440, 448, 456, 465, - 474, 483, 492, 501, 510, 520, 530, 540, - 550, 560, 571, 582, 593, 604, 615, 627, - 639, 651, 663, 676, 689, 702, 715, 729, - 743, 757, 771, 786, 801, 816, 832, 848, - 864, 881, 898, 915, 933, 951, 969, 988, - 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, - 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, - 1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567, - 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, - }, { - 4, 9, 11, 13, 16, 18, 21, 24, - 27, 30, 33, 37, 40, 44, 48, 51, - 55, 59, 63, 67, 71, 75, 79, 83, - 88, 92, 96, 100, 105, 109, 114, 118, - 122, 127, 131, 136, 140, 145, 149, 154, - 158, 163, 168, 172, 177, 181, 186, 190, - 195, 199, 204, 208, 213, 217, 222, 226, - 231, 235, 240, 244, 249, 253, 258, 262, - 267, 271, 275, 280, 284, 289, 293, 297, - 302, 306, 311, 315, 319, 324, 328, 332, - 337, 341, 345, 349, 354, 358, 362, 367, - 371, 375, 379, 384, 388, 392, 396, 401, - 409, 417, 425, 433, 441, 449, 458, 466, - 474, 482, 490, 498, 506, 514, 523, 531, - 539, 547, 555, 563, 571, 579, 588, 596, - 604, 616, 628, 640, 652, 664, 676, 688, - 700, 713, 725, 737, 749, 761, 773, 785, - 797, 809, 825, 841, 857, 873, 889, 905, - 922, 938, 954, 970, 986, 1002, 1018, 1038, - 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, - 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, - 1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603, - 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, - 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, - 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, - 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, - 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, - 3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952, - 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, - 4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372, - 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, - 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312, - }, { - 4, 13, 19, 27, 35, 44, 54, 64, - 75, 87, 99, 112, 126, 139, 154, 168, - 183, 199, 214, 230, 247, 263, 280, 297, - 314, 331, 349, 366, 384, 402, 420, 438, - 456, 475, 493, 511, 530, 548, 567, 586, - 604, 623, 642, 660, 679, 698, 716, 735, - 753, 772, 791, 809, 828, 846, 865, 884, - 902, 920, 939, 957, 976, 994, 1012, 1030, - 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, - 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317, - 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, - 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, - 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, - 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118, - 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, - 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750, - 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, - 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619, - 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, - 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791, - 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, - 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, - 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, - 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635, - 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, - 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, - 11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565, - 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, - 16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414, - 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, - 21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070, - 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247, - } -}; - -static const enum TxfmType vp9_intra_txfm_type[14] = { - [VERT_PRED] = ADST_DCT, - [HOR_PRED] = DCT_ADST, - [DC_PRED] = DCT_DCT, - [DIAG_DOWN_LEFT_PRED] = DCT_DCT, - [DIAG_DOWN_RIGHT_PRED] = ADST_ADST, - [VERT_RIGHT_PRED] = ADST_DCT, - [HOR_DOWN_PRED] = DCT_ADST, - [VERT_LEFT_PRED] = ADST_DCT, - [HOR_UP_PRED] = DCT_ADST, - [TM_VP8_PRED] = ADST_ADST, - [NEARESTMV] = DCT_DCT, - [NEARMV] = DCT_DCT, - [ZEROMV] = DCT_DCT, - [NEWMV] = DCT_DCT, -}; - -static const int16_t vp9_default_scan_4x4[16] = { - 0, 1, 4, 5, - 2, 8, 3, 6, - 12, 9, 7, 10, - 13, 11, 14, 15, -}; - -static const int16_t vp9_col_scan_4x4[16] = { - 0, 1, 2, 4, - 3, 5, 6, 8, - 7, 9, 10, 12, - 13, 11, 14, 15, -}; - -static const int16_t vp9_row_scan_4x4[16] = { - 0, 4, 1, 8, - 5, 12, 9, 2, - 6, 13, 3, 10, - 7, 14, 11, 15, -}; - -static const int16_t vp9_default_scan_8x8[64] = { - 0, 1, 8, 2, 9, 16, 10, 3, - 17, 24, 18, 11, 4, 25, 32, 19, - 12, 26, 5, 33, 20, 27, 40, 13, - 34, 6, 41, 28, 21, 35, 42, 48, - 14, 7, 36, 29, 43, 56, 49, 22, - 15, 37, 50, 44, 57, 30, 23, 51, - 45, 58, 38, 31, 52, 59, 39, 46, - 53, 60, 47, 54, 61, 55, 62, 63, -}; - -static const int16_t vp9_col_scan_8x8[64] = { - 0, 1, 2, 8, 3, 9, 4, 10, - 16, 5, 11, 17, 12, 18, 6, 24, - 19, 13, 25, 7, 26, 20, 32, 14, - 27, 21, 33, 28, 34, 15, 22, 35, - 40, 29, 41, 36, 23, 30, 42, 37, - 48, 43, 31, 44, 49, 38, 50, 56, - 45, 39, 51, 57, 52, 46, 58, 53, - 59, 47, 60, 54, 61, 55, 62, 63, -}; - -static const int16_t vp9_row_scan_8x8[64] = { - 0, 8, 16, 1, 9, 24, 2, 17, - 32, 10, 25, 3, 40, 18, 11, 33, - 26, 19, 4, 48, 41, 34, 12, 27, - 56, 20, 5, 42, 35, 13, 49, 28, - 6, 21, 43, 36, 14, 50, 29, 57, - 7, 44, 22, 37, 51, 15, 58, 30, - 23, 45, 52, 38, 59, 31, 46, 53, - 39, 60, 47, 61, 54, 62, 55, 63, -}; - -static const int16_t vp9_default_scan_16x16[256] = { - 0, 1, 16, 2, 17, 32, 3, 18, 33, 48, 4, 34, 19, 49, 20, 5, - 35, 64, 50, 36, 65, 21, 6, 51, 80, 66, 37, 22, 52, 7, 81, 67, - 38, 82, 53, 23, 96, 68, 8, 83, 97, 54, 39, 69, 112, 24, 98, 84, - 70, 55, 9, 40, 85, 99, 113, 128, 25, 114, 100, 71, 86, 56, 10, 41, - 115, 101, 129, 116, 72, 87, 26, 130, 144, 102, 57, 11, 42, 117, 131, 145, - 88, 103, 27, 73, 132, 118, 146, 58, 160, 12, 43, 133, 147, 104, 89, 119, - 161, 74, 148, 134, 28, 162, 59, 13, 176, 120, 149, 90, 135, 105, 163, 44, - 75, 177, 164, 29, 150, 121, 136, 178, 165, 14, 106, 60, 91, 151, 45, 179, - 192, 137, 166, 122, 76, 180, 152, 30, 61, 15, 107, 167, 181, 193, 92, 208, - 46, 138, 123, 153, 194, 77, 168, 182, 31, 195, 209, 183, 108, 139, 62, 154, - 47, 196, 93, 169, 210, 197, 224, 124, 184, 211, 78, 109, 170, 155, 63, 198, - 212, 185, 225, 240, 140, 94, 199, 125, 79, 213, 226, 171, 186, 156, 214, 200, - 110, 227, 141, 95, 241, 215, 228, 201, 126, 242, 187, 172, 157, 229, 111, 216, - 243, 142, 202, 230, 127, 217, 244, 173, 188, 231, 158, 203, 143, 245, 218, 232, - 189, 246, 159, 174, 233, 247, 219, 204, 175, 190, 248, 234, 205, 220, 249, 191, - 235, 221, 250, 206, 222, 251, 236, 207, 237, 223, 252, 238, 253, 239, 254, 255, -}; - -static const int16_t vp9_col_scan_16x16[256] = { - 0, 1, 2, 3, 16, 4, 17, 5, 18, 6, 19, 32, 20, 7, 33, 21, - 34, 8, 35, 22, 48, 36, 9, 49, 23, 50, 37, 10, 38, 51, 24, 64, - 52, 11, 65, 39, 25, 53, 66, 54, 40, 67, 12, 80, 26, 68, 55, 81, - 41, 69, 13, 27, 82, 56, 70, 83, 42, 14, 84, 96, 71, 28, 57, 85, - 97, 15, 72, 98, 43, 86, 58, 99, 29, 87, 100, 112, 73, 44, 101, 59, - 30, 113, 88, 114, 74, 128, 102, 45, 31, 115, 60, 103, 89, 116, 75, 129, - 117, 46, 104, 90, 61, 130, 118, 131, 132, 105, 76, 47, 119, 144, 91, 62, - 133, 106, 145, 120, 146, 134, 77, 147, 121, 92, 135, 148, 63, 107, 136, 122, - 93, 149, 160, 78, 150, 137, 108, 161, 162, 151, 123, 79, 138, 163, 152, 94, - 164, 109, 165, 153, 124, 139, 176, 166, 95, 177, 167, 110, 154, 178, 125, 179, - 140, 168, 155, 111, 180, 192, 181, 169, 141, 126, 182, 193, 194, 156, 183, 170, - 195, 127, 142, 196, 184, 208, 197, 157, 171, 143, 185, 198, 209, 199, 210, 172, - 158, 186, 211, 224, 212, 200, 240, 159, 213, 225, 187, 201, 173, 226, 214, 215, - 227, 202, 228, 188, 241, 216, 174, 229, 242, 203, 243, 217, 230, 175, 189, 244, - 231, 204, 218, 232, 245, 219, 246, 190, 233, 205, 191, 247, 234, 248, 220, 206, - 249, 235, 221, 207, 250, 236, 222, 251, 223, 237, 238, 252, 239, 253, 254, 255, -}; - -static const int16_t vp9_row_scan_16x16[256] = { - 0, 16, 32, 1, 48, 17, 64, 33, 2, 80, 18, 49, 96, 34, 3, 65, - 19, 112, 50, 81, 35, 4, 128, 66, 20, 97, 51, 82, 5, 144, 36, 67, - 113, 98, 21, 52, 160, 83, 129, 37, 68, 6, 114, 176, 99, 53, 22, 84, - 145, 38, 69, 130, 7, 115, 192, 100, 54, 23, 85, 161, 146, 131, 39, 70, - 208, 116, 8, 101, 177, 55, 86, 24, 162, 147, 132, 71, 224, 117, 40, 102, - 9, 148, 56, 87, 193, 163, 240, 133, 178, 25, 118, 72, 41, 103, 164, 10, - 149, 88, 134, 209, 179, 57, 119, 194, 26, 73, 165, 150, 104, 42, 135, 11, - 180, 120, 89, 225, 195, 58, 27, 210, 151, 181, 166, 74, 43, 105, 12, 136, - 90, 59, 241, 121, 28, 196, 167, 211, 152, 44, 182, 137, 75, 13, 226, 106, - 122, 60, 197, 91, 168, 29, 183, 153, 14, 76, 212, 138, 45, 107, 15, 198, - 92, 227, 169, 30, 123, 154, 61, 242, 184, 213, 139, 46, 77, 31, 108, 170, - 199, 185, 124, 228, 93, 155, 214, 62, 140, 243, 78, 47, 200, 109, 186, 171, - 201, 94, 63, 215, 229, 156, 79, 125, 141, 110, 216, 187, 172, 244, 202, 230, - 217, 95, 157, 126, 245, 111, 142, 231, 188, 127, 158, 218, 173, 232, 246, 233, - 203, 143, 247, 174, 189, 159, 219, 204, 248, 234, 249, 175, 190, 220, 205, 250, - 235, 191, 221, 251, 236, 206, 252, 222, 207, 237, 223, 253, 238, 254, 239, 255, -}; - -static const int16_t vp9_default_scan_32x32[1024] = { - 0, 1, 32, 2, 33, 64, 3, 34, 65, 4, 96, 35, 66, 5, 36, 97, 67, 128, 98, 68, 37, 6, 129, 99, 7, 160, 69, 38, 130, 100, 161, 131, - 39, 70, 8, 101, 162, 132, 192, 71, 40, 9, 102, 163, 133, 193, 72, 224, 103, 41, 164, 10, 194, 134, 165, 73, 104, 135, 225, 42, 195, 11, 256, 166, - 226, 196, 74, 105, 136, 43, 12, 167, 197, 227, 257, 75, 106, 137, 228, 44, 198, 168, 258, 288, 13, 229, 76, 107, 199, 138, 259, 169, 289, 45, 230, 260, - 200, 108, 14, 170, 139, 320, 290, 77, 231, 261, 46, 201, 140, 291, 109, 232, 321, 262, 171, 78, 292, 15, 322, 202, 263, 352, 172, 293, 233, 141, 323, 110, - 47, 203, 264, 234, 294, 353, 324, 16, 79, 204, 265, 295, 325, 173, 354, 142, 235, 384, 48, 296, 111, 266, 355, 326, 80, 17, 205, 236, 174, 356, 385, 327, - 143, 297, 267, 357, 386, 112, 49, 328, 298, 206, 416, 237, 358, 387, 81, 175, 18, 329, 359, 388, 299, 330, 389, 113, 417, 238, 360, 50, 207, 418, 390, 331, - 19, 448, 361, 82, 419, 391, 239, 51, 362, 420, 114, 449, 480, 421, 83, 363, 450, 422, 512, 451, 423, 115, 452, 481, 453, 482, 454, 544, 483, 455, 513, 484, - 514, 485, 515, 486, 545, 576, 487, 546, 547, 608, 577, 578, 579, 609, 610, 611, 20, 144, 268, 392, 516, 640, 21, 52, 145, 176, 269, 300, 393, 424, 517, 548, - 641, 672, 22, 53, 84, 146, 177, 208, 270, 301, 332, 394, 425, 456, 518, 549, 580, 642, 673, 704, 23, 54, 85, 116, 147, 178, 209, 240, 271, 302, 333, 364, - 395, 426, 457, 488, 519, 550, 581, 612, 643, 674, 705, 736, 55, 86, 117, 179, 210, 241, 303, 334, 365, 427, 458, 489, 551, 582, 613, 675, 706, 737, 87, 118, - 211, 242, 335, 366, 459, 490, 583, 614, 707, 738, 119, 243, 367, 491, 615, 739, 24, 148, 272, 396, 520, 644, 768, 25, 56, 149, 180, 273, 304, 397, 428, 521, - 552, 645, 676, 769, 800, 26, 57, 88, 150, 181, 212, 274, 305, 336, 398, 429, 460, 522, 553, 584, 646, 677, 708, 770, 801, 832, 27, 58, 89, 120, 151, 182, - 213, 244, 275, 306, 337, 368, 399, 430, 461, 492, 523, 554, 585, 616, 647, 678, 709, 740, 771, 802, 833, 864, 59, 90, 121, 183, 214, 245, 307, 338, 369, 431, - 462, 493, 555, 586, 617, 679, 710, 741, 803, 834, 865, 91, 122, 215, 246, 339, 370, 463, 494, 587, 618, 711, 742, 835, 866, 123, 247, 371, 495, 619, 743, 867, - 28, 152, 276, 400, 524, 648, 772, 896, 29, 60, 153, 184, 277, 308, 401, 432, 525, 556, 649, 680, 773, 804, 897, 928, 30, 61, 92, 154, 185, 216, 278, 309, - 340, 402, 433, 464, 526, 557, 588, 650, 681, 712, 774, 805, 836, 898, 929, 960, 31, 62, 93, 124, 155, 186, 217, 248, 279, 310, 341, 372, 403, 434, 465, 496, - 527, 558, 589, 620, 651, 682, 713, 744, 775, 806, 837, 868, 899, 930, 961, 992, 63, 94, 125, 187, 218, 249, 311, 342, 373, 435, 466, 497, 559, 590, 621, 683, - 714, 745, 807, 838, 869, 931, 962, 993, 95, 126, 219, 250, 343, 374, 467, 498, 591, 622, 715, 746, 839, 870, 963, 994, 127, 251, 375, 499, 623, 747, 871, 995, - 156, 280, 404, 528, 652, 776, 900, 157, 188, 281, 312, 405, 436, 529, 560, 653, 684, 777, 808, 901, 932, 158, 189, 220, 282, 313, 344, 406, 437, 468, 530, 561, - 592, 654, 685, 716, 778, 809, 840, 902, 933, 964, 159, 190, 221, 252, 283, 314, 345, 376, 407, 438, 469, 500, 531, 562, 593, 624, 655, 686, 717, 748, 779, 810, - 841, 872, 903, 934, 965, 996, 191, 222, 253, 315, 346, 377, 439, 470, 501, 563, 594, 625, 687, 718, 749, 811, 842, 873, 935, 966, 997, 223, 254, 347, 378, 471, - 502, 595, 626, 719, 750, 843, 874, 967, 998, 255, 379, 503, 627, 751, 875, 999, 284, 408, 532, 656, 780, 904, 285, 316, 409, 440, 533, 564, 657, 688, 781, 812, - 905, 936, 286, 317, 348, 410, 441, 472, 534, 565, 596, 658, 689, 720, 782, 813, 844, 906, 937, 968, 287, 318, 349, 380, 411, 442, 473, 504, 535, 566, 597, 628, - 659, 690, 721, 752, 783, 814, 845, 876, 907, 938, 969, 1000, 319, 350, 381, 443, 474, 505, 567, 598, 629, 691, 722, 753, 815, 846, 877, 939, 970, 1001, 351, 382, - 475, 506, 599, 630, 723, 754, 847, 878, 971, 1002, 383, 507, 631, 755, 879, 1003, 412, 536, 660, 784, 908, 413, 444, 537, 568, 661, 692, 785, 816, 909, 940, 414, - 445, 476, 538, 569, 600, 662, 693, 724, 786, 817, 848, 910, 941, 972, 415, 446, 477, 508, 539, 570, 601, 632, 663, 694, 725, 756, 787, 818, 849, 880, 911, 942, - 973, 1004, 447, 478, 509, 571, 602, 633, 695, 726, 757, 819, 850, 881, 943, 974, 1005, 479, 510, 603, 634, 727, 758, 851, 882, 975, 1006, 511, 635, 759, 883, 1007, - 540, 664, 788, 912, 541, 572, 665, 696, 789, 820, 913, 944, 542, 573, 604, 666, 697, 728, 790, 821, 852, 914, 945, 976, 543, 574, 605, 636, 667, 698, 729, 760, - 791, 822, 853, 884, 915, 946, 977, 1008, 575, 606, 637, 699, 730, 761, 823, 854, 885, 947, 978, 1009, 607, 638, 731, 762, 855, 886, 979, 1010, 639, 763, 887, 1011, - 668, 792, 916, 669, 700, 793, 824, 917, 948, 670, 701, 732, 794, 825, 856, 918, 949, 980, 671, 702, 733, 764, 795, 826, 857, 888, 919, 950, 981, 1012, 703, 734, - 765, 827, 858, 889, 951, 982, 1013, 735, 766, 859, 890, 983, 1014, 767, 891, 1015, 796, 920, 797, 828, 921, 952, 798, 829, 860, 922, 953, 984, 799, 830, 861, 892, - 923, 954, 985, 1016, 831, 862, 893, 955, 986, 1017, 863, 894, 987, 1018, 895, 1019, 924, 925, 956, 926, 957, 988, 927, 958, 989, 1020, 959, 990, 1021, 991, 1022, 1023, -}; - -static const int16_t * const vp9_scans[5][4] = { - { - vp9_default_scan_4x4, vp9_col_scan_4x4, - vp9_row_scan_4x4, vp9_default_scan_4x4 - }, { - vp9_default_scan_8x8, vp9_col_scan_8x8, - vp9_row_scan_8x8, vp9_default_scan_8x8 - }, { - vp9_default_scan_16x16, vp9_col_scan_16x16, - vp9_row_scan_16x16, vp9_default_scan_16x16 - }, { - vp9_default_scan_32x32, vp9_default_scan_32x32, - vp9_default_scan_32x32, vp9_default_scan_32x32 - }, { // lossless - vp9_default_scan_4x4, vp9_default_scan_4x4, - vp9_default_scan_4x4, vp9_default_scan_4x4 - } -}; - -static const int16_t vp9_default_scan_4x4_nb[16][2] = { - { 0, 0 }, { 0, 0 }, { 4, 1 }, { 1, 1 }, - { 4, 4 }, { 2, 2 }, { 5, 2 }, { 8, 8 }, - { 8, 5 }, { 6, 3 }, { 9, 6 }, { 12, 9 }, - { 10, 7 }, { 13, 10 }, { 14, 11 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_4x4_nb[16][2] = { - { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, - { 4, 4 }, { 5, 5 }, { 4, 4 }, { 6, 6 }, - { 8, 8 }, { 9, 9 }, { 8, 8 }, { 12, 12 }, - { 10, 10 }, { 13, 13 }, { 14, 14 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_4x4_nb[16][2] = { - { 0, 0 }, { 0, 0 }, { 4, 4 }, { 1, 1 }, - { 8, 8 }, { 5, 5 }, { 1, 1 }, { 2, 2 }, - { 9, 9 }, { 2, 2 }, { 6, 6 }, { 3, 3 }, - { 10, 10 }, { 7, 7 }, { 11, 11 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_8x8_nb[64][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 8, 1 }, - { 8, 8 }, { 9, 2 }, { 2, 2 }, { 16, 9 }, - { 16, 16 }, { 17, 10 }, { 10, 3 }, { 3, 3 }, - { 24, 17 }, { 24, 24 }, { 18, 11 }, { 11, 4 }, - { 25, 18 }, { 4, 4 }, { 32, 25 }, { 19, 12 }, - { 26, 19 }, { 32, 32 }, { 12, 5 }, { 33, 26 }, - { 5, 5 }, { 40, 33 }, { 27, 20 }, { 20, 13 }, - { 34, 27 }, { 41, 34 }, { 40, 40 }, { 13, 6 }, - { 6, 6 }, { 35, 28 }, { 28, 21 }, { 42, 35 }, - { 48, 48 }, { 48, 41 }, { 21, 14 }, { 14, 7 }, - { 36, 29 }, { 49, 42 }, { 43, 36 }, { 56, 49 }, - { 29, 22 }, { 22, 15 }, { 50, 43 }, { 44, 37 }, - { 57, 50 }, { 37, 30 }, { 30, 23 }, { 51, 44 }, - { 58, 51 }, { 38, 31 }, { 45, 38 }, { 52, 45 }, - { 59, 52 }, { 46, 39 }, { 53, 46 }, { 60, 53 }, - { 54, 47 }, { 61, 54 }, { 62, 55 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_8x8_nb[64][2] = { - { 0, 0 }, { 1, 1 }, { 0, 0 }, { 2, 2 }, - { 8, 8 }, { 3, 3 }, { 9, 9 }, { 8, 8 }, - { 4, 4 }, { 10, 10 }, { 16, 16 }, { 11, 11 }, - { 17, 17 }, { 5, 5 }, { 16, 16 }, { 18, 18 }, - { 12, 12 }, { 24, 24 }, { 6, 6 }, { 25, 25 }, - { 19, 19 }, { 24, 24 }, { 13, 13 }, { 26, 26 }, - { 20, 20 }, { 32, 32 }, { 27, 27 }, { 33, 33 }, - { 14, 14 }, { 21, 21 }, { 34, 34 }, { 32, 32 }, - { 28, 28 }, { 40, 40 }, { 35, 35 }, { 22, 22 }, - { 29, 29 }, { 41, 41 }, { 36, 36 }, { 40, 40 }, - { 42, 42 }, { 30, 30 }, { 43, 43 }, { 48, 48 }, - { 37, 37 }, { 49, 49 }, { 48, 48 }, { 44, 44 }, - { 38, 38 }, { 50, 50 }, { 56, 56 }, { 51, 51 }, - { 45, 45 }, { 57, 57 }, { 52, 52 }, { 58, 58 }, - { 46, 46 }, { 59, 59 }, { 53, 53 }, { 60, 60 }, - { 54, 54 }, { 61, 61 }, { 62, 62 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_8x8_nb[64][2] = { - { 0, 0 }, { 8, 8 }, { 0, 0 }, { 1, 1 }, - { 16, 16 }, { 1, 1 }, { 9, 9 }, { 24, 24 }, - { 2, 2 }, { 17, 17 }, { 2, 2 }, { 32, 32 }, - { 10, 10 }, { 3, 3 }, { 25, 25 }, { 18, 18 }, - { 11, 11 }, { 3, 3 }, { 40, 40 }, { 33, 33 }, - { 26, 26 }, { 4, 4 }, { 19, 19 }, { 48, 48 }, - { 12, 12 }, { 4, 4 }, { 34, 34 }, { 27, 27 }, - { 5, 5 }, { 41, 41 }, { 20, 20 }, { 5, 5 }, - { 13, 13 }, { 35, 35 }, { 28, 28 }, { 6, 6 }, - { 42, 42 }, { 21, 21 }, { 49, 49 }, { 6, 6 }, - { 36, 36 }, { 14, 14 }, { 29, 29 }, { 43, 43 }, - { 7, 7 }, { 50, 50 }, { 22, 22 }, { 15, 15 }, - { 37, 37 }, { 44, 44 }, { 30, 30 }, { 51, 51 }, - { 23, 23 }, { 38, 38 }, { 45, 45 }, { 31, 31 }, - { 52, 52 }, { 39, 39 }, { 53, 53 }, { 46, 46 }, - { 54, 54 }, { 47, 47 }, { 55, 55 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_16x16_nb[256][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 16, 1 }, - { 16, 16 }, { 2, 2 }, { 17, 2 }, { 32, 17 }, - { 32, 32 }, { 3, 3 }, { 33, 18 }, { 18, 3 }, - { 48, 33 }, { 19, 4 }, { 4, 4 }, { 34, 19 }, - { 48, 48 }, { 49, 34 }, { 35, 20 }, { 64, 49 }, - { 20, 5 }, { 5, 5 }, { 50, 35 }, { 64, 64 }, - { 65, 50 }, { 36, 21 }, { 21, 6 }, { 51, 36 }, - { 6, 6 }, { 80, 65 }, { 66, 51 }, { 37, 22 }, - { 81, 66 }, { 52, 37 }, { 22, 7 }, { 80, 80 }, - { 67, 52 }, { 7, 7 }, { 82, 67 }, { 96, 81 }, - { 53, 38 }, { 38, 23 }, { 68, 53 }, { 96, 96 }, - { 23, 8 }, { 97, 82 }, { 83, 68 }, { 69, 54 }, - { 54, 39 }, { 8, 8 }, { 39, 24 }, { 84, 69 }, - { 98, 83 }, { 112, 97 }, { 112, 112 }, { 24, 9 }, - { 113, 98 }, { 99, 84 }, { 70, 55 }, { 85, 70 }, - { 55, 40 }, { 9, 9 }, { 40, 25 }, { 114, 99 }, - { 100, 85 }, { 128, 113 }, { 115, 100 }, { 71, 56 }, - { 86, 71 }, { 25, 10 }, { 129, 114 }, { 128, 128 }, - { 101, 86 }, { 56, 41 }, { 10, 10 }, { 41, 26 }, - { 116, 101 }, { 130, 115 }, { 144, 129 }, { 87, 72 }, - { 102, 87 }, { 26, 11 }, { 72, 57 }, { 131, 116 }, - { 117, 102 }, { 145, 130 }, { 57, 42 }, { 144, 144 }, - { 11, 11 }, { 42, 27 }, { 132, 117 }, { 146, 131 }, - { 103, 88 }, { 88, 73 }, { 118, 103 }, { 160, 145 }, - { 73, 58 }, { 147, 132 }, { 133, 118 }, { 27, 12 }, - { 161, 146 }, { 58, 43 }, { 12, 12 }, { 160, 160 }, - { 119, 104 }, { 148, 133 }, { 89, 74 }, { 134, 119 }, - { 104, 89 }, { 162, 147 }, { 43, 28 }, { 74, 59 }, - { 176, 161 }, { 163, 148 }, { 28, 13 }, { 149, 134 }, - { 120, 105 }, { 135, 120 }, { 177, 162 }, { 164, 149 }, - { 13, 13 }, { 105, 90 }, { 59, 44 }, { 90, 75 }, - { 150, 135 }, { 44, 29 }, { 178, 163 }, { 176, 176 }, - { 136, 121 }, { 165, 150 }, { 121, 106 }, { 75, 60 }, - { 179, 164 }, { 151, 136 }, { 29, 14 }, { 60, 45 }, - { 14, 14 }, { 106, 91 }, { 166, 151 }, { 180, 165 }, - { 192, 177 }, { 91, 76 }, { 192, 192 }, { 45, 30 }, - { 137, 122 }, { 122, 107 }, { 152, 137 }, { 193, 178 }, - { 76, 61 }, { 167, 152 }, { 181, 166 }, { 30, 15 }, - { 194, 179 }, { 208, 193 }, { 182, 167 }, { 107, 92 }, - { 138, 123 }, { 61, 46 }, { 153, 138 }, { 46, 31 }, - { 195, 180 }, { 92, 77 }, { 168, 153 }, { 209, 194 }, - { 196, 181 }, { 208, 208 }, { 123, 108 }, { 183, 168 }, - { 210, 195 }, { 77, 62 }, { 108, 93 }, { 169, 154 }, - { 154, 139 }, { 62, 47 }, { 197, 182 }, { 211, 196 }, - { 184, 169 }, { 224, 209 }, { 224, 224 }, { 139, 124 }, - { 93, 78 }, { 198, 183 }, { 124, 109 }, { 78, 63 }, - { 212, 197 }, { 225, 210 }, { 170, 155 }, { 185, 170 }, - { 155, 140 }, { 213, 198 }, { 199, 184 }, { 109, 94 }, - { 226, 211 }, { 140, 125 }, { 94, 79 }, { 240, 225 }, - { 214, 199 }, { 227, 212 }, { 200, 185 }, { 125, 110 }, - { 241, 226 }, { 186, 171 }, { 171, 156 }, { 156, 141 }, - { 228, 213 }, { 110, 95 }, { 215, 200 }, { 242, 227 }, - { 141, 126 }, { 201, 186 }, { 229, 214 }, { 126, 111 }, - { 216, 201 }, { 243, 228 }, { 172, 157 }, { 187, 172 }, - { 230, 215 }, { 157, 142 }, { 202, 187 }, { 142, 127 }, - { 244, 229 }, { 217, 202 }, { 231, 216 }, { 188, 173 }, - { 245, 230 }, { 158, 143 }, { 173, 158 }, { 232, 217 }, - { 246, 231 }, { 218, 203 }, { 203, 188 }, { 174, 159 }, - { 189, 174 }, { 247, 232 }, { 233, 218 }, { 204, 189 }, - { 219, 204 }, { 248, 233 }, { 190, 175 }, { 234, 219 }, - { 220, 205 }, { 249, 234 }, { 205, 190 }, { 221, 206 }, - { 250, 235 }, { 235, 220 }, { 206, 191 }, { 236, 221 }, - { 222, 207 }, { 251, 236 }, { 237, 222 }, { 252, 237 }, - { 238, 223 }, { 253, 238 }, { 254, 239 }, { 0, 0 }, -}; - -static const int16_t vp9_col_scan_16x16_nb[256][2] = { - { 0, 0 }, { 1, 1 }, { 2, 2 }, { 0, 0 }, - { 3, 3 }, { 16, 16 }, { 4, 4 }, { 17, 17 }, - { 5, 5 }, { 18, 18 }, { 16, 16 }, { 19, 19 }, - { 6, 6 }, { 32, 32 }, { 20, 20 }, { 33, 33 }, - { 7, 7 }, { 34, 34 }, { 21, 21 }, { 32, 32 }, - { 35, 35 }, { 8, 8 }, { 48, 48 }, { 22, 22 }, - { 49, 49 }, { 36, 36 }, { 9, 9 }, { 37, 37 }, - { 50, 50 }, { 23, 23 }, { 48, 48 }, { 51, 51 }, - { 10, 10 }, { 64, 64 }, { 38, 38 }, { 24, 24 }, - { 52, 52 }, { 65, 65 }, { 53, 53 }, { 39, 39 }, - { 66, 66 }, { 11, 11 }, { 64, 64 }, { 25, 25 }, - { 67, 67 }, { 54, 54 }, { 80, 80 }, { 40, 40 }, - { 68, 68 }, { 12, 12 }, { 26, 26 }, { 81, 81 }, - { 55, 55 }, { 69, 69 }, { 82, 82 }, { 41, 41 }, - { 13, 13 }, { 83, 83 }, { 80, 80 }, { 70, 70 }, - { 27, 27 }, { 56, 56 }, { 84, 84 }, { 96, 96 }, - { 14, 14 }, { 71, 71 }, { 97, 97 }, { 42, 42 }, - { 85, 85 }, { 57, 57 }, { 98, 98 }, { 28, 28 }, - { 86, 86 }, { 99, 99 }, { 96, 96 }, { 72, 72 }, - { 43, 43 }, { 100, 100 }, { 58, 58 }, { 29, 29 }, - { 112, 112 }, { 87, 87 }, { 113, 113 }, { 73, 73 }, - { 112, 112 }, { 101, 101 }, { 44, 44 }, { 30, 30 }, - { 114, 114 }, { 59, 59 }, { 102, 102 }, { 88, 88 }, - { 115, 115 }, { 74, 74 }, { 128, 128 }, { 116, 116 }, - { 45, 45 }, { 103, 103 }, { 89, 89 }, { 60, 60 }, - { 129, 129 }, { 117, 117 }, { 130, 130 }, { 131, 131 }, - { 104, 104 }, { 75, 75 }, { 46, 46 }, { 118, 118 }, - { 128, 128 }, { 90, 90 }, { 61, 61 }, { 132, 132 }, - { 105, 105 }, { 144, 144 }, { 119, 119 }, { 145, 145 }, - { 133, 133 }, { 76, 76 }, { 146, 146 }, { 120, 120 }, - { 91, 91 }, { 134, 134 }, { 147, 147 }, { 62, 62 }, - { 106, 106 }, { 135, 135 }, { 121, 121 }, { 92, 92 }, - { 148, 148 }, { 144, 144 }, { 77, 77 }, { 149, 149 }, - { 136, 136 }, { 107, 107 }, { 160, 160 }, { 161, 161 }, - { 150, 150 }, { 122, 122 }, { 78, 78 }, { 137, 137 }, - { 162, 162 }, { 151, 151 }, { 93, 93 }, { 163, 163 }, - { 108, 108 }, { 164, 164 }, { 152, 152 }, { 123, 123 }, - { 138, 138 }, { 160, 160 }, { 165, 165 }, { 94, 94 }, - { 176, 176 }, { 166, 166 }, { 109, 109 }, { 153, 153 }, - { 177, 177 }, { 124, 124 }, { 178, 178 }, { 139, 139 }, - { 167, 167 }, { 154, 154 }, { 110, 110 }, { 179, 179 }, - { 176, 176 }, { 180, 180 }, { 168, 168 }, { 140, 140 }, - { 125, 125 }, { 181, 181 }, { 192, 192 }, { 193, 193 }, - { 155, 155 }, { 182, 182 }, { 169, 169 }, { 194, 194 }, - { 126, 126 }, { 141, 141 }, { 195, 195 }, { 183, 183 }, - { 192, 192 }, { 196, 196 }, { 156, 156 }, { 170, 170 }, - { 142, 142 }, { 184, 184 }, { 197, 197 }, { 208, 208 }, - { 198, 198 }, { 209, 209 }, { 171, 171 }, { 157, 157 }, - { 185, 185 }, { 210, 210 }, { 208, 208 }, { 211, 211 }, - { 199, 199 }, { 224, 224 }, { 158, 158 }, { 212, 212 }, - { 224, 224 }, { 186, 186 }, { 200, 200 }, { 172, 172 }, - { 225, 225 }, { 213, 213 }, { 214, 214 }, { 226, 226 }, - { 201, 201 }, { 227, 227 }, { 187, 187 }, { 240, 240 }, - { 215, 215 }, { 173, 173 }, { 228, 228 }, { 241, 241 }, - { 202, 202 }, { 242, 242 }, { 216, 216 }, { 229, 229 }, - { 174, 174 }, { 188, 188 }, { 243, 243 }, { 230, 230 }, - { 203, 203 }, { 217, 217 }, { 231, 231 }, { 244, 244 }, - { 218, 218 }, { 245, 245 }, { 189, 189 }, { 232, 232 }, - { 204, 204 }, { 190, 190 }, { 246, 246 }, { 233, 233 }, - { 247, 247 }, { 219, 219 }, { 205, 205 }, { 248, 248 }, - { 234, 234 }, { 220, 220 }, { 206, 206 }, { 249, 249 }, - { 235, 235 }, { 221, 221 }, { 250, 250 }, { 222, 222 }, - { 236, 236 }, { 237, 237 }, { 251, 251 }, { 238, 238 }, - { 252, 252 }, { 253, 253 }, { 254, 254 }, { 0, 0 }, -}; - -static const int16_t vp9_row_scan_16x16_nb[256][2] = { - { 0, 0 }, { 16, 16 }, { 0, 0 }, { 32, 32 }, - { 1, 1 }, { 48, 48 }, { 17, 17 }, { 1, 1 }, - { 64, 64 }, { 2, 2 }, { 33, 33 }, { 80, 80 }, - { 18, 18 }, { 2, 2 }, { 49, 49 }, { 3, 3 }, - { 96, 96 }, { 34, 34 }, { 65, 65 }, { 19, 19 }, - { 3, 3 }, { 112, 112 }, { 50, 50 }, { 4, 4 }, - { 81, 81 }, { 35, 35 }, { 66, 66 }, { 4, 4 }, - { 128, 128 }, { 20, 20 }, { 51, 51 }, { 97, 97 }, - { 82, 82 }, { 5, 5 }, { 36, 36 }, { 144, 144 }, - { 67, 67 }, { 113, 113 }, { 21, 21 }, { 52, 52 }, - { 5, 5 }, { 98, 98 }, { 160, 160 }, { 83, 83 }, - { 37, 37 }, { 6, 6 }, { 68, 68 }, { 129, 129 }, - { 22, 22 }, { 53, 53 }, { 114, 114 }, { 6, 6 }, - { 99, 99 }, { 176, 176 }, { 84, 84 }, { 38, 38 }, - { 7, 7 }, { 69, 69 }, { 145, 145 }, { 130, 130 }, - { 115, 115 }, { 23, 23 }, { 54, 54 }, { 192, 192 }, - { 100, 100 }, { 7, 7 }, { 85, 85 }, { 161, 161 }, - { 39, 39 }, { 70, 70 }, { 8, 8 }, { 146, 146 }, - { 131, 131 }, { 116, 116 }, { 55, 55 }, { 208, 208 }, - { 101, 101 }, { 24, 24 }, { 86, 86 }, { 8, 8 }, - { 132, 132 }, { 40, 40 }, { 71, 71 }, { 177, 177 }, - { 147, 147 }, { 224, 224 }, { 117, 117 }, { 162, 162 }, - { 9, 9 }, { 102, 102 }, { 56, 56 }, { 25, 25 }, - { 87, 87 }, { 148, 148 }, { 9, 9 }, { 133, 133 }, - { 72, 72 }, { 118, 118 }, { 193, 193 }, { 163, 163 }, - { 41, 41 }, { 103, 103 }, { 178, 178 }, { 10, 10 }, - { 57, 57 }, { 149, 149 }, { 134, 134 }, { 88, 88 }, - { 26, 26 }, { 119, 119 }, { 10, 10 }, { 164, 164 }, - { 104, 104 }, { 73, 73 }, { 209, 209 }, { 179, 179 }, - { 42, 42 }, { 11, 11 }, { 194, 194 }, { 135, 135 }, - { 165, 165 }, { 150, 150 }, { 58, 58 }, { 27, 27 }, - { 89, 89 }, { 11, 11 }, { 120, 120 }, { 74, 74 }, - { 43, 43 }, { 225, 225 }, { 105, 105 }, { 12, 12 }, - { 180, 180 }, { 151, 151 }, { 195, 195 }, { 136, 136 }, - { 28, 28 }, { 166, 166 }, { 121, 121 }, { 59, 59 }, - { 12, 12 }, { 210, 210 }, { 90, 90 }, { 106, 106 }, - { 44, 44 }, { 181, 181 }, { 75, 75 }, { 152, 152 }, - { 13, 13 }, { 167, 167 }, { 137, 137 }, { 13, 13 }, - { 60, 60 }, { 196, 196 }, { 122, 122 }, { 29, 29 }, - { 91, 91 }, { 14, 14 }, { 182, 182 }, { 76, 76 }, - { 211, 211 }, { 153, 153 }, { 14, 14 }, { 107, 107 }, - { 138, 138 }, { 45, 45 }, { 226, 226 }, { 168, 168 }, - { 197, 197 }, { 123, 123 }, { 30, 30 }, { 61, 61 }, - { 15, 15 }, { 92, 92 }, { 154, 154 }, { 183, 183 }, - { 169, 169 }, { 108, 108 }, { 212, 212 }, { 77, 77 }, - { 139, 139 }, { 198, 198 }, { 46, 46 }, { 124, 124 }, - { 227, 227 }, { 62, 62 }, { 31, 31 }, { 184, 184 }, - { 93, 93 }, { 170, 170 }, { 155, 155 }, { 185, 185 }, - { 78, 78 }, { 47, 47 }, { 199, 199 }, { 213, 213 }, - { 140, 140 }, { 63, 63 }, { 109, 109 }, { 125, 125 }, - { 94, 94 }, { 200, 200 }, { 171, 171 }, { 156, 156 }, - { 228, 228 }, { 186, 186 }, { 214, 214 }, { 201, 201 }, - { 79, 79 }, { 141, 141 }, { 110, 110 }, { 229, 229 }, - { 95, 95 }, { 126, 126 }, { 215, 215 }, { 172, 172 }, - { 111, 111 }, { 142, 142 }, { 202, 202 }, { 157, 157 }, - { 216, 216 }, { 230, 230 }, { 217, 217 }, { 187, 187 }, - { 127, 127 }, { 231, 231 }, { 158, 158 }, { 173, 173 }, - { 143, 143 }, { 203, 203 }, { 188, 188 }, { 232, 232 }, - { 218, 218 }, { 233, 233 }, { 159, 159 }, { 174, 174 }, - { 204, 204 }, { 189, 189 }, { 234, 234 }, { 219, 219 }, - { 175, 175 }, { 205, 205 }, { 235, 235 }, { 220, 220 }, - { 190, 190 }, { 236, 236 }, { 206, 206 }, { 191, 191 }, - { 221, 221 }, { 207, 207 }, { 237, 237 }, { 222, 222 }, - { 238, 238 }, { 223, 223 }, { 239, 239 }, { 0, 0 }, -}; - -static const int16_t vp9_default_scan_32x32_nb[1024][2] = { - { 0, 0 }, { 0, 0 }, { 1, 1 }, { 32, 1 }, - { 32, 32 }, { 2, 2 }, { 33, 2 }, { 64, 33 }, - { 3, 3 }, { 64, 64 }, { 34, 3 }, { 65, 34 }, - { 4, 4 }, { 35, 4 }, { 96, 65 }, { 66, 35 }, - { 96, 96 }, { 97, 66 }, { 67, 36 }, { 36, 5 }, - { 5, 5 }, { 128, 97 }, { 98, 67 }, { 6, 6 }, - { 128, 128 }, { 68, 37 }, { 37, 6 }, { 129, 98 }, - { 99, 68 }, { 160, 129 }, { 130, 99 }, { 38, 7 }, - { 69, 38 }, { 7, 7 }, { 100, 69 }, { 161, 130 }, - { 131, 100 }, { 160, 160 }, { 70, 39 }, { 39, 8 }, - { 8, 8 }, { 101, 70 }, { 162, 131 }, { 132, 101 }, - { 192, 161 }, { 71, 40 }, { 192, 192 }, { 102, 71 }, - { 40, 9 }, { 163, 132 }, { 9, 9 }, { 193, 162 }, - { 133, 102 }, { 164, 133 }, { 72, 41 }, { 103, 72 }, - { 134, 103 }, { 224, 193 }, { 41, 10 }, { 194, 163 }, - { 10, 10 }, { 224, 224 }, { 165, 134 }, { 225, 194 }, - { 195, 164 }, { 73, 42 }, { 104, 73 }, { 135, 104 }, - { 42, 11 }, { 11, 11 }, { 166, 135 }, { 196, 165 }, - { 226, 195 }, { 256, 225 }, { 74, 43 }, { 105, 74 }, - { 136, 105 }, { 227, 196 }, { 43, 12 }, { 197, 166 }, - { 167, 136 }, { 257, 226 }, { 256, 256 }, { 12, 12 }, - { 228, 197 }, { 75, 44 }, { 106, 75 }, { 198, 167 }, - { 137, 106 }, { 258, 227 }, { 168, 137 }, { 288, 257 }, - { 44, 13 }, { 229, 198 }, { 259, 228 }, { 199, 168 }, - { 107, 76 }, { 13, 13 }, { 169, 138 }, { 138, 107 }, - { 288, 288 }, { 289, 258 }, { 76, 45 }, { 230, 199 }, - { 260, 229 }, { 45, 14 }, { 200, 169 }, { 139, 108 }, - { 290, 259 }, { 108, 77 }, { 231, 200 }, { 320, 289 }, - { 261, 230 }, { 170, 139 }, { 77, 46 }, { 291, 260 }, - { 14, 14 }, { 321, 290 }, { 201, 170 }, { 262, 231 }, - { 320, 320 }, { 171, 140 }, { 292, 261 }, { 232, 201 }, - { 140, 109 }, { 322, 291 }, { 109, 78 }, { 46, 15 }, - { 202, 171 }, { 263, 232 }, { 233, 202 }, { 293, 262 }, - { 352, 321 }, { 323, 292 }, { 15, 15 }, { 78, 47 }, - { 203, 172 }, { 264, 233 }, { 294, 263 }, { 324, 293 }, - { 172, 141 }, { 353, 322 }, { 141, 110 }, { 234, 203 }, - { 352, 352 }, { 47, 16 }, { 295, 264 }, { 110, 79 }, - { 265, 234 }, { 354, 323 }, { 325, 294 }, { 79, 48 }, - { 16, 16 }, { 204, 173 }, { 235, 204 }, { 173, 142 }, - { 355, 324 }, { 384, 353 }, { 326, 295 }, { 142, 111 }, - { 296, 265 }, { 266, 235 }, { 356, 325 }, { 385, 354 }, - { 111, 80 }, { 48, 17 }, { 327, 296 }, { 297, 266 }, - { 205, 174 }, { 384, 384 }, { 236, 205 }, { 357, 326 }, - { 386, 355 }, { 80, 49 }, { 174, 143 }, { 17, 17 }, - { 328, 297 }, { 358, 327 }, { 387, 356 }, { 298, 267 }, - { 329, 298 }, { 388, 357 }, { 112, 81 }, { 416, 385 }, - { 237, 206 }, { 359, 328 }, { 49, 18 }, { 206, 175 }, - { 417, 386 }, { 389, 358 }, { 330, 299 }, { 18, 18 }, - { 416, 416 }, { 360, 329 }, { 81, 50 }, { 418, 387 }, - { 390, 359 }, { 238, 207 }, { 50, 19 }, { 361, 330 }, - { 419, 388 }, { 113, 82 }, { 448, 417 }, { 448, 448 }, - { 420, 389 }, { 82, 51 }, { 362, 331 }, { 449, 418 }, - { 421, 390 }, { 480, 480 }, { 450, 419 }, { 422, 391 }, - { 114, 83 }, { 451, 420 }, { 480, 449 }, { 452, 421 }, - { 481, 450 }, { 453, 422 }, { 512, 512 }, { 482, 451 }, - { 454, 423 }, { 512, 481 }, { 483, 452 }, { 513, 482 }, - { 484, 453 }, { 514, 483 }, { 485, 454 }, { 544, 513 }, - { 544, 544 }, { 486, 455 }, { 545, 514 }, { 546, 515 }, - { 576, 576 }, { 576, 545 }, { 577, 546 }, { 578, 547 }, - { 608, 577 }, { 609, 578 }, { 610, 579 }, { 19, 19 }, - { 143, 112 }, { 267, 236 }, { 391, 360 }, { 515, 484 }, - { 608, 608 }, { 20, 20 }, { 51, 20 }, { 144, 113 }, - { 175, 144 }, { 268, 237 }, { 299, 268 }, { 392, 361 }, - { 423, 392 }, { 516, 485 }, { 547, 516 }, { 640, 609 }, - { 640, 640 }, { 21, 21 }, { 52, 21 }, { 83, 52 }, - { 145, 114 }, { 176, 145 }, { 207, 176 }, { 269, 238 }, - { 300, 269 }, { 331, 300 }, { 393, 362 }, { 424, 393 }, - { 455, 424 }, { 517, 486 }, { 548, 517 }, { 579, 548 }, - { 641, 610 }, { 672, 641 }, { 672, 672 }, { 22, 22 }, - { 53, 22 }, { 84, 53 }, { 115, 84 }, { 146, 115 }, - { 177, 146 }, { 208, 177 }, { 239, 208 }, { 270, 239 }, - { 301, 270 }, { 332, 301 }, { 363, 332 }, { 394, 363 }, - { 425, 394 }, { 456, 425 }, { 487, 456 }, { 518, 487 }, - { 549, 518 }, { 580, 549 }, { 611, 580 }, { 642, 611 }, - { 673, 642 }, { 704, 673 }, { 704, 704 }, { 54, 23 }, - { 85, 54 }, { 116, 85 }, { 178, 147 }, { 209, 178 }, - { 240, 209 }, { 302, 271 }, { 333, 302 }, { 364, 333 }, - { 426, 395 }, { 457, 426 }, { 488, 457 }, { 550, 519 }, - { 581, 550 }, { 612, 581 }, { 674, 643 }, { 705, 674 }, - { 736, 705 }, { 86, 55 }, { 117, 86 }, { 210, 179 }, - { 241, 210 }, { 334, 303 }, { 365, 334 }, { 458, 427 }, - { 489, 458 }, { 582, 551 }, { 613, 582 }, { 706, 675 }, - { 737, 706 }, { 118, 87 }, { 242, 211 }, { 366, 335 }, - { 490, 459 }, { 614, 583 }, { 738, 707 }, { 23, 23 }, - { 147, 116 }, { 271, 240 }, { 395, 364 }, { 519, 488 }, - { 643, 612 }, { 736, 736 }, { 24, 24 }, { 55, 24 }, - { 148, 117 }, { 179, 148 }, { 272, 241 }, { 303, 272 }, - { 396, 365 }, { 427, 396 }, { 520, 489 }, { 551, 520 }, - { 644, 613 }, { 675, 644 }, { 768, 737 }, { 768, 768 }, - { 25, 25 }, { 56, 25 }, { 87, 56 }, { 149, 118 }, - { 180, 149 }, { 211, 180 }, { 273, 242 }, { 304, 273 }, - { 335, 304 }, { 397, 366 }, { 428, 397 }, { 459, 428 }, - { 521, 490 }, { 552, 521 }, { 583, 552 }, { 645, 614 }, - { 676, 645 }, { 707, 676 }, { 769, 738 }, { 800, 769 }, - { 800, 800 }, { 26, 26 }, { 57, 26 }, { 88, 57 }, - { 119, 88 }, { 150, 119 }, { 181, 150 }, { 212, 181 }, - { 243, 212 }, { 274, 243 }, { 305, 274 }, { 336, 305 }, - { 367, 336 }, { 398, 367 }, { 429, 398 }, { 460, 429 }, - { 491, 460 }, { 522, 491 }, { 553, 522 }, { 584, 553 }, - { 615, 584 }, { 646, 615 }, { 677, 646 }, { 708, 677 }, - { 739, 708 }, { 770, 739 }, { 801, 770 }, { 832, 801 }, - { 832, 832 }, { 58, 27 }, { 89, 58 }, { 120, 89 }, - { 182, 151 }, { 213, 182 }, { 244, 213 }, { 306, 275 }, - { 337, 306 }, { 368, 337 }, { 430, 399 }, { 461, 430 }, - { 492, 461 }, { 554, 523 }, { 585, 554 }, { 616, 585 }, - { 678, 647 }, { 709, 678 }, { 740, 709 }, { 802, 771 }, - { 833, 802 }, { 864, 833 }, { 90, 59 }, { 121, 90 }, - { 214, 183 }, { 245, 214 }, { 338, 307 }, { 369, 338 }, - { 462, 431 }, { 493, 462 }, { 586, 555 }, { 617, 586 }, - { 710, 679 }, { 741, 710 }, { 834, 803 }, { 865, 834 }, - { 122, 91 }, { 246, 215 }, { 370, 339 }, { 494, 463 }, - { 618, 587 }, { 742, 711 }, { 866, 835 }, { 27, 27 }, - { 151, 120 }, { 275, 244 }, { 399, 368 }, { 523, 492 }, - { 647, 616 }, { 771, 740 }, { 864, 864 }, { 28, 28 }, - { 59, 28 }, { 152, 121 }, { 183, 152 }, { 276, 245 }, - { 307, 276 }, { 400, 369 }, { 431, 400 }, { 524, 493 }, - { 555, 524 }, { 648, 617 }, { 679, 648 }, { 772, 741 }, - { 803, 772 }, { 896, 865 }, { 896, 896 }, { 29, 29 }, - { 60, 29 }, { 91, 60 }, { 153, 122 }, { 184, 153 }, - { 215, 184 }, { 277, 246 }, { 308, 277 }, { 339, 308 }, - { 401, 370 }, { 432, 401 }, { 463, 432 }, { 525, 494 }, - { 556, 525 }, { 587, 556 }, { 649, 618 }, { 680, 649 }, - { 711, 680 }, { 773, 742 }, { 804, 773 }, { 835, 804 }, - { 897, 866 }, { 928, 897 }, { 928, 928 }, { 30, 30 }, - { 61, 30 }, { 92, 61 }, { 123, 92 }, { 154, 123 }, - { 185, 154 }, { 216, 185 }, { 247, 216 }, { 278, 247 }, - { 309, 278 }, { 340, 309 }, { 371, 340 }, { 402, 371 }, - { 433, 402 }, { 464, 433 }, { 495, 464 }, { 526, 495 }, - { 557, 526 }, { 588, 557 }, { 619, 588 }, { 650, 619 }, - { 681, 650 }, { 712, 681 }, { 743, 712 }, { 774, 743 }, - { 805, 774 }, { 836, 805 }, { 867, 836 }, { 898, 867 }, - { 929, 898 }, { 960, 929 }, { 960, 960 }, { 62, 31 }, - { 93, 62 }, { 124, 93 }, { 186, 155 }, { 217, 186 }, - { 248, 217 }, { 310, 279 }, { 341, 310 }, { 372, 341 }, - { 434, 403 }, { 465, 434 }, { 496, 465 }, { 558, 527 }, - { 589, 558 }, { 620, 589 }, { 682, 651 }, { 713, 682 }, - { 744, 713 }, { 806, 775 }, { 837, 806 }, { 868, 837 }, - { 930, 899 }, { 961, 930 }, { 992, 961 }, { 94, 63 }, - { 125, 94 }, { 218, 187 }, { 249, 218 }, { 342, 311 }, - { 373, 342 }, { 466, 435 }, { 497, 466 }, { 590, 559 }, - { 621, 590 }, { 714, 683 }, { 745, 714 }, { 838, 807 }, - { 869, 838 }, { 962, 931 }, { 993, 962 }, { 126, 95 }, - { 250, 219 }, { 374, 343 }, { 498, 467 }, { 622, 591 }, - { 746, 715 }, { 870, 839 }, { 994, 963 }, { 155, 124 }, - { 279, 248 }, { 403, 372 }, { 527, 496 }, { 651, 620 }, - { 775, 744 }, { 899, 868 }, { 156, 125 }, { 187, 156 }, - { 280, 249 }, { 311, 280 }, { 404, 373 }, { 435, 404 }, - { 528, 497 }, { 559, 528 }, { 652, 621 }, { 683, 652 }, - { 776, 745 }, { 807, 776 }, { 900, 869 }, { 931, 900 }, - { 157, 126 }, { 188, 157 }, { 219, 188 }, { 281, 250 }, - { 312, 281 }, { 343, 312 }, { 405, 374 }, { 436, 405 }, - { 467, 436 }, { 529, 498 }, { 560, 529 }, { 591, 560 }, - { 653, 622 }, { 684, 653 }, { 715, 684 }, { 777, 746 }, - { 808, 777 }, { 839, 808 }, { 901, 870 }, { 932, 901 }, - { 963, 932 }, { 158, 127 }, { 189, 158 }, { 220, 189 }, - { 251, 220 }, { 282, 251 }, { 313, 282 }, { 344, 313 }, - { 375, 344 }, { 406, 375 }, { 437, 406 }, { 468, 437 }, - { 499, 468 }, { 530, 499 }, { 561, 530 }, { 592, 561 }, - { 623, 592 }, { 654, 623 }, { 685, 654 }, { 716, 685 }, - { 747, 716 }, { 778, 747 }, { 809, 778 }, { 840, 809 }, - { 871, 840 }, { 902, 871 }, { 933, 902 }, { 964, 933 }, - { 995, 964 }, { 190, 159 }, { 221, 190 }, { 252, 221 }, - { 314, 283 }, { 345, 314 }, { 376, 345 }, { 438, 407 }, - { 469, 438 }, { 500, 469 }, { 562, 531 }, { 593, 562 }, - { 624, 593 }, { 686, 655 }, { 717, 686 }, { 748, 717 }, - { 810, 779 }, { 841, 810 }, { 872, 841 }, { 934, 903 }, - { 965, 934 }, { 996, 965 }, { 222, 191 }, { 253, 222 }, - { 346, 315 }, { 377, 346 }, { 470, 439 }, { 501, 470 }, - { 594, 563 }, { 625, 594 }, { 718, 687 }, { 749, 718 }, - { 842, 811 }, { 873, 842 }, { 966, 935 }, { 997, 966 }, - { 254, 223 }, { 378, 347 }, { 502, 471 }, { 626, 595 }, - { 750, 719 }, { 874, 843 }, { 998, 967 }, { 283, 252 }, - { 407, 376 }, { 531, 500 }, { 655, 624 }, { 779, 748 }, - { 903, 872 }, { 284, 253 }, { 315, 284 }, { 408, 377 }, - { 439, 408 }, { 532, 501 }, { 563, 532 }, { 656, 625 }, - { 687, 656 }, { 780, 749 }, { 811, 780 }, { 904, 873 }, - { 935, 904 }, { 285, 254 }, { 316, 285 }, { 347, 316 }, - { 409, 378 }, { 440, 409 }, { 471, 440 }, { 533, 502 }, - { 564, 533 }, { 595, 564 }, { 657, 626 }, { 688, 657 }, - { 719, 688 }, { 781, 750 }, { 812, 781 }, { 843, 812 }, - { 905, 874 }, { 936, 905 }, { 967, 936 }, { 286, 255 }, - { 317, 286 }, { 348, 317 }, { 379, 348 }, { 410, 379 }, - { 441, 410 }, { 472, 441 }, { 503, 472 }, { 534, 503 }, - { 565, 534 }, { 596, 565 }, { 627, 596 }, { 658, 627 }, - { 689, 658 }, { 720, 689 }, { 751, 720 }, { 782, 751 }, - { 813, 782 }, { 844, 813 }, { 875, 844 }, { 906, 875 }, - { 937, 906 }, { 968, 937 }, { 999, 968 }, { 318, 287 }, - { 349, 318 }, { 380, 349 }, { 442, 411 }, { 473, 442 }, - { 504, 473 }, { 566, 535 }, { 597, 566 }, { 628, 597 }, - { 690, 659 }, { 721, 690 }, { 752, 721 }, { 814, 783 }, - { 845, 814 }, { 876, 845 }, { 938, 907 }, { 969, 938 }, - { 1000, 969 }, { 350, 319 }, { 381, 350 }, { 474, 443 }, - { 505, 474 }, { 598, 567 }, { 629, 598 }, { 722, 691 }, - { 753, 722 }, { 846, 815 }, { 877, 846 }, { 970, 939 }, - { 1001, 970 }, { 382, 351 }, { 506, 475 }, { 630, 599 }, - { 754, 723 }, { 878, 847 }, { 1002, 971 }, { 411, 380 }, - { 535, 504 }, { 659, 628 }, { 783, 752 }, { 907, 876 }, - { 412, 381 }, { 443, 412 }, { 536, 505 }, { 567, 536 }, - { 660, 629 }, { 691, 660 }, { 784, 753 }, { 815, 784 }, - { 908, 877 }, { 939, 908 }, { 413, 382 }, { 444, 413 }, - { 475, 444 }, { 537, 506 }, { 568, 537 }, { 599, 568 }, - { 661, 630 }, { 692, 661 }, { 723, 692 }, { 785, 754 }, - { 816, 785 }, { 847, 816 }, { 909, 878 }, { 940, 909 }, - { 971, 940 }, { 414, 383 }, { 445, 414 }, { 476, 445 }, - { 507, 476 }, { 538, 507 }, { 569, 538 }, { 600, 569 }, - { 631, 600 }, { 662, 631 }, { 693, 662 }, { 724, 693 }, - { 755, 724 }, { 786, 755 }, { 817, 786 }, { 848, 817 }, - { 879, 848 }, { 910, 879 }, { 941, 910 }, { 972, 941 }, - { 1003, 972 }, { 446, 415 }, { 477, 446 }, { 508, 477 }, - { 570, 539 }, { 601, 570 }, { 632, 601 }, { 694, 663 }, - { 725, 694 }, { 756, 725 }, { 818, 787 }, { 849, 818 }, - { 880, 849 }, { 942, 911 }, { 973, 942 }, { 1004, 973 }, - { 478, 447 }, { 509, 478 }, { 602, 571 }, { 633, 602 }, - { 726, 695 }, { 757, 726 }, { 850, 819 }, { 881, 850 }, - { 974, 943 }, { 1005, 974 }, { 510, 479 }, { 634, 603 }, - { 758, 727 }, { 882, 851 }, { 1006, 975 }, { 539, 508 }, - { 663, 632 }, { 787, 756 }, { 911, 880 }, { 540, 509 }, - { 571, 540 }, { 664, 633 }, { 695, 664 }, { 788, 757 }, - { 819, 788 }, { 912, 881 }, { 943, 912 }, { 541, 510 }, - { 572, 541 }, { 603, 572 }, { 665, 634 }, { 696, 665 }, - { 727, 696 }, { 789, 758 }, { 820, 789 }, { 851, 820 }, - { 913, 882 }, { 944, 913 }, { 975, 944 }, { 542, 511 }, - { 573, 542 }, { 604, 573 }, { 635, 604 }, { 666, 635 }, - { 697, 666 }, { 728, 697 }, { 759, 728 }, { 790, 759 }, - { 821, 790 }, { 852, 821 }, { 883, 852 }, { 914, 883 }, - { 945, 914 }, { 976, 945 }, { 1007, 976 }, { 574, 543 }, - { 605, 574 }, { 636, 605 }, { 698, 667 }, { 729, 698 }, - { 760, 729 }, { 822, 791 }, { 853, 822 }, { 884, 853 }, - { 946, 915 }, { 977, 946 }, { 1008, 977 }, { 606, 575 }, - { 637, 606 }, { 730, 699 }, { 761, 730 }, { 854, 823 }, - { 885, 854 }, { 978, 947 }, { 1009, 978 }, { 638, 607 }, - { 762, 731 }, { 886, 855 }, { 1010, 979 }, { 667, 636 }, - { 791, 760 }, { 915, 884 }, { 668, 637 }, { 699, 668 }, - { 792, 761 }, { 823, 792 }, { 916, 885 }, { 947, 916 }, - { 669, 638 }, { 700, 669 }, { 731, 700 }, { 793, 762 }, - { 824, 793 }, { 855, 824 }, { 917, 886 }, { 948, 917 }, - { 979, 948 }, { 670, 639 }, { 701, 670 }, { 732, 701 }, - { 763, 732 }, { 794, 763 }, { 825, 794 }, { 856, 825 }, - { 887, 856 }, { 918, 887 }, { 949, 918 }, { 980, 949 }, - { 1011, 980 }, { 702, 671 }, { 733, 702 }, { 764, 733 }, - { 826, 795 }, { 857, 826 }, { 888, 857 }, { 950, 919 }, - { 981, 950 }, { 1012, 981 }, { 734, 703 }, { 765, 734 }, - { 858, 827 }, { 889, 858 }, { 982, 951 }, { 1013, 982 }, - { 766, 735 }, { 890, 859 }, { 1014, 983 }, { 795, 764 }, - { 919, 888 }, { 796, 765 }, { 827, 796 }, { 920, 889 }, - { 951, 920 }, { 797, 766 }, { 828, 797 }, { 859, 828 }, - { 921, 890 }, { 952, 921 }, { 983, 952 }, { 798, 767 }, - { 829, 798 }, { 860, 829 }, { 891, 860 }, { 922, 891 }, - { 953, 922 }, { 984, 953 }, { 1015, 984 }, { 830, 799 }, - { 861, 830 }, { 892, 861 }, { 954, 923 }, { 985, 954 }, - { 1016, 985 }, { 862, 831 }, { 893, 862 }, { 986, 955 }, - { 1017, 986 }, { 894, 863 }, { 1018, 987 }, { 923, 892 }, - { 924, 893 }, { 955, 924 }, { 925, 894 }, { 956, 925 }, - { 987, 956 }, { 926, 895 }, { 957, 926 }, { 988, 957 }, - { 1019, 988 }, { 958, 927 }, { 989, 958 }, { 1020, 989 }, - { 990, 959 }, { 1021, 990 }, { 1022, 991 }, { 0, 0 }, -}; - -static const int16_t (* const vp9_scans_nb[5][4])[2] = { - { - vp9_default_scan_4x4_nb, vp9_col_scan_4x4_nb, - vp9_row_scan_4x4_nb, vp9_default_scan_4x4_nb - }, { - vp9_default_scan_8x8_nb, vp9_col_scan_8x8_nb, - vp9_row_scan_8x8_nb, vp9_default_scan_8x8_nb - }, { - vp9_default_scan_16x16_nb, vp9_col_scan_16x16_nb, - vp9_row_scan_16x16_nb, vp9_default_scan_16x16_nb - }, { - vp9_default_scan_32x32_nb, vp9_default_scan_32x32_nb, - vp9_default_scan_32x32_nb, vp9_default_scan_32x32_nb - }, { // lossless - vp9_default_scan_4x4_nb, vp9_default_scan_4x4_nb, - vp9_default_scan_4x4_nb, vp9_default_scan_4x4_nb - } -}; - -static const uint8_t vp9_model_pareto8[256][8] = { - { 6, 86, 128, 11, 87, 42, 91, 52 }, - { 3, 86, 128, 6, 86, 23, 88, 29 }, - { 6, 86, 128, 11, 87, 42, 91, 52 }, - { 9, 86, 129, 17, 88, 61, 94, 76 }, - { 12, 86, 129, 22, 88, 77, 97, 93 }, - { 15, 87, 129, 28, 89, 93, 100, 110 }, - { 17, 87, 129, 33, 90, 105, 103, 123 }, - { 20, 88, 130, 38, 91, 118, 106, 136 }, - { 23, 88, 130, 43, 91, 128, 108, 146 }, - { 26, 89, 131, 48, 92, 139, 111, 156 }, - { 28, 89, 131, 53, 93, 147, 114, 163 }, - { 31, 90, 131, 58, 94, 156, 117, 171 }, - { 34, 90, 131, 62, 94, 163, 119, 177 }, - { 37, 90, 132, 66, 95, 171, 122, 184 }, - { 39, 90, 132, 70, 96, 177, 124, 189 }, - { 42, 91, 132, 75, 97, 183, 127, 194 }, - { 44, 91, 132, 79, 97, 188, 129, 198 }, - { 47, 92, 133, 83, 98, 193, 132, 202 }, - { 49, 92, 133, 86, 99, 197, 134, 205 }, - { 52, 93, 133, 90, 100, 201, 137, 208 }, - { 54, 93, 133, 94, 100, 204, 139, 211 }, - { 57, 94, 134, 98, 101, 208, 142, 214 }, - { 59, 94, 134, 101, 102, 211, 144, 216 }, - { 62, 94, 135, 105, 103, 214, 146, 218 }, - { 64, 94, 135, 108, 103, 216, 148, 220 }, - { 66, 95, 135, 111, 104, 219, 151, 222 }, - { 68, 95, 135, 114, 105, 221, 153, 223 }, - { 71, 96, 136, 117, 106, 224, 155, 225 }, - { 73, 96, 136, 120, 106, 225, 157, 226 }, - { 76, 97, 136, 123, 107, 227, 159, 228 }, - { 78, 97, 136, 126, 108, 229, 160, 229 }, - { 80, 98, 137, 129, 109, 231, 162, 231 }, - { 82, 98, 137, 131, 109, 232, 164, 232 }, - { 84, 98, 138, 134, 110, 234, 166, 233 }, - { 86, 98, 138, 137, 111, 235, 168, 234 }, - { 89, 99, 138, 140, 112, 236, 170, 235 }, - { 91, 99, 138, 142, 112, 237, 171, 235 }, - { 93, 100, 139, 145, 113, 238, 173, 236 }, - { 95, 100, 139, 147, 114, 239, 174, 237 }, - { 97, 101, 140, 149, 115, 240, 176, 238 }, - { 99, 101, 140, 151, 115, 241, 177, 238 }, - { 101, 102, 140, 154, 116, 242, 179, 239 }, - { 103, 102, 140, 156, 117, 242, 180, 239 }, - { 105, 103, 141, 158, 118, 243, 182, 240 }, - { 107, 103, 141, 160, 118, 243, 183, 240 }, - { 109, 104, 141, 162, 119, 244, 185, 241 }, - { 111, 104, 141, 164, 119, 244, 186, 241 }, - { 113, 104, 142, 166, 120, 245, 187, 242 }, - { 114, 104, 142, 168, 121, 245, 188, 242 }, - { 116, 105, 143, 170, 122, 246, 190, 243 }, - { 118, 105, 143, 171, 122, 246, 191, 243 }, - { 120, 106, 143, 173, 123, 247, 192, 244 }, - { 121, 106, 143, 175, 124, 247, 193, 244 }, - { 123, 107, 144, 177, 125, 248, 195, 244 }, - { 125, 107, 144, 178, 125, 248, 196, 244 }, - { 127, 108, 145, 180, 126, 249, 197, 245 }, - { 128, 108, 145, 181, 127, 249, 198, 245 }, - { 130, 109, 145, 183, 128, 249, 199, 245 }, - { 132, 109, 145, 184, 128, 249, 200, 245 }, - { 134, 110, 146, 186, 129, 250, 201, 246 }, - { 135, 110, 146, 187, 130, 250, 202, 246 }, - { 137, 111, 147, 189, 131, 251, 203, 246 }, - { 138, 111, 147, 190, 131, 251, 204, 246 }, - { 140, 112, 147, 192, 132, 251, 205, 247 }, - { 141, 112, 147, 193, 132, 251, 206, 247 }, - { 143, 113, 148, 194, 133, 251, 207, 247 }, - { 144, 113, 148, 195, 134, 251, 207, 247 }, - { 146, 114, 149, 197, 135, 252, 208, 248 }, - { 147, 114, 149, 198, 135, 252, 209, 248 }, - { 149, 115, 149, 199, 136, 252, 210, 248 }, - { 150, 115, 149, 200, 137, 252, 210, 248 }, - { 152, 115, 150, 201, 138, 252, 211, 248 }, - { 153, 115, 150, 202, 138, 252, 212, 248 }, - { 155, 116, 151, 204, 139, 253, 213, 249 }, - { 156, 116, 151, 205, 139, 253, 213, 249 }, - { 158, 117, 151, 206, 140, 253, 214, 249 }, - { 159, 117, 151, 207, 141, 253, 215, 249 }, - { 161, 118, 152, 208, 142, 253, 216, 249 }, - { 162, 118, 152, 209, 142, 253, 216, 249 }, - { 163, 119, 153, 210, 143, 253, 217, 249 }, - { 164, 119, 153, 211, 143, 253, 217, 249 }, - { 166, 120, 153, 212, 144, 254, 218, 250 }, - { 167, 120, 153, 212, 145, 254, 219, 250 }, - { 168, 121, 154, 213, 146, 254, 220, 250 }, - { 169, 121, 154, 214, 146, 254, 220, 250 }, - { 171, 122, 155, 215, 147, 254, 221, 250 }, - { 172, 122, 155, 216, 147, 254, 221, 250 }, - { 173, 123, 155, 217, 148, 254, 222, 250 }, - { 174, 123, 155, 217, 149, 254, 222, 250 }, - { 176, 124, 156, 218, 150, 254, 223, 250 }, - { 177, 124, 156, 219, 150, 254, 223, 250 }, - { 178, 125, 157, 220, 151, 254, 224, 251 }, - { 179, 125, 157, 220, 151, 254, 224, 251 }, - { 180, 126, 157, 221, 152, 254, 225, 251 }, - { 181, 126, 157, 221, 152, 254, 225, 251 }, - { 183, 127, 158, 222, 153, 254, 226, 251 }, - { 184, 127, 158, 223, 154, 254, 226, 251 }, - { 185, 128, 159, 224, 155, 255, 227, 251 }, - { 186, 128, 159, 224, 155, 255, 227, 251 }, - { 187, 129, 160, 225, 156, 255, 228, 251 }, - { 188, 130, 160, 225, 156, 255, 228, 251 }, - { 189, 131, 160, 226, 157, 255, 228, 251 }, - { 190, 131, 160, 226, 158, 255, 228, 251 }, - { 191, 132, 161, 227, 159, 255, 229, 251 }, - { 192, 132, 161, 227, 159, 255, 229, 251 }, - { 193, 133, 162, 228, 160, 255, 230, 252 }, - { 194, 133, 162, 229, 160, 255, 230, 252 }, - { 195, 134, 163, 230, 161, 255, 231, 252 }, - { 196, 134, 163, 230, 161, 255, 231, 252 }, - { 197, 135, 163, 231, 162, 255, 231, 252 }, - { 198, 135, 163, 231, 162, 255, 231, 252 }, - { 199, 136, 164, 232, 163, 255, 232, 252 }, - { 200, 136, 164, 232, 164, 255, 232, 252 }, - { 201, 137, 165, 233, 165, 255, 233, 252 }, - { 201, 137, 165, 233, 165, 255, 233, 252 }, - { 202, 138, 166, 233, 166, 255, 233, 252 }, - { 203, 138, 166, 233, 166, 255, 233, 252 }, - { 204, 139, 166, 234, 167, 255, 234, 252 }, - { 205, 139, 166, 234, 167, 255, 234, 252 }, - { 206, 140, 167, 235, 168, 255, 235, 252 }, - { 206, 140, 167, 235, 168, 255, 235, 252 }, - { 207, 141, 168, 236, 169, 255, 235, 252 }, - { 208, 141, 168, 236, 170, 255, 235, 252 }, - { 209, 142, 169, 237, 171, 255, 236, 252 }, - { 209, 143, 169, 237, 171, 255, 236, 252 }, - { 210, 144, 169, 237, 172, 255, 236, 252 }, - { 211, 144, 169, 237, 172, 255, 236, 252 }, - { 212, 145, 170, 238, 173, 255, 237, 252 }, - { 213, 145, 170, 238, 173, 255, 237, 252 }, - { 214, 146, 171, 239, 174, 255, 237, 253 }, - { 214, 146, 171, 239, 174, 255, 237, 253 }, - { 215, 147, 172, 240, 175, 255, 238, 253 }, - { 215, 147, 172, 240, 175, 255, 238, 253 }, - { 216, 148, 173, 240, 176, 255, 238, 253 }, - { 217, 148, 173, 240, 176, 255, 238, 253 }, - { 218, 149, 173, 241, 177, 255, 239, 253 }, - { 218, 149, 173, 241, 178, 255, 239, 253 }, - { 219, 150, 174, 241, 179, 255, 239, 253 }, - { 219, 151, 174, 241, 179, 255, 239, 253 }, - { 220, 152, 175, 242, 180, 255, 240, 253 }, - { 221, 152, 175, 242, 180, 255, 240, 253 }, - { 222, 153, 176, 242, 181, 255, 240, 253 }, - { 222, 153, 176, 242, 181, 255, 240, 253 }, - { 223, 154, 177, 243, 182, 255, 240, 253 }, - { 223, 154, 177, 243, 182, 255, 240, 253 }, - { 224, 155, 178, 244, 183, 255, 241, 253 }, - { 224, 155, 178, 244, 183, 255, 241, 253 }, - { 225, 156, 178, 244, 184, 255, 241, 253 }, - { 225, 157, 178, 244, 184, 255, 241, 253 }, - { 226, 158, 179, 244, 185, 255, 242, 253 }, - { 227, 158, 179, 244, 185, 255, 242, 253 }, - { 228, 159, 180, 245, 186, 255, 242, 253 }, - { 228, 159, 180, 245, 186, 255, 242, 253 }, - { 229, 160, 181, 245, 187, 255, 242, 253 }, - { 229, 160, 181, 245, 187, 255, 242, 253 }, - { 230, 161, 182, 246, 188, 255, 243, 253 }, - { 230, 162, 182, 246, 188, 255, 243, 253 }, - { 231, 163, 183, 246, 189, 255, 243, 253 }, - { 231, 163, 183, 246, 189, 255, 243, 253 }, - { 232, 164, 184, 247, 190, 255, 243, 253 }, - { 232, 164, 184, 247, 190, 255, 243, 253 }, - { 233, 165, 185, 247, 191, 255, 244, 253 }, - { 233, 165, 185, 247, 191, 255, 244, 253 }, - { 234, 166, 185, 247, 192, 255, 244, 253 }, - { 234, 167, 185, 247, 192, 255, 244, 253 }, - { 235, 168, 186, 248, 193, 255, 244, 253 }, - { 235, 168, 186, 248, 193, 255, 244, 253 }, - { 236, 169, 187, 248, 194, 255, 244, 253 }, - { 236, 169, 187, 248, 194, 255, 244, 253 }, - { 236, 170, 188, 248, 195, 255, 245, 253 }, - { 236, 170, 188, 248, 195, 255, 245, 253 }, - { 237, 171, 189, 249, 196, 255, 245, 254 }, - { 237, 172, 189, 249, 196, 255, 245, 254 }, - { 238, 173, 190, 249, 197, 255, 245, 254 }, - { 238, 173, 190, 249, 197, 255, 245, 254 }, - { 239, 174, 191, 249, 198, 255, 245, 254 }, - { 239, 174, 191, 249, 198, 255, 245, 254 }, - { 240, 175, 192, 249, 199, 255, 246, 254 }, - { 240, 176, 192, 249, 199, 255, 246, 254 }, - { 240, 177, 193, 250, 200, 255, 246, 254 }, - { 240, 177, 193, 250, 200, 255, 246, 254 }, - { 241, 178, 194, 250, 201, 255, 246, 254 }, - { 241, 178, 194, 250, 201, 255, 246, 254 }, - { 242, 179, 195, 250, 202, 255, 246, 254 }, - { 242, 180, 195, 250, 202, 255, 246, 254 }, - { 242, 181, 196, 250, 203, 255, 247, 254 }, - { 242, 181, 196, 250, 203, 255, 247, 254 }, - { 243, 182, 197, 251, 204, 255, 247, 254 }, - { 243, 183, 197, 251, 204, 255, 247, 254 }, - { 244, 184, 198, 251, 205, 255, 247, 254 }, - { 244, 184, 198, 251, 205, 255, 247, 254 }, - { 244, 185, 199, 251, 206, 255, 247, 254 }, - { 244, 185, 199, 251, 206, 255, 247, 254 }, - { 245, 186, 200, 251, 207, 255, 247, 254 }, - { 245, 187, 200, 251, 207, 255, 247, 254 }, - { 246, 188, 201, 252, 207, 255, 248, 254 }, - { 246, 188, 201, 252, 207, 255, 248, 254 }, - { 246, 189, 202, 252, 208, 255, 248, 254 }, - { 246, 190, 202, 252, 208, 255, 248, 254 }, - { 247, 191, 203, 252, 209, 255, 248, 254 }, - { 247, 191, 203, 252, 209, 255, 248, 254 }, - { 247, 192, 204, 252, 210, 255, 248, 254 }, - { 247, 193, 204, 252, 210, 255, 248, 254 }, - { 248, 194, 205, 252, 211, 255, 248, 254 }, - { 248, 194, 205, 252, 211, 255, 248, 254 }, - { 248, 195, 206, 252, 212, 255, 249, 254 }, - { 248, 196, 206, 252, 212, 255, 249, 254 }, - { 249, 197, 207, 253, 213, 255, 249, 254 }, - { 249, 197, 207, 253, 213, 255, 249, 254 }, - { 249, 198, 208, 253, 214, 255, 249, 254 }, - { 249, 199, 209, 253, 214, 255, 249, 254 }, - { 250, 200, 210, 253, 215, 255, 249, 254 }, - { 250, 200, 210, 253, 215, 255, 249, 254 }, - { 250, 201, 211, 253, 215, 255, 249, 254 }, - { 250, 202, 211, 253, 215, 255, 249, 254 }, - { 250, 203, 212, 253, 216, 255, 249, 254 }, - { 250, 203, 212, 253, 216, 255, 249, 254 }, - { 251, 204, 213, 253, 217, 255, 250, 254 }, - { 251, 205, 213, 253, 217, 255, 250, 254 }, - { 251, 206, 214, 254, 218, 255, 250, 254 }, - { 251, 206, 215, 254, 218, 255, 250, 254 }, - { 252, 207, 216, 254, 219, 255, 250, 254 }, - { 252, 208, 216, 254, 219, 255, 250, 254 }, - { 252, 209, 217, 254, 220, 255, 250, 254 }, - { 252, 210, 217, 254, 220, 255, 250, 254 }, - { 252, 211, 218, 254, 221, 255, 250, 254 }, - { 252, 212, 218, 254, 221, 255, 250, 254 }, - { 253, 213, 219, 254, 222, 255, 250, 254 }, - { 253, 213, 220, 254, 222, 255, 250, 254 }, - { 253, 214, 221, 254, 223, 255, 250, 254 }, - { 253, 215, 221, 254, 223, 255, 250, 254 }, - { 253, 216, 222, 254, 224, 255, 251, 254 }, - { 253, 217, 223, 254, 224, 255, 251, 254 }, - { 253, 218, 224, 254, 225, 255, 251, 254 }, - { 253, 219, 224, 254, 225, 255, 251, 254 }, - { 254, 220, 225, 254, 225, 255, 251, 254 }, - { 254, 221, 226, 254, 225, 255, 251, 254 }, - { 254, 222, 227, 255, 226, 255, 251, 254 }, - { 254, 223, 227, 255, 226, 255, 251, 254 }, - { 254, 224, 228, 255, 227, 255, 251, 254 }, - { 254, 225, 229, 255, 227, 255, 251, 254 }, - { 254, 226, 230, 255, 228, 255, 251, 254 }, - { 254, 227, 230, 255, 229, 255, 251, 254 }, - { 255, 228, 231, 255, 230, 255, 251, 254 }, - { 255, 229, 232, 255, 230, 255, 251, 254 }, - { 255, 230, 233, 255, 231, 255, 252, 254 }, - { 255, 231, 234, 255, 231, 255, 252, 254 }, - { 255, 232, 235, 255, 232, 255, 252, 254 }, - { 255, 233, 236, 255, 232, 255, 252, 254 }, - { 255, 235, 237, 255, 233, 255, 252, 254 }, - { 255, 236, 238, 255, 234, 255, 252, 254 }, - { 255, 238, 240, 255, 235, 255, 252, 255 }, - { 255, 239, 241, 255, 235, 255, 252, 254 }, - { 255, 241, 243, 255, 236, 255, 252, 254 }, - { 255, 243, 245, 255, 237, 255, 252, 254 }, - { 255, 246, 247, 255, 239, 255, 253, 255 }, -}; - -typedef struct { - uint8_t y_mode[4][9]; - uint8_t uv_mode[10][9]; - uint8_t filter[4][2]; - uint8_t mv_mode[7][3]; - uint8_t intra[4]; - uint8_t comp[5]; - uint8_t single_ref[5][2]; - uint8_t comp_ref[5]; - uint8_t tx32p[2][3]; - uint8_t tx16p[2][2]; - uint8_t tx8p[2]; - uint8_t skip[3]; - uint8_t mv_joint[3]; - struct { - uint8_t sign; - uint8_t classes[10]; - uint8_t class0; - uint8_t bits[10]; - uint8_t class0_fp[2][3]; - uint8_t fp[3]; - uint8_t class0_hp; - uint8_t hp; - } mv_comp[2]; - uint8_t partition[4][4][3]; -} prob_context; - -static const prob_context vp9_default_probs = { - { /* y_mode */ - { 65, 32, 18, 144, 162, 194, 41, 51, 98 } /* bsize < 8x8 */, - { 132, 68, 18, 165, 217, 196, 45, 40, 78 } /* bsize < 16x16 */, - { 173, 80, 19, 176, 240, 193, 64, 35, 46 } /* bsize < 32x32 */, - { 221, 135, 38, 194, 248, 121, 96, 85, 29 } /* bsize >= 32x32 */ - }, { /* uv_mode */ - { 48, 12, 154, 155, 139, 90, 34, 117, 119 } /* y = v */, - { 67, 6, 25, 204, 243, 158, 13, 21, 96 } /* y = h */, - { 120, 7, 76, 176, 208, 126, 28, 54, 103 } /* y = dc */, - { 97, 5, 44, 131, 176, 139, 48, 68, 97 } /* y = d45 */, - { 83, 5, 42, 156, 111, 152, 26, 49, 152 } /* y = d135 */, - { 80, 5, 58, 178, 74, 83, 33, 62, 145 } /* y = d117 */, - { 86, 5, 32, 154, 192, 168, 14, 22, 163 } /* y = d153 */, - { 77, 7, 64, 116, 132, 122, 37, 126, 120 } /* y = d63 */, - { 85, 5, 32, 156, 216, 148, 19, 29, 73 } /* y = d27 */, - { 101, 21, 107, 181, 192, 103, 19, 67, 125 } /* y = tm */ - }, { /* filter */ - { 235, 162, }, - { 36, 255, }, - { 34, 3, }, - { 149, 144, }, - }, { /* mv_mode */ - { 2, 173, 34}, // 0 = both zero mv - { 7, 145, 85}, // 1 = one zero mv + one a predicted mv - { 7, 166, 63}, // 2 = two predicted mvs - { 7, 94, 66}, // 3 = one predicted/zero and one new mv - { 8, 64, 46}, // 4 = two new mvs - { 17, 81, 31}, // 5 = one intra neighbour + x - { 25, 29, 30}, // 6 = two intra neighbours - }, { /* intra */ - 9, 102, 187, 225 - }, { /* comp */ - 239, 183, 119, 96, 41 - }, { /* single_ref */ - { 33, 16 }, - { 77, 74 }, - { 142, 142 }, - { 172, 170 }, - { 238, 247 } - }, { /* comp_ref */ - 50, 126, 123, 221, 226 - }, { /* tx32p */ - { 3, 136, 37, }, - { 5, 52, 13, }, - }, { /* tx16p */ - { 20, 152, }, - { 15, 101, }, - }, { /* tx8p */ - 100, 66 - }, { /* skip */ - 192, 128, 64 - }, { /* mv_joint */ - 32, 64, 96 - }, { - { /* mv vertical component */ - 128, /* sign */ - { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, /* class */ - 216, /* class0 */ - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240}, /* bits */ - { /* class0_fp */ - { 128, 128, 64 }, - { 96, 112, 64 } - }, - { 64, 96, 64 }, /* fp */ - 160, /* class0_hp bit */ - 128, /* hp */ - }, { /* mv horizontal component */ - 128, /* sign */ - { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, /* class */ - 208, /* class0 */ - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */ - { /* class0_fp */ - { 128, 128, 64 }, - { 96, 112, 64 } - }, - { 64, 96, 64 }, /* fp */ - 160, /* class0_hp bit */ - 128, /* hp */ - } - }, { /* partition */ - { /* 64x64 -> 32x32 */ - { 222, 34, 30 } /* a/l both not split */, - { 72, 16, 44 } /* a split, l not split */, - { 58, 32, 12 } /* l split, a not split */, - { 10, 7, 6 } /* a/l both split */, - }, { /* 32x32 -> 16x16 */ - { 177, 58, 59 } /* a/l both not split */, - { 68, 26, 63 } /* a split, l not split */, - { 52, 79, 25 } /* l split, a not split */, - { 17, 14, 12 } /* a/l both split */, - }, { /* 16x16 -> 8x8 */ - { 174, 73, 87 } /* a/l both not split */, - { 92, 41, 83 } /* a split, l not split */, - { 82, 99, 50 } /* l split, a not split */, - { 53, 39, 39 } /* a/l both split */, - }, { /* 8x8 -> 4x4 */ - { 199, 122, 141 } /* a/l both not split */, - { 147, 63, 159 } /* a split, l not split */, - { 148, 133, 118 } /* l split, a not split */, - { 121, 104, 114 } /* a/l both split */, - } - }, -}; - -static const uint8_t vp9_default_coef_probs[4][2][2][6][6][3] = { - { /* tx = 4x4 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 195, 29, 183 }, - { 84, 49, 136 }, - { 8, 42, 71 } - }, { /* Coeff Band 1 */ - { 31, 107, 169 }, - { 35, 99, 159 }, - { 17, 82, 140 }, - { 8, 66, 114 }, - { 2, 44, 76 }, - { 1, 19, 32 } - }, { /* Coeff Band 2 */ - { 40, 132, 201 }, - { 29, 114, 187 }, - { 13, 91, 157 }, - { 7, 75, 127 }, - { 3, 58, 95 }, - { 1, 28, 47 } - }, { /* Coeff Band 3 */ - { 69, 142, 221 }, - { 42, 122, 201 }, - { 15, 91, 159 }, - { 6, 67, 121 }, - { 1, 42, 77 }, - { 1, 17, 31 } - }, { /* Coeff Band 4 */ - { 102, 148, 228 }, - { 67, 117, 204 }, - { 17, 82, 154 }, - { 6, 59, 114 }, - { 2, 39, 75 }, - { 1, 15, 29 } - }, { /* Coeff Band 5 */ - { 156, 57, 233 }, - { 119, 57, 212 }, - { 58, 48, 163 }, - { 29, 40, 124 }, - { 12, 30, 81 }, - { 3, 12, 31 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 191, 107, 226 }, - { 124, 117, 204 }, - { 25, 99, 155 } - }, { /* Coeff Band 1 */ - { 29, 148, 210 }, - { 37, 126, 194 }, - { 8, 93, 157 }, - { 2, 68, 118 }, - { 1, 39, 69 }, - { 1, 17, 33 } - }, { /* Coeff Band 2 */ - { 41, 151, 213 }, - { 27, 123, 193 }, - { 3, 82, 144 }, - { 1, 58, 105 }, - { 1, 32, 60 }, - { 1, 13, 26 } - }, { /* Coeff Band 3 */ - { 59, 159, 220 }, - { 23, 126, 198 }, - { 4, 88, 151 }, - { 1, 66, 114 }, - { 1, 38, 71 }, - { 1, 18, 34 } - }, { /* Coeff Band 4 */ - { 114, 136, 232 }, - { 51, 114, 207 }, - { 11, 83, 155 }, - { 3, 56, 105 }, - { 1, 33, 65 }, - { 1, 17, 34 } - }, { /* Coeff Band 5 */ - { 149, 65, 234 }, - { 121, 57, 215 }, - { 61, 49, 166 }, - { 28, 36, 114 }, - { 12, 25, 76 }, - { 3, 16, 42 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 214, 49, 220 }, - { 132, 63, 188 }, - { 42, 65, 137 } - }, { /* Coeff Band 1 */ - { 85, 137, 221 }, - { 104, 131, 216 }, - { 49, 111, 192 }, - { 21, 87, 155 }, - { 2, 49, 87 }, - { 1, 16, 28 } - }, { /* Coeff Band 2 */ - { 89, 163, 230 }, - { 90, 137, 220 }, - { 29, 100, 183 }, - { 10, 70, 135 }, - { 2, 42, 81 }, - { 1, 17, 33 } - }, { /* Coeff Band 3 */ - { 108, 167, 237 }, - { 55, 133, 222 }, - { 15, 97, 179 }, - { 4, 72, 135 }, - { 1, 45, 85 }, - { 1, 19, 38 } - }, { /* Coeff Band 4 */ - { 124, 146, 240 }, - { 66, 124, 224 }, - { 17, 88, 175 }, - { 4, 58, 122 }, - { 1, 36, 75 }, - { 1, 18, 37 } - }, { /* Coeff Band 5 */ - { 141, 79, 241 }, - { 126, 70, 227 }, - { 66, 58, 182 }, - { 30, 44, 136 }, - { 12, 34, 96 }, - { 2, 20, 47 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 229, 99, 249 }, - { 143, 111, 235 }, - { 46, 109, 192 } - }, { /* Coeff Band 1 */ - { 82, 158, 236 }, - { 94, 146, 224 }, - { 25, 117, 191 }, - { 9, 87, 149 }, - { 3, 56, 99 }, - { 1, 33, 57 } - }, { /* Coeff Band 2 */ - { 83, 167, 237 }, - { 68, 145, 222 }, - { 10, 103, 177 }, - { 2, 72, 131 }, - { 1, 41, 79 }, - { 1, 20, 39 } - }, { /* Coeff Band 3 */ - { 99, 167, 239 }, - { 47, 141, 224 }, - { 10, 104, 178 }, - { 2, 73, 133 }, - { 1, 44, 85 }, - { 1, 22, 47 } - }, { /* Coeff Band 4 */ - { 127, 145, 243 }, - { 71, 129, 228 }, - { 17, 93, 177 }, - { 3, 61, 124 }, - { 1, 41, 84 }, - { 1, 21, 52 } - }, { /* Coeff Band 5 */ - { 157, 78, 244 }, - { 140, 72, 231 }, - { 69, 58, 184 }, - { 31, 44, 137 }, - { 14, 38, 105 }, - { 8, 23, 61 } - } - } - } - }, { /* tx = 8x8 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 125, 34, 187 }, - { 52, 41, 133 }, - { 6, 31, 56 } - }, { /* Coeff Band 1 */ - { 37, 109, 153 }, - { 51, 102, 147 }, - { 23, 87, 128 }, - { 8, 67, 101 }, - { 1, 41, 63 }, - { 1, 19, 29 } - }, { /* Coeff Band 2 */ - { 31, 154, 185 }, - { 17, 127, 175 }, - { 6, 96, 145 }, - { 2, 73, 114 }, - { 1, 51, 82 }, - { 1, 28, 45 } - }, { /* Coeff Band 3 */ - { 23, 163, 200 }, - { 10, 131, 185 }, - { 2, 93, 148 }, - { 1, 67, 111 }, - { 1, 41, 69 }, - { 1, 14, 24 } - }, { /* Coeff Band 4 */ - { 29, 176, 217 }, - { 12, 145, 201 }, - { 3, 101, 156 }, - { 1, 69, 111 }, - { 1, 39, 63 }, - { 1, 14, 23 } - }, { /* Coeff Band 5 */ - { 57, 192, 233 }, - { 25, 154, 215 }, - { 6, 109, 167 }, - { 3, 78, 118 }, - { 1, 48, 69 }, - { 1, 21, 29 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 202, 105, 245 }, - { 108, 106, 216 }, - { 18, 90, 144 } - }, { /* Coeff Band 1 */ - { 33, 172, 219 }, - { 64, 149, 206 }, - { 14, 117, 177 }, - { 5, 90, 141 }, - { 2, 61, 95 }, - { 1, 37, 57 } - }, { /* Coeff Band 2 */ - { 33, 179, 220 }, - { 11, 140, 198 }, - { 1, 89, 148 }, - { 1, 60, 104 }, - { 1, 33, 57 }, - { 1, 12, 21 } - }, { /* Coeff Band 3 */ - { 30, 181, 221 }, - { 8, 141, 198 }, - { 1, 87, 145 }, - { 1, 58, 100 }, - { 1, 31, 55 }, - { 1, 12, 20 } - }, { /* Coeff Band 4 */ - { 32, 186, 224 }, - { 7, 142, 198 }, - { 1, 86, 143 }, - { 1, 58, 100 }, - { 1, 31, 55 }, - { 1, 12, 22 } - }, { /* Coeff Band 5 */ - { 57, 192, 227 }, - { 20, 143, 204 }, - { 3, 96, 154 }, - { 1, 68, 112 }, - { 1, 42, 69 }, - { 1, 19, 32 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 212, 35, 215 }, - { 113, 47, 169 }, - { 29, 48, 105 } - }, { /* Coeff Band 1 */ - { 74, 129, 203 }, - { 106, 120, 203 }, - { 49, 107, 178 }, - { 19, 84, 144 }, - { 4, 50, 84 }, - { 1, 15, 25 } - }, { /* Coeff Band 2 */ - { 71, 172, 217 }, - { 44, 141, 209 }, - { 15, 102, 173 }, - { 6, 76, 133 }, - { 2, 51, 89 }, - { 1, 24, 42 } - }, { /* Coeff Band 3 */ - { 64, 185, 231 }, - { 31, 148, 216 }, - { 8, 103, 175 }, - { 3, 74, 131 }, - { 1, 46, 81 }, - { 1, 18, 30 } - }, { /* Coeff Band 4 */ - { 65, 196, 235 }, - { 25, 157, 221 }, - { 5, 105, 174 }, - { 1, 67, 120 }, - { 1, 38, 69 }, - { 1, 15, 30 } - }, { /* Coeff Band 5 */ - { 65, 204, 238 }, - { 30, 156, 224 }, - { 7, 107, 177 }, - { 2, 70, 124 }, - { 1, 42, 73 }, - { 1, 18, 34 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 225, 86, 251 }, - { 144, 104, 235 }, - { 42, 99, 181 } - }, { /* Coeff Band 1 */ - { 85, 175, 239 }, - { 112, 165, 229 }, - { 29, 136, 200 }, - { 12, 103, 162 }, - { 6, 77, 123 }, - { 2, 53, 84 } - }, { /* Coeff Band 2 */ - { 75, 183, 239 }, - { 30, 155, 221 }, - { 3, 106, 171 }, - { 1, 74, 128 }, - { 1, 44, 76 }, - { 1, 17, 28 } - }, { /* Coeff Band 3 */ - { 73, 185, 240 }, - { 27, 159, 222 }, - { 2, 107, 172 }, - { 1, 75, 127 }, - { 1, 42, 73 }, - { 1, 17, 29 } - }, { /* Coeff Band 4 */ - { 62, 190, 238 }, - { 21, 159, 222 }, - { 2, 107, 172 }, - { 1, 72, 122 }, - { 1, 40, 71 }, - { 1, 18, 32 } - }, { /* Coeff Band 5 */ - { 61, 199, 240 }, - { 27, 161, 226 }, - { 4, 113, 180 }, - { 1, 76, 129 }, - { 1, 46, 80 }, - { 1, 23, 41 } - } - } - } - }, { /* tx = 16x16 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 7, 27, 153 }, - { 5, 30, 95 }, - { 1, 16, 30 } - }, { /* Coeff Band 1 */ - { 50, 75, 127 }, - { 57, 75, 124 }, - { 27, 67, 108 }, - { 10, 54, 86 }, - { 1, 33, 52 }, - { 1, 12, 18 } - }, { /* Coeff Band 2 */ - { 43, 125, 151 }, - { 26, 108, 148 }, - { 7, 83, 122 }, - { 2, 59, 89 }, - { 1, 38, 60 }, - { 1, 17, 27 } - }, { /* Coeff Band 3 */ - { 23, 144, 163 }, - { 13, 112, 154 }, - { 2, 75, 117 }, - { 1, 50, 81 }, - { 1, 31, 51 }, - { 1, 14, 23 } - }, { /* Coeff Band 4 */ - { 18, 162, 185 }, - { 6, 123, 171 }, - { 1, 78, 125 }, - { 1, 51, 86 }, - { 1, 31, 54 }, - { 1, 14, 23 } - }, { /* Coeff Band 5 */ - { 15, 199, 227 }, - { 3, 150, 204 }, - { 1, 91, 146 }, - { 1, 55, 95 }, - { 1, 30, 53 }, - { 1, 11, 20 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 19, 55, 240 }, - { 19, 59, 196 }, - { 3, 52, 105 } - }, { /* Coeff Band 1 */ - { 41, 166, 207 }, - { 104, 153, 199 }, - { 31, 123, 181 }, - { 14, 101, 152 }, - { 5, 72, 106 }, - { 1, 36, 52 } - }, { /* Coeff Band 2 */ - { 35, 176, 211 }, - { 12, 131, 190 }, - { 2, 88, 144 }, - { 1, 60, 101 }, - { 1, 36, 60 }, - { 1, 16, 28 } - }, { /* Coeff Band 3 */ - { 28, 183, 213 }, - { 8, 134, 191 }, - { 1, 86, 142 }, - { 1, 56, 96 }, - { 1, 30, 53 }, - { 1, 12, 20 } - }, { /* Coeff Band 4 */ - { 20, 190, 215 }, - { 4, 135, 192 }, - { 1, 84, 139 }, - { 1, 53, 91 }, - { 1, 28, 49 }, - { 1, 11, 20 } - }, { /* Coeff Band 5 */ - { 13, 196, 216 }, - { 2, 137, 192 }, - { 1, 86, 143 }, - { 1, 57, 99 }, - { 1, 32, 56 }, - { 1, 13, 24 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 211, 29, 217 }, - { 96, 47, 156 }, - { 22, 43, 87 } - }, { /* Coeff Band 1 */ - { 78, 120, 193 }, - { 111, 116, 186 }, - { 46, 102, 164 }, - { 15, 80, 128 }, - { 2, 49, 76 }, - { 1, 18, 28 } - }, { /* Coeff Band 2 */ - { 71, 161, 203 }, - { 42, 132, 192 }, - { 10, 98, 150 }, - { 3, 69, 109 }, - { 1, 44, 70 }, - { 1, 18, 29 } - }, { /* Coeff Band 3 */ - { 57, 186, 211 }, - { 30, 140, 196 }, - { 4, 93, 146 }, - { 1, 62, 102 }, - { 1, 38, 65 }, - { 1, 16, 27 } - }, { /* Coeff Band 4 */ - { 47, 199, 217 }, - { 14, 145, 196 }, - { 1, 88, 142 }, - { 1, 57, 98 }, - { 1, 36, 62 }, - { 1, 15, 26 } - }, { /* Coeff Band 5 */ - { 26, 219, 229 }, - { 5, 155, 207 }, - { 1, 94, 151 }, - { 1, 60, 104 }, - { 1, 36, 62 }, - { 1, 16, 28 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 233, 29, 248 }, - { 146, 47, 220 }, - { 43, 52, 140 } - }, { /* Coeff Band 1 */ - { 100, 163, 232 }, - { 179, 161, 222 }, - { 63, 142, 204 }, - { 37, 113, 174 }, - { 26, 89, 137 }, - { 18, 68, 97 } - }, { /* Coeff Band 2 */ - { 85, 181, 230 }, - { 32, 146, 209 }, - { 7, 100, 164 }, - { 3, 71, 121 }, - { 1, 45, 77 }, - { 1, 18, 30 } - }, { /* Coeff Band 3 */ - { 65, 187, 230 }, - { 20, 148, 207 }, - { 2, 97, 159 }, - { 1, 68, 116 }, - { 1, 40, 70 }, - { 1, 14, 29 } - }, { /* Coeff Band 4 */ - { 40, 194, 227 }, - { 8, 147, 204 }, - { 1, 94, 155 }, - { 1, 65, 112 }, - { 1, 39, 66 }, - { 1, 14, 26 } - }, { /* Coeff Band 5 */ - { 16, 208, 228 }, - { 3, 151, 207 }, - { 1, 98, 160 }, - { 1, 67, 117 }, - { 1, 41, 74 }, - { 1, 17, 31 } - } - } - } - }, { /* tx = 32x32 */ - { /* block Type 0 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 17, 38, 140 }, - { 7, 34, 80 }, - { 1, 17, 29 } - }, { /* Coeff Band 1 */ - { 37, 75, 128 }, - { 41, 76, 128 }, - { 26, 66, 116 }, - { 12, 52, 94 }, - { 2, 32, 55 }, - { 1, 10, 16 } - }, { /* Coeff Band 2 */ - { 50, 127, 154 }, - { 37, 109, 152 }, - { 16, 82, 121 }, - { 5, 59, 85 }, - { 1, 35, 54 }, - { 1, 13, 20 } - }, { /* Coeff Band 3 */ - { 40, 142, 167 }, - { 17, 110, 157 }, - { 2, 71, 112 }, - { 1, 44, 72 }, - { 1, 27, 45 }, - { 1, 11, 17 } - }, { /* Coeff Band 4 */ - { 30, 175, 188 }, - { 9, 124, 169 }, - { 1, 74, 116 }, - { 1, 48, 78 }, - { 1, 30, 49 }, - { 1, 11, 18 } - }, { /* Coeff Band 5 */ - { 10, 222, 223 }, - { 2, 150, 194 }, - { 1, 83, 128 }, - { 1, 48, 79 }, - { 1, 27, 45 }, - { 1, 11, 17 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 36, 41, 235 }, - { 29, 36, 193 }, - { 10, 27, 111 } - }, { /* Coeff Band 1 */ - { 85, 165, 222 }, - { 177, 162, 215 }, - { 110, 135, 195 }, - { 57, 113, 168 }, - { 23, 83, 120 }, - { 10, 49, 61 } - }, { /* Coeff Band 2 */ - { 85, 190, 223 }, - { 36, 139, 200 }, - { 5, 90, 146 }, - { 1, 60, 103 }, - { 1, 38, 65 }, - { 1, 18, 30 } - }, { /* Coeff Band 3 */ - { 72, 202, 223 }, - { 23, 141, 199 }, - { 2, 86, 140 }, - { 1, 56, 97 }, - { 1, 36, 61 }, - { 1, 16, 27 } - }, { /* Coeff Band 4 */ - { 55, 218, 225 }, - { 13, 145, 200 }, - { 1, 86, 141 }, - { 1, 57, 99 }, - { 1, 35, 61 }, - { 1, 13, 22 } - }, { /* Coeff Band 5 */ - { 15, 235, 212 }, - { 1, 132, 184 }, - { 1, 84, 139 }, - { 1, 57, 97 }, - { 1, 34, 56 }, - { 1, 14, 23 } - } - } - }, { /* block Type 1 */ - { /* Intra */ - { /* Coeff Band 0 */ - { 181, 21, 201 }, - { 61, 37, 123 }, - { 10, 38, 71 } - }, { /* Coeff Band 1 */ - { 47, 106, 172 }, - { 95, 104, 173 }, - { 42, 93, 159 }, - { 18, 77, 131 }, - { 4, 50, 81 }, - { 1, 17, 23 } - }, { /* Coeff Band 2 */ - { 62, 147, 199 }, - { 44, 130, 189 }, - { 28, 102, 154 }, - { 18, 75, 115 }, - { 2, 44, 65 }, - { 1, 12, 19 } - }, { /* Coeff Band 3 */ - { 55, 153, 210 }, - { 24, 130, 194 }, - { 3, 93, 146 }, - { 1, 61, 97 }, - { 1, 31, 50 }, - { 1, 10, 16 } - }, { /* Coeff Band 4 */ - { 49, 186, 223 }, - { 17, 148, 204 }, - { 1, 96, 142 }, - { 1, 53, 83 }, - { 1, 26, 44 }, - { 1, 11, 17 } - }, { /* Coeff Band 5 */ - { 13, 217, 212 }, - { 2, 136, 180 }, - { 1, 78, 124 }, - { 1, 50, 83 }, - { 1, 29, 49 }, - { 1, 14, 23 } - } - }, { /* Inter */ - { /* Coeff Band 0 */ - { 197, 13, 247 }, - { 82, 17, 222 }, - { 25, 17, 162 } - }, { /* Coeff Band 1 */ - { 126, 186, 247 }, - { 234, 191, 243 }, - { 176, 177, 234 }, - { 104, 158, 220 }, - { 66, 128, 186 }, - { 55, 90, 137 } - }, { /* Coeff Band 2 */ - { 111, 197, 242 }, - { 46, 158, 219 }, - { 9, 104, 171 }, - { 2, 65, 125 }, - { 1, 44, 80 }, - { 1, 17, 91 } - }, { /* Coeff Band 3 */ - { 104, 208, 245 }, - { 39, 168, 224 }, - { 3, 109, 162 }, - { 1, 79, 124 }, - { 1, 50, 102 }, - { 1, 43, 102 } - }, { /* Coeff Band 4 */ - { 84, 220, 246 }, - { 31, 177, 231 }, - { 2, 115, 180 }, - { 1, 79, 134 }, - { 1, 55, 77 }, - { 1, 60, 79 } - }, { /* Coeff Band 5 */ - { 43, 243, 240 }, - { 8, 180, 217 }, - { 1, 115, 166 }, - { 1, 84, 121 }, - { 1, 51, 67 }, - { 1, 16, 6 } - } - } - } - } -}; - -enum MVJoint { - MV_JOINT_ZERO, - MV_JOINT_H, - MV_JOINT_V, - MV_JOINT_HV, -}; - -static const int8_t vp9_mv_joint_tree[3][2] = { - { -MV_JOINT_ZERO, 1 }, // '0' - { -MV_JOINT_H, 2 }, // '10' - { -MV_JOINT_V, -MV_JOINT_HV }, // '11x' -}; - -static const int8_t vp9_mv_class_tree[10][2] = { - { -0, 1 }, // '0' - { -1, 2 }, // '10' - { 3, 4 }, - { -2, -3 }, // '110x' - { 5, 6 }, - { -4, -5 }, // '1110x' - { -6, 7 }, // '11110' - { 8, 9 }, - { -7, -8 }, // '111110x' - { -9, -10 }, // '111111x' -}; - -static const int8_t vp9_mv_fp_tree[3][2] = { - { -0, 1 }, // '0' - { -1, 2 }, // '10' - { -2, -3 }, // '11x' -}; +#include "vp9dec.h" + +extern const uint8_t ff_vp9_bwh_tab[2][N_BS_SIZES][2]; +extern const int8_t ff_vp9_partition_tree[3][2]; +extern const uint8_t ff_vp9_default_kf_partition_probs[4][4][3]; +extern const int8_t ff_vp9_segmentation_tree[7][2]; +extern const int8_t ff_vp9_intramode_tree[9][2]; +extern const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9]; +extern const uint8_t ff_vp9_default_kf_uvmode_probs[10][9]; +extern const int8_t ff_vp9_inter_mode_tree[3][2]; +extern const int8_t ff_vp9_filter_tree[2][2]; +extern const enum FilterMode ff_vp9_filter_lut[3]; +extern const int16_t ff_vp9_dc_qlookup[3][256]; +extern const int16_t ff_vp9_ac_qlookup[3][256]; +extern const enum TxfmType ff_vp9_intra_txfm_type[14]; +extern const int16_t ff_vp9_default_scan_4x4[16]; +extern const int16_t ff_vp9_col_scan_4x4[16]; +extern const int16_t ff_vp9_row_scan_4x4[16]; +extern const int16_t ff_vp9_default_scan_8x8[64]; +extern const int16_t ff_vp9_col_scan_8x8[64]; +extern const int16_t ff_vp9_row_scan_8x8[64]; +extern const int16_t ff_vp9_default_scan_16x16[256]; +extern const int16_t ff_vp9_col_scan_16x16[256]; +extern const int16_t ff_vp9_row_scan_16x16[256]; +extern const int16_t ff_vp9_default_scan_32x32[1024]; +extern const int16_t * const ff_vp9_scans[5][4]; +extern const int16_t ff_vp9_default_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_col_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_row_scan_4x4_nb[16][2]; +extern const int16_t ff_vp9_default_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_col_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_row_scan_8x8_nb[64][2]; +extern const int16_t ff_vp9_default_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_col_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_row_scan_16x16_nb[256][2]; +extern const int16_t ff_vp9_default_scan_32x32_nb[1024][2]; +extern const int16_t (* const ff_vp9_scans_nb[5][4])[2]; +extern const uint8_t ff_vp9_model_pareto8[256][8]; +extern const ProbContext ff_vp9_default_probs; +extern const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3]; +extern const int8_t ff_vp9_mv_joint_tree[3][2]; +extern const int8_t ff_vp9_mv_class_tree[10][2]; +extern const int8_t ff_vp9_mv_fp_tree[3][2]; #endif /* AVCODEC_VP9DATA_H */ diff --git a/media/ffvpx/libavcodec/vp9dec.h b/media/ffvpx/libavcodec/vp9dec.h new file mode 100644 index 000000000..66573edc7 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9dec.h @@ -0,0 +1,240 @@ +/* + * 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 + */ + +#ifndef AVCODEC_VP9DEC_H +#define AVCODEC_VP9DEC_H + +#include <stddef.h> +#include <stdint.h> +#include <stdatomic.h> + +#include "libavutil/buffer.h" +#include "libavutil/thread.h" +#include "libavutil/internal.h" + +#include "vp9.h" +#include "vp9dsp.h" +#include "vp9shared.h" + +enum MVJoint { + MV_JOINT_ZERO, + MV_JOINT_H, + MV_JOINT_V, + MV_JOINT_HV, +}; + +typedef struct ProbContext { + uint8_t y_mode[4][9]; + uint8_t uv_mode[10][9]; + uint8_t filter[4][2]; + uint8_t mv_mode[7][3]; + uint8_t intra[4]; + uint8_t comp[5]; + uint8_t single_ref[5][2]; + uint8_t comp_ref[5]; + uint8_t tx32p[2][3]; + uint8_t tx16p[2][2]; + uint8_t tx8p[2]; + uint8_t skip[3]; + uint8_t mv_joint[3]; + struct { + uint8_t sign; + uint8_t classes[10]; + uint8_t class0; + uint8_t bits[10]; + uint8_t class0_fp[2][3]; + uint8_t fp[3]; + uint8_t class0_hp; + uint8_t hp; + } mv_comp[2]; + uint8_t partition[4][4][3]; +} ProbContext; + +typedef 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 */]; +} VP9Filter; + +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 VP9TileData VP9TileData; + +typedef struct VP9Context { + VP9SharedContext s; + VP9TileData *td; + + VP9DSPContext dsp; + VideoDSPContext vdsp; + GetBitContext gb; + VP56RangeCoder c; + int pass, active_tile_cols; + +#if HAVE_THREADS + pthread_mutex_t progress_mutex; + pthread_cond_t progress_cond; + atomic_int *entries; +#endif + + uint8_t ss_h, ss_v; + uint8_t last_bpp, bpp_index, bytesperpixel; + uint8_t last_keyframe; + // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal + // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads + // and are therefore per-stream. pix_fmt represents the value in the header + // of the currently processed frame. + int w, h; + enum AVPixelFormat pix_fmt, last_fmt, gf_fmt; + unsigned sb_cols, sb_rows, rows, cols; + ThreadFrame next_refs[8]; + + struct { + uint8_t lim_lut[64]; + uint8_t mblim_lut[64]; + } filter_lut; + struct { + ProbContext p; + uint8_t coef[4][2][2][6][6][3]; + } prob_ctx[4]; + struct { + ProbContext p; + uint8_t coef[4][2][2][6][6][11]; + } prob; + + // contextual (above) cache + 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]; + VP9Filter *lflvl; + + // block reconstruction intermediates + int block_alloc_using_2pass; + uint16_t mvscale[3][2]; + uint8_t mvstep[3][2]; +} VP9Context; + +struct VP9TileData { + //VP9Context should be const, but because of the threading API(generates + //a lot of warnings) it's not. + VP9Context *s; + VP56RangeCoder *c_b; + VP56RangeCoder *c; + int row, row7, col, col7; + uint8_t *dst[3]; + ptrdiff_t y_stride, uv_stride; + VP9Block *b_base, *b; + unsigned tile_col_start; + + 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; + + // whole-frame cache + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; + + // contextual (left) 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]; + // block reconstruction intermediates + DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; + DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; + struct { int x, y; } min_mv, max_mv; + int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; + uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; +}; + +void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb); + +void ff_vp9_adapt_probs(VP9Context *s); + +void ff_vp9_decode_block(VP9TileData *td, int row, int col, + VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, + enum BlockLevel bl, enum BlockPartition bp); + +void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, + int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff); + +void ff_vp9_intra_recon_8bpp(VP9TileData *td, + ptrdiff_t y_off, ptrdiff_t uv_off); +void ff_vp9_intra_recon_16bpp(VP9TileData *td, + ptrdiff_t y_off, ptrdiff_t uv_off); +void ff_vp9_inter_recon_8bpp(VP9TileData *td); +void ff_vp9_inter_recon_16bpp(VP9TileData *td); + +#endif /* AVCODEC_VP9DEC_H */ diff --git a/media/ffvpx/libavcodec/vp9dsp.c b/media/ffvpx/libavcodec/vp9dsp.c index 54e77e267..f6d73f73c 100644 --- a/media/ffvpx/libavcodec/vp9dsp.c +++ b/media/ffvpx/libavcodec/vp9dsp.c @@ -25,6 +25,62 @@ #include "libavutil/common.h" #include "vp9dsp.h" +const DECLARE_ALIGNED(16, int16_t, ff_vp9_subpel_filters)[3][16][8] = { + [FILTER_8TAP_REGULAR] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, + { 0, 1, -5, 126, 8, -3, 1, 0 }, + { -1, 3, -10, 122, 18, -6, 2, 0 }, + { -1, 4, -13, 118, 27, -9, 3, -1 }, + { -1, 4, -16, 112, 37, -11, 4, -1 }, + { -1, 5, -18, 105, 48, -14, 4, -1 }, + { -1, 5, -19, 97, 58, -16, 5, -1 }, + { -1, 6, -19, 88, 68, -18, 5, -1 }, + { -1, 6, -19, 78, 78, -19, 6, -1 }, + { -1, 5, -18, 68, 88, -19, 6, -1 }, + { -1, 5, -16, 58, 97, -19, 5, -1 }, + { -1, 4, -14, 48, 105, -18, 5, -1 }, + { -1, 4, -11, 37, 112, -16, 4, -1 }, + { -1, 3, -9, 27, 118, -13, 4, -1 }, + { 0, 2, -6, 18, 122, -10, 3, -1 }, + { 0, 1, -3, 8, 126, -5, 1, 0 }, + }, [FILTER_8TAP_SHARP] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, + { -1, 3, -7, 127, 8, -3, 1, 0 }, + { -2, 5, -13, 125, 17, -6, 3, -1 }, + { -3, 7, -17, 121, 27, -10, 5, -2 }, + { -4, 9, -20, 115, 37, -13, 6, -2 }, + { -4, 10, -23, 108, 48, -16, 8, -3 }, + { -4, 10, -24, 100, 59, -19, 9, -3 }, + { -4, 11, -24, 90, 70, -21, 10, -4 }, + { -4, 11, -23, 80, 80, -23, 11, -4 }, + { -4, 10, -21, 70, 90, -24, 11, -4 }, + { -3, 9, -19, 59, 100, -24, 10, -4 }, + { -3, 8, -16, 48, 108, -23, 10, -4 }, + { -2, 6, -13, 37, 115, -20, 9, -4 }, + { -2, 5, -10, 27, 121, -17, 7, -3 }, + { -1, 3, -6, 17, 125, -13, 5, -2 }, + { 0, 1, -3, 8, 127, -7, 3, -1 }, + }, [FILTER_8TAP_SMOOTH] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, + { -3, -1, 32, 64, 38, 1, -3, 0 }, + { -2, -2, 29, 63, 41, 2, -3, 0 }, + { -2, -2, 26, 63, 43, 4, -4, 0 }, + { -2, -3, 24, 62, 46, 5, -4, 0 }, + { -2, -3, 21, 60, 49, 7, -4, 0 }, + { -1, -4, 18, 59, 51, 9, -4, 0 }, + { -1, -4, 16, 57, 53, 12, -4, -1 }, + { -1, -4, 14, 55, 55, 14, -4, -1 }, + { -1, -4, 12, 53, 57, 16, -4, -1 }, + { 0, -4, 9, 51, 59, 18, -4, -1 }, + { 0, -4, 7, 49, 60, 21, -3, -2 }, + { 0, -4, 5, 46, 62, 24, -3, -2 }, + { 0, -4, 4, 43, 63, 26, -2, -2 }, + { 0, -3, 2, 41, 63, 29, -2, -2 }, + { 0, -3, 1, 38, 64, 32, -1, -3 }, + } +}; + + av_cold void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact) { if (bpp == 8) { @@ -36,6 +92,8 @@ av_cold void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact) ff_vp9dsp_init_12(dsp); } + if (ARCH_AARCH64) ff_vp9dsp_init_aarch64(dsp, bpp); + if (ARCH_ARM) ff_vp9dsp_init_arm(dsp, bpp); if (ARCH_X86) ff_vp9dsp_init_x86(dsp, bpp, bitexact); if (ARCH_MIPS) ff_vp9dsp_init_mips(dsp, bpp); } diff --git a/media/ffvpx/libavcodec/vp9dsp.h b/media/ffvpx/libavcodec/vp9dsp.h index 733f5bfc4..e2256316a 100644 --- a/media/ffvpx/libavcodec/vp9dsp.h +++ b/media/ffvpx/libavcodec/vp9dsp.h @@ -27,7 +27,7 @@ #include <stddef.h> #include <stdint.h> -#include "vp9.h" +#include "libavcodec/vp9.h" typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, @@ -111,21 +111,25 @@ typedef struct VP9DSPContext { * * dst/stride are aligned by hsize */ - vp9_mc_func mc[5][4][2][2][2]; + vp9_mc_func mc[5][N_FILTERS][2][2][2]; /* * for scalable MC, first 3 dimensions identical to above, the other two * don't exist since it changes per stepsize. */ - vp9_scaled_mc_func smc[5][4][2]; + vp9_scaled_mc_func smc[5][N_FILTERS][2]; } VP9DSPContext; +extern const int16_t ff_vp9_subpel_filters[3][16][8]; + void ff_vp9dsp_init(VP9DSPContext *dsp, int bpp, int bitexact); void ff_vp9dsp_init_8(VP9DSPContext *dsp); void ff_vp9dsp_init_10(VP9DSPContext *dsp); void ff_vp9dsp_init_12(VP9DSPContext *dsp); +void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp); +void ff_vp9dsp_init_arm(VP9DSPContext *dsp, int bpp); void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact); void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp); diff --git a/media/ffvpx/libavcodec/vp9dsp_template.c b/media/ffvpx/libavcodec/vp9dsp_template.c index 4d810fec3..bb54561a6 100644 --- a/media/ffvpx/libavcodec/vp9dsp_template.c +++ b/media/ffvpx/libavcodec/vp9dsp_template.c @@ -1991,61 +1991,6 @@ copy_avg_fn(4) #endif /* BIT_DEPTH != 12 */ -static const int16_t vp9_subpel_filters[3][16][8] = { - [FILTER_8TAP_REGULAR] = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, - { 0, 1, -5, 126, 8, -3, 1, 0 }, - { -1, 3, -10, 122, 18, -6, 2, 0 }, - { -1, 4, -13, 118, 27, -9, 3, -1 }, - { -1, 4, -16, 112, 37, -11, 4, -1 }, - { -1, 5, -18, 105, 48, -14, 4, -1 }, - { -1, 5, -19, 97, 58, -16, 5, -1 }, - { -1, 6, -19, 88, 68, -18, 5, -1 }, - { -1, 6, -19, 78, 78, -19, 6, -1 }, - { -1, 5, -18, 68, 88, -19, 6, -1 }, - { -1, 5, -16, 58, 97, -19, 5, -1 }, - { -1, 4, -14, 48, 105, -18, 5, -1 }, - { -1, 4, -11, 37, 112, -16, 4, -1 }, - { -1, 3, -9, 27, 118, -13, 4, -1 }, - { 0, 2, -6, 18, 122, -10, 3, -1 }, - { 0, 1, -3, 8, 126, -5, 1, 0 }, - }, [FILTER_8TAP_SHARP] = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, - { -1, 3, -7, 127, 8, -3, 1, 0 }, - { -2, 5, -13, 125, 17, -6, 3, -1 }, - { -3, 7, -17, 121, 27, -10, 5, -2 }, - { -4, 9, -20, 115, 37, -13, 6, -2 }, - { -4, 10, -23, 108, 48, -16, 8, -3 }, - { -4, 10, -24, 100, 59, -19, 9, -3 }, - { -4, 11, -24, 90, 70, -21, 10, -4 }, - { -4, 11, -23, 80, 80, -23, 11, -4 }, - { -4, 10, -21, 70, 90, -24, 11, -4 }, - { -3, 9, -19, 59, 100, -24, 10, -4 }, - { -3, 8, -16, 48, 108, -23, 10, -4 }, - { -2, 6, -13, 37, 115, -20, 9, -4 }, - { -2, 5, -10, 27, 121, -17, 7, -3 }, - { -1, 3, -6, 17, 125, -13, 5, -2 }, - { 0, 1, -3, 8, 127, -7, 3, -1 }, - }, [FILTER_8TAP_SMOOTH] = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, - { -3, -1, 32, 64, 38, 1, -3, 0 }, - { -2, -2, 29, 63, 41, 2, -3, 0 }, - { -2, -2, 26, 63, 43, 4, -4, 0 }, - { -2, -3, 24, 62, 46, 5, -4, 0 }, - { -2, -3, 21, 60, 49, 7, -4, 0 }, - { -1, -4, 18, 59, 51, 9, -4, 0 }, - { -1, -4, 16, 57, 53, 12, -4, -1 }, - { -1, -4, 14, 55, 55, 14, -4, -1 }, - { -1, -4, 12, 53, 57, 16, -4, -1 }, - { 0, -4, 9, 51, 59, 18, -4, -1 }, - { 0, -4, 7, 49, 60, 21, -3, -2 }, - { 0, -4, 5, 46, 62, 24, -3, -2 }, - { 0, -4, 4, 43, 63, 26, -2, -2 }, - { 0, -3, 2, 41, 63, 29, -2, -2 }, - { 0, -3, 1, 38, 64, 32, -1, -3 }, - } -}; - #define FILTER_8TAP(src, x, F, stride) \ av_clip_pixel((F[0] * src[x + -3 * stride] + \ F[1] * src[x + -2 * stride] + \ @@ -2155,7 +2100,7 @@ static void avg##_8tap_##type##_##sz##dir##_c(uint8_t *dst, ptrdiff_t dst_stride int h, int mx, int my) \ { \ avg##_8tap_1d_##dir##_c(dst, dst_stride, src, src_stride, sz, h, \ - vp9_subpel_filters[type_idx][dir_m]); \ + ff_vp9_subpel_filters[type_idx][dir_m]); \ } #define filter_fn_2d(sz, type, type_idx, avg) \ @@ -2164,8 +2109,8 @@ static void avg##_8tap_##type##_##sz##hv_c(uint8_t *dst, ptrdiff_t dst_stride, \ int h, int mx, int my) \ { \ avg##_8tap_2d_hv_c(dst, dst_stride, src, src_stride, sz, h, \ - vp9_subpel_filters[type_idx][mx], \ - vp9_subpel_filters[type_idx][my]); \ + ff_vp9_subpel_filters[type_idx][mx], \ + ff_vp9_subpel_filters[type_idx][my]); \ } #if BIT_DEPTH != 12 @@ -2454,7 +2399,7 @@ static void avg##_scaled_##type##_##sz##_c(uint8_t *dst, ptrdiff_t dst_stride, \ int h, int mx, int my, int dx, int dy) \ { \ avg##_scaled_8tap_c(dst, dst_stride, src, src_stride, sz, h, mx, my, dx, dy, \ - vp9_subpel_filters[type_idx]); \ + ff_vp9_subpel_filters[type_idx]); \ } #if BIT_DEPTH != 12 diff --git a/media/ffvpx/libavcodec/vp9lpf.c b/media/ffvpx/libavcodec/vp9lpf.c new file mode 100644 index 000000000..414cede85 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9lpf.c @@ -0,0 +1,202 @@ +/* + * 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 "vp9dec.h" + +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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L] << 8; + I |= s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (hm23 & x) { + L = l[8 << ss_v]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L] << 8; + I |= s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.lim_lut[L]; + + if (vm3 & (x << (1 + ss_h))) { + L = l[1 + ss_h]; + H |= (L >> 4) << 8; + E |= s->filter_lut.mblim_lut[L] << 8; + I |= s->filter_lut.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_lut.mblim_lut[L], I = s->filter_lut.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; + } + } +} + +void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, + int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff) +{ + VP9Context *s = avctx->priv_data; + AVFrame *f = s->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); + } +} diff --git a/media/ffvpx/libavcodec/vp9mvs.c b/media/ffvpx/libavcodec/vp9mvs.c new file mode 100644 index 000000000..88db1c341 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9mvs.c @@ -0,0 +1,364 @@ +/* + * 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 "internal.h" +#include "vp56.h" +#include "vp9.h" +#include "vp9data.h" +#include "vp9dec.h" + +static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, + VP9TileData *td) +{ + dst->x = av_clip(src->x, td->min_mv.x, td->max_mv.x); + dst->y = av_clip(src->y, td->min_mv.y, td->max_mv.y); +} + +static void find_ref_mvs(VP9TileData *td, + 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 } }, + }; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col, row7 = td->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, td); \ + 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, td); \ + 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, td); \ + return; \ + } else if (mem == INVALID_MV) { \ + mem = m; \ + } else if (m != mem) { \ + clamp_mv(pmv, &mv, td); \ + return; \ + } \ + } \ + } while (0) + + if (row > 0) { + VP9mvrefPair *mv = &s->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 > td->tile_col_start) { + VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; + if (mv->ref[0] == ref) + RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][0]); + else if (mv->ref[1] == ref) + RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][1]); + } + i = 2; + } else { + i = 0; + } + + // previously coded MVs in this neighborhood, using same reference frame + for (; i < 8; i++) { + int c = p[i][0] + col, r = p[i][1] + row; + + if (c >= td->tile_col_start && c < s->cols && + r >= 0 && r < s->rows) { + VP9mvrefPair *mv = &s->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->s.h.use_last_frame_mvs) { + VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col]; + + if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass) + ff_thread_await_progress(&s->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 neighborhood, using different reference frame + for (i = 0; i < 8; i++) { + int c = p[i][0] + col, r = p[i][1] + row; + + if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { + VP9mvrefPair *mv = &s->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->s.h.signbias[mv->ref[0]] != s->s.h.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->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); + } + } + } + + // MV at this position in previous frame, using different reference frame + if (s->s.h.use_last_frame_mvs) { + VP9mvrefPair *mv = &s->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->s.h.signbias[mv->ref[0]] != s->s.h.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->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]); + } + } + + AV_ZERO32(pmv); + clamp_mv(pmv, pmv, td); +#undef INVALID_MV +#undef RETURN_MV +#undef RETURN_SCALE_MV +} + +static av_always_inline int read_mv_component(VP9TileData *td, int idx, int hp) +{ + VP9Context *s = td->s; + int bit, sign = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].sign); + int n, c = vp8_rac_get_tree(td->c, ff_vp9_mv_class_tree, + s->prob.p.mv_comp[idx].classes); + + td->counts.mv_comp[idx].sign[sign]++; + td->counts.mv_comp[idx].classes[c]++; + if (c) { + int m; + + for (n = 0, m = 0; m < c; m++) { + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].bits[m]); + n |= bit << m; + td->counts.mv_comp[idx].bits[m][bit]++; + } + n <<= 3; + bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree, + s->prob.p.mv_comp[idx].fp); + n |= bit << 1; + td->counts.mv_comp[idx].fp[bit]++; + if (hp) { + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].hp); + td->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 + td->counts.mv_comp[idx].hp[1]++; + } + n += 8 << c; + } else { + n = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0); + td->counts.mv_comp[idx].class0[n]++; + bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree, + s->prob.p.mv_comp[idx].class0_fp[n]); + td->counts.mv_comp[idx].class0_fp[n][bit]++; + n = (n << 3) | (bit << 1); + if (hp) { + bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0_hp); + td->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 + td->counts.mv_comp[idx].class0_hp[1]++; + } + } + + return sign ? -(n + 1) : (n + 1); +} + +void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + + if (mode == ZEROMV) { + AV_ZERO64(mv); + } else { + int hp; + + // FIXME cache this value and reuse for other subblocks + find_ref_mvs(td, &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->s.h.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(td->c, ff_vp9_mv_joint_tree, + s->prob.p.mv_joint); + + td->counts.mv_joint[j]++; + if (j >= MV_JOINT_V) + mv[0].y += read_mv_component(td, 0, hp); + if (j & 1) + mv[0].x += read_mv_component(td, 1, hp); + } + + if (b->comp) { + // FIXME cache this value and reuse for other subblocks + find_ref_mvs(td, &mv[1], b->ref[1], 1, mode == NEARMV, + mode == NEWMV ? -1 : sb); + if ((mode == NEWMV || sb == -1) && + !(hp = s->s.h.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(td->c, ff_vp9_mv_joint_tree, + s->prob.p.mv_joint); + + td->counts.mv_joint[j]++; + if (j >= MV_JOINT_V) + mv[1].y += read_mv_component(td, 0, hp); + if (j & 1) + mv[1].x += read_mv_component(td, 1, hp); + } + } + } +} diff --git a/media/ffvpx/libavcodec/vp9prob.c b/media/ffvpx/libavcodec/vp9prob.c new file mode 100644 index 000000000..fb295b482 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9prob.c @@ -0,0 +1,274 @@ +/* + * 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 "vp56.h" +#include "vp9.h" +#include "vp9data.h" +#include "vp9dec.h" + +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); +} + +void ff_vp9_adapt_probs(VP9Context *s) +{ + int i, j, k, l, m; + ProbContext *p = &s->prob_ctx[s->s.h.framectxid].p; + int uf = (s->s.h.keyframe || s->s.h.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->s.h.framectxid].coef[i][j][k][l][m]; + unsigned *e = s->td[0].counts.eob[i][j][k][l][m]; + unsigned *c = s->td[0].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->s.h.keyframe || s->s.h.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->td[0].counts.skip[i][0], + s->td[0].counts.skip[i][1], 20, 128); + + // intra/inter flag + for (i = 0; i < 4; i++) + adapt_prob(&p->intra[i], s->td[0].counts.intra[i][0], + s->td[0].counts.intra[i][1], 20, 128); + + // comppred flag + if (s->s.h.comppredmode == PRED_SWITCHABLE) { + for (i = 0; i < 5; i++) + adapt_prob(&p->comp[i], s->td[0].counts.comp[i][0], + s->td[0].counts.comp[i][1], 20, 128); + } + + // reference frames + if (s->s.h.comppredmode != PRED_SINGLEREF) { + for (i = 0; i < 5; i++) + adapt_prob(&p->comp_ref[i], s->td[0].counts.comp_ref[i][0], + s->td[0].counts.comp_ref[i][1], 20, 128); + } + + if (s->s.h.comppredmode != PRED_COMPREF) { + for (i = 0; i < 5; i++) { + uint8_t *pp = p->single_ref[i]; + unsigned (*c)[2] = s->td[0].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->td[0].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->s.h.txfmmode == TX_SWITCHABLE) { + for (i = 0; i < 2; i++) { + unsigned *c16 = s->td[0].counts.tx16p[i], *c32 = s->td[0].counts.tx32p[i]; + + adapt_prob(&p->tx8p[i], s->td[0].counts.tx8p[i][0], + s->td[0].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->s.h.filtermode == FILTER_SWITCHABLE) { + for (i = 0; i < 4; i++) { + uint8_t *pp = p->filter[i]; + unsigned *c = s->td[0].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->td[0].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->td[0].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->td[0].counts.mv_comp[i].sign[0], + s->td[0].counts.mv_comp[i].sign[1], 20, 128); + + pp = p->mv_comp[i].classes; + c = s->td[0].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->td[0].counts.mv_comp[i].class0[0], + s->td[0].counts.mv_comp[i].class0[1], 20, 128); + pp = p->mv_comp[i].bits; + c2 = s->td[0].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->td[0].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->td[0].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->s.h.highprecisionmvs) { + adapt_prob(&p->mv_comp[i].class0_hp, + s->td[0].counts.mv_comp[i].class0_hp[0], + s->td[0].counts.mv_comp[i].class0_hp[1], 20, 128); + adapt_prob(&p->mv_comp[i].hp, s->td[0].counts.mv_comp[i].hp[0], + s->td[0].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->td[0].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->td[0].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); + } +} diff --git a/media/ffvpx/libavcodec/vp9recon.c b/media/ffvpx/libavcodec/vp9recon.c new file mode 100644 index 000000000..49bb04e1f --- /dev/null +++ b/media/ffvpx/libavcodec/vp9recon.c @@ -0,0 +1,644 @@ +/* + * 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 "libavutil/avassert.h" + +#include "avcodec.h" +#include "internal.h" +#include "videodsp.h" +#include "vp9data.h" +#include "vp9dec.h" + +static av_always_inline int check_intra_mode(VP9TileData *td, 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) +{ + VP9Context *s = td->s; + int have_top = row > 0 || y > 0; + int have_left = col > td->tile_col_start || x > 0; + int have_right = x < w - 1; + int bpp = s->s.h.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(VP9TileData *td, ptrdiff_t y_off, + ptrdiff_t uv_off, int bytesperpixel) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; + int h4 = ff_vp9_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->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; + int uvstep1d = 1 << b->uvtx, p; + uint8_t *dst = td->dst[0], *dst_r = s->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 = ff_vp9_intra_txfm_type[mode]; + int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&td->eob[n]) : td->eob[n]; + + mode = check_intra_mode(td, mode, &a, ptr_r, + s->s.frames[CUR_FRAME].tf.f->linesize[0], + ptr, td->y_stride, l, + col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); + s->dsp.intra_pred[b->tx][mode](ptr, td->y_stride, l, a); + if (eob) + s->dsp.itxfm_add[tx][txtp](ptr, td->y_stride, + td->block + 16 * n * bytesperpixel, eob); + } + dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; + dst += 4 * step1d * td->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 = td->dst[1 + p]; + dst_r = s->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(&td->uveob[p][n]) : td->uveob[p][n]; + + mode = check_intra_mode(td, mode, &a, ptr_r, + s->s.frames[CUR_FRAME].tf.f->linesize[1], + ptr, td->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, td->uv_stride, l, a); + if (eob) + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, + td->uvblock[p] + 16 * n * bytesperpixel, eob); + } + dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; + dst += 4 * uvstep1d * td->uv_stride; + } + } +} + +void ff_vp9_intra_recon_8bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) +{ + intra_recon(td, y_off, uv_off, 1); +} + +void ff_vp9_intra_recon_16bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) +{ + intra_recon(td, y_off, uv_off, 2); +} + +static av_always_inline void mc_luma_unscaled(VP9TileData *td, 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) +{ + VP9Context *s = td->s; + 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); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). + if (x < !!mx * 3 || y < !!my * 3 || + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { + s->vdsp.emulated_edge_mc(td->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 = td->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(VP9TileData *td, 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) +{ + VP9Context *s = td->s; + int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !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); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (!!my * 5) than horizontally (!!mx * 4). + if (x < !!mx * 3 || y < !!my * 3 || + x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { + s->vdsp.emulated_edge_mc(td->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 = td->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(td->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 = td->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(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ + px, py, pw, ph, bw, bh, w, h, i) \ + mc_luma_unscaled(td, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, bw, bh, w, h, bytesperpixel) +#define mc_chroma_dir(td, 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(td, 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 +#undef mc_chroma_dir +#undef FN +#undef BYTES_PER_PIXEL +#undef SCALED + +static av_always_inline void mc_luma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, + 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 *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) +{ + VP9Context *s = td->s; + if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && + s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { + mc_luma_unscaled(td, mc, dst, dst_stride, ref, ref_stride, ref_frame, + y, x, in_mv, bw, bh, w, h, bytesperpixel); + } else { +#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) * 8, (s->cols * 8 - x + px + 3) * 8); + mv.y = av_clip(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); + // 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); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(td->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 = td->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(VP9TileData *td, vp9_scaled_mc_func smc, + 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 *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) +{ + VP9Context *s = td->s; + if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && + s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { + mc_chroma_unscaled(td, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, + ref_v, src_stride_v, ref_frame, + y, x, in_mv, bw, bh, w, h, bytesperpixel); + } else { + 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) * 16, (s->cols * 4 - x + px + 3) * 16); + 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) * 8, (s->cols * 8 - x + px + 3) * 8); + mx = scale_mv(mv.x * 2, 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) * 16, (s->rows * 4 - y + py + 3) * 16); + 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) * 8, (s->rows * 8 - y + py + 3) * 8); + my = scale_mv(mv.y * 2, 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); + // The arm/aarch64 _hv filters read one more row than what actually is + // needed, so switch to emulated edge one pixel sooner vertically + // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(td->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 = td->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(td->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 = td->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(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ + px, py, pw, ph, bw, bh, w, h, i) \ + mc_luma_scaled(td, s->dsp.s##mc, s->dsp.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(td, 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(td, s->dsp.s##mc, s->dsp.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 inter_recon(VP9TileData *td, int bytesperpixel) +{ + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; + + if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { + if (bytesperpixel == 1) { + inter_pred_scaled_8bpp(td); + } else { + inter_pred_scaled_16bpp(td); + } + } else { + if (bytesperpixel == 1) { + inter_pred_8bpp(td); + } else { + inter_pred_16bpp(td); + } + } + + if (!b->skip) { + /* mostly copied intra_recon() */ + + int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; + int h4 = ff_vp9_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->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; + int uvstep1d = 1 << b->uvtx, p; + uint8_t *dst = td->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(&td->eob[n]) : td->eob[n]; + + if (eob) + s->dsp.itxfm_add[tx][DCT_DCT](ptr, td->y_stride, + td->block + 16 * n * bytesperpixel, eob); + } + dst += 4 * td->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 = td->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(&td->uveob[p][n]) : td->uveob[p][n]; + + if (eob) + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, + td->uvblock[p] + 16 * n * bytesperpixel, eob); + } + dst += 4 * uvstep1d * td->uv_stride; + } + } + } +} + +void ff_vp9_inter_recon_8bpp(VP9TileData *td) +{ + inter_recon(td, 1); +} + +void ff_vp9_inter_recon_16bpp(VP9TileData *td) +{ + inter_recon(td, 2); +} diff --git a/media/ffvpx/libavcodec/vp9shared.h b/media/ffvpx/libavcodec/vp9shared.h new file mode 100644 index 000000000..54726df74 --- /dev/null +++ b/media/ffvpx/libavcodec/vp9shared.h @@ -0,0 +1,169 @@ +/* + * 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 + */ + +#ifndef AVCODEC_VP9SHARED_H +#define AVCODEC_VP9SHARED_H + +#include <stddef.h> +#include <stdint.h> + +#include "vp9.h" +#include "thread.h" +#include "vp56.h" + +enum BlockPartition { + PARTITION_NONE, // [ ] <-. + PARTITION_H, // [-] | + PARTITION_V, // [|] | + PARTITION_SPLIT, // [+] --' +}; + +enum InterPredMode { + NEARESTMV = 10, + NEARMV = 11, + ZEROMV = 12, + NEWMV = 13, +}; + +enum CompPredMode { + PRED_SINGLEREF, + PRED_COMPREF, + PRED_SWITCHABLE, +}; + +typedef struct VP9mvrefPair { + VP56mv mv[2]; + int8_t ref[2]; +} VP9mvrefPair; + +typedef struct VP9Frame { + ThreadFrame tf; + AVBufferRef *extradata; + uint8_t *segmentation_map; + VP9mvrefPair *mv; + int uses_2pass; + + AVBufferRef *hwaccel_priv_buf; + void *hwaccel_picture_private; +} VP9Frame; + +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, +}; + +typedef struct VP9BitstreamHeader { + // bitstream header + uint8_t profile; + uint8_t bpp; + uint8_t keyframe; + uint8_t invisible; + uint8_t errorres; + uint8_t intraonly; + uint8_t resetctx; + uint8_t refreshrefmask; + uint8_t highprecisionmvs; + enum FilterMode filtermode; + uint8_t allowcompinter; + uint8_t refreshctx; + uint8_t parallelmode; + uint8_t framectxid; + uint8_t use_last_frame_mvs; + uint8_t refidx[3]; + uint8_t signbias[3]; + uint8_t fixcompref; + uint8_t varcompref[2]; + struct { + uint8_t level; + int8_t sharpness; + } filter; + struct { + uint8_t enabled; + uint8_t updated; + 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 prob[7]; + uint8_t pred_prob[3]; + 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; + enum TxfmMode txfmmode; + enum CompPredMode comppredmode; + struct { + unsigned log2_tile_cols, log2_tile_rows; + unsigned tile_cols, tile_rows; + } tiling; + + int uncompressed_header_size; + int compressed_header_size; +} VP9BitstreamHeader; + +typedef struct VP9SharedContext { + VP9BitstreamHeader h; + + ThreadFrame refs[8]; +#define CUR_FRAME 0 +#define REF_FRAME_MVPAIR 1 +#define REF_FRAME_SEGMAP 2 + VP9Frame frames[3]; +} VP9SharedContext; + +#endif /* AVCODEC_VP9SHARED_H */ diff --git a/media/ffvpx/libavcodec/x86/constants.h b/media/ffvpx/libavcodec/x86/constants.h index b82aef9a4..bbb0ef844 100644 --- a/media/ffvpx/libavcodec/x86/constants.h +++ b/media/ffvpx/libavcodec/x86/constants.h @@ -43,6 +43,7 @@ extern const xmm_reg ff_pw_64; extern const uint64_t ff_pw_96; extern const uint64_t ff_pw_128; extern const ymm_reg ff_pw_255; +extern const ymm_reg ff_pw_256; extern const ymm_reg ff_pw_512; extern const ymm_reg ff_pw_1023; extern const ymm_reg ff_pw_1024; diff --git a/media/ffvpx/libavcodec/x86/flacdsp_init.c b/media/ffvpx/libavcodec/x86/flacdsp_init.c index e28c5c932..1971f81b8 100644 --- a/media/ffvpx/libavcodec/x86/flacdsp_init.c +++ b/media/ffvpx/libavcodec/x86/flacdsp_init.c @@ -53,7 +53,7 @@ DECORRELATE_FUNCS(32, avx); av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); #if CONFIG_FLAC_DECODER @@ -111,5 +111,5 @@ av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int c->lpc16_encode = ff_flac_enc_lpc_16_sse4; } #endif -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/h264_i386.h b/media/ffvpx/libavcodec/x86/h264_i386.h deleted file mode 100644 index 19cd12838..000000000 --- a/media/ffvpx/libavcodec/x86/h264_i386.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 Michael Niedermayer <michaelni@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 / MPEG-4 part10 codec. - * non-MMX i386-specific optimizations for H.264 - * @author Michael Niedermayer <michaelni@gmx.at> - */ - -#ifndef AVCODEC_X86_H264_I386_H -#define AVCODEC_X86_H264_I386_H - -#include <stddef.h> - -#include "libavcodec/cabac.h" -#include "cabac.h" - -#if HAVE_INLINE_ASM - -#if ARCH_X86_64 -#define REG64 "r" -#else -#define REG64 "m" -#endif - -//FIXME use some macros to avoid duplicating get_cabac (cannot be done yet -//as that would make optimization work hard) -#if HAVE_7REGS && !BROKEN_COMPILER -#define decode_significance decode_significance_x86 -static int decode_significance_x86(CABACContext *c, int max_coeff, - uint8_t *significant_coeff_ctx_base, - int *index, x86_reg last_off){ - void *end= significant_coeff_ctx_base + max_coeff - 1; - int minusstart= -(intptr_t)significant_coeff_ctx_base; - int minusindex= 4-(intptr_t)index; - int bit; - x86_reg coeff_count; - -#ifdef BROKEN_RELOCATIONS - void *tables; - - __asm__ volatile( - "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" - : "=&r"(tables) - : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) - ); -#endif - - __asm__ volatile( - "3: \n\t" - - BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", - "%5", "%q5", "%k0", "%b0", - "%c11(%6)", "%c12(%6)", - AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), - AV_STRINGIFY(H264_LPS_RANGE_OFFSET), - AV_STRINGIFY(H264_MLPS_STATE_OFFSET), - "%13") - - "test $1, %4 \n\t" - " jz 4f \n\t" - "add %10, %1 \n\t" - - BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", - "%5", "%q5", "%k0", "%b0", - "%c11(%6)", "%c12(%6)", - AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), - AV_STRINGIFY(H264_LPS_RANGE_OFFSET), - AV_STRINGIFY(H264_MLPS_STATE_OFFSET), - "%13") - - "sub %10, %1 \n\t" - "mov %2, %0 \n\t" - "movl %7, %%ecx \n\t" - "add %1, %%"FF_REG_c" \n\t" - "movl %%ecx, (%0) \n\t" - - "test $1, %4 \n\t" - " jnz 5f \n\t" - - "add"FF_OPSIZE" $4, %2 \n\t" - - "4: \n\t" - "add $1, %1 \n\t" - "cmp %8, %1 \n\t" - " jb 3b \n\t" - "mov %2, %0 \n\t" - "movl %7, %%ecx \n\t" - "add %1, %%"FF_REG_c" \n\t" - "movl %%ecx, (%0) \n\t" - "5: \n\t" - "add %9, %k0 \n\t" - "shr $2, %k0 \n\t" - : "=&q"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), - "+&r"(c->low), "=&r"(bit), "+&r"(c->range) - : "r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), - "i"(offsetof(CABACContext, bytestream)), - "i"(offsetof(CABACContext, bytestream_end)) - TABLES_ARG - : "%"FF_REG_c, "memory" - ); - return coeff_count; -} - -#define decode_significance_8x8 decode_significance_8x8_x86 -static int decode_significance_8x8_x86(CABACContext *c, - uint8_t *significant_coeff_ctx_base, - int *index, uint8_t *last_coeff_ctx_base, const uint8_t *sig_off){ - int minusindex= 4-(intptr_t)index; - int bit; - x86_reg coeff_count; - x86_reg last=0; - x86_reg state; - -#ifdef BROKEN_RELOCATIONS - void *tables; - - __asm__ volatile( - "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" - : "=&r"(tables) - : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) - ); -#endif - - __asm__ volatile( - "mov %1, %6 \n\t" - "3: \n\t" - - "mov %10, %0 \n\t" - "movzb (%0, %6), %6 \n\t" - "add %9, %6 \n\t" - - BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", - "%5", "%q5", "%k0", "%b0", - "%c12(%7)", "%c13(%7)", - AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), - AV_STRINGIFY(H264_LPS_RANGE_OFFSET), - AV_STRINGIFY(H264_MLPS_STATE_OFFSET), - "%15") - - "mov %1, %6 \n\t" - "test $1, %4 \n\t" - " jz 4f \n\t" - -#ifdef BROKEN_RELOCATIONS - "movzb %c14(%15, %q6), %6\n\t" -#else - "movzb "MANGLE(ff_h264_cabac_tables)"+%c14(%6), %6\n\t" -#endif - "add %11, %6 \n\t" - - BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", - "%5", "%q5", "%k0", "%b0", - "%c12(%7)", "%c13(%7)", - AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), - AV_STRINGIFY(H264_LPS_RANGE_OFFSET), - AV_STRINGIFY(H264_MLPS_STATE_OFFSET), - "%15") - - "mov %2, %0 \n\t" - "mov %1, %6 \n\t" - "mov %k6, (%0) \n\t" - - "test $1, %4 \n\t" - " jnz 5f \n\t" - - "add"FF_OPSIZE" $4, %2 \n\t" - - "4: \n\t" - "add $1, %6 \n\t" - "mov %6, %1 \n\t" - "cmp $63, %6 \n\t" - " jb 3b \n\t" - "mov %2, %0 \n\t" - "mov %k6, (%0) \n\t" - "5: \n\t" - "addl %8, %k0 \n\t" - "shr $2, %k0 \n\t" - : "=&q"(coeff_count), "+"REG64(last), "+"REG64(index), "+&r"(c->low), - "=&r"(bit), "+&r"(c->range), "=&r"(state) - : "r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), - REG64(sig_off), REG64(last_coeff_ctx_base), - "i"(offsetof(CABACContext, bytestream)), - "i"(offsetof(CABACContext, bytestream_end)), - "i"(H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET) TABLES_ARG - : "%"FF_REG_c, "memory" - ); - return coeff_count; -} -#endif /* HAVE_7REGS && BROKEN_COMPILER */ - -#endif /* HAVE_INLINE_ASM */ -#endif /* AVCODEC_X86_H264_I386_H */ diff --git a/media/ffvpx/libavcodec/x86/h264_intrapred.asm b/media/ffvpx/libavcodec/x86/h264_intrapred.asm index c88d91b49..f3aa3172f 100644 --- a/media/ffvpx/libavcodec/x86/h264_intrapred.asm +++ b/media/ffvpx/libavcodec/x86/h264_intrapred.asm @@ -49,7 +49,7 @@ cextern pw_17 cextern pw_32 ;----------------------------------------------------------------------------- -; void ff_pred16x16_vertical_8(uint8_t *src, int stride) +; void ff_pred16x16_vertical_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -85,7 +85,7 @@ cglobal pred16x16_vertical_8, 2,3 REP_RET ;----------------------------------------------------------------------------- -; void ff_pred16x16_horizontal_8(uint8_t *src, int stride) +; void ff_pred16x16_horizontal_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_H 0 @@ -126,7 +126,7 @@ INIT_XMM ssse3 PRED16x16_H ;----------------------------------------------------------------------------- -; void ff_pred16x16_dc_8(uint8_t *src, int stride) +; void ff_pred16x16_dc_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_DC 0 @@ -188,7 +188,7 @@ INIT_XMM ssse3 PRED16x16_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_tm_vp8_8(uint8_t *src, int stride) +; void ff_pred16x16_tm_vp8_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_TM 0 @@ -268,8 +268,45 @@ cglobal pred16x16_tm_vp8_8, 2,6,6 jg .loop REP_RET +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal pred16x16_tm_vp8_8, 2, 4, 5, dst, stride, stride3, iteration + sub dstq, strideq + pmovzxbw m0, [dstq] + vpbroadcastb xm1, [r0-1] + pmovzxbw m1, xm1 + psubw m0, m1 + mov iterationd, 4 + lea stride3q, [strideq*3] +.loop: + vpbroadcastb xm1, [dstq+strideq*1-1] + vpbroadcastb xm2, [dstq+strideq*2-1] + vpbroadcastb xm3, [dstq+stride3q-1] + vpbroadcastb xm4, [dstq+strideq*4-1] + pmovzxbw m1, xm1 + pmovzxbw m2, xm2 + pmovzxbw m3, xm3 + pmovzxbw m4, xm4 + paddw m1, m0 + paddw m2, m0 + paddw m3, m0 + paddw m4, m0 + vpackuswb m1, m1, m2 + vpackuswb m3, m3, m4 + vpermq m1, m1, q3120 + vpermq m3, m3, q3120 + movdqa [dstq+strideq*1], xm1 + vextracti128 [dstq+strideq*2], m1, 1 + movdqa [dstq+stride3q*1], xm3 + vextracti128 [dstq+strideq*4], m3, 1 + lea dstq, [dstq+strideq*4] + dec iterationd + jg .loop + REP_RET +%endif + ;----------------------------------------------------------------------------- -; void ff_pred16x16_plane_*_8(uint8_t *src, int stride) +; void ff_pred16x16_plane_*_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro H264_PRED16x16_PLANE 1 @@ -550,7 +587,7 @@ H264_PRED16x16_PLANE rv40 H264_PRED16x16_PLANE svq3 ;----------------------------------------------------------------------------- -; void ff_pred8x8_plane_8(uint8_t *src, int stride) +; void ff_pred8x8_plane_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro H264_PRED8x8_PLANE 0 @@ -724,7 +761,7 @@ INIT_XMM ssse3 H264_PRED8x8_PLANE ;----------------------------------------------------------------------------- -; void ff_pred8x8_vertical_8(uint8_t *src, int stride) +; void ff_pred8x8_vertical_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -741,7 +778,7 @@ cglobal pred8x8_vertical_8, 2,2 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_horizontal_8(uint8_t *src, int stride) +; void ff_pred8x8_horizontal_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8_H 0 @@ -769,7 +806,7 @@ INIT_MMX ssse3 PRED8x8_H ;----------------------------------------------------------------------------- -; void ff_pred8x8_top_dc_8_mmxext(uint8_t *src, int stride) +; void ff_pred8x8_top_dc_8_mmxext(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred8x8_top_dc_8, 2,5 @@ -803,7 +840,7 @@ cglobal pred8x8_top_dc_8, 2,5 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_dc_8_mmxext(uint8_t *src, int stride) +; void ff_pred8x8_dc_8_mmxext(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -864,7 +901,7 @@ cglobal pred8x8_dc_8, 2,5 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_dc_rv40_8(uint8_t *src, int stride) +; void ff_pred8x8_dc_rv40_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -901,7 +938,7 @@ cglobal pred8x8_dc_rv40_8, 2,7 REP_RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_tm_vp8_8(uint8_t *src, int stride) +; void ff_pred8x8_tm_vp8_8(uint8_t *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8_TM 0 @@ -1014,7 +1051,7 @@ cglobal pred8x8_tm_vp8_8, 2,3,6 ;----------------------------------------------------------------------------- ; void ff_pred8x8l_top_dc_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_TOP_DC 0 cglobal pred8x8l_top_dc_8, 4,4 @@ -1070,7 +1107,7 @@ PRED8x8L_TOP_DC ;----------------------------------------------------------------------------- ; void ff_pred8x8l_dc_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DC 0 @@ -1174,7 +1211,7 @@ PRED8x8L_DC ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL 0 @@ -1246,7 +1283,7 @@ PRED8x8L_HORIZONTAL ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_8(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL 0 @@ -1297,7 +1334,7 @@ PRED8x8L_VERTICAL ;----------------------------------------------------------------------------- ; void ff_pred8x8l_down_left_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1498,7 +1535,7 @@ PRED8x8L_DOWN_LEFT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_down_right_8_mmxext(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1750,7 +1787,7 @@ PRED8x8L_DOWN_RIGHT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_right_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -1978,7 +2015,7 @@ PRED8x8L_VERTICAL_RIGHT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_vertical_left_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL_LEFT 0 @@ -2068,7 +2105,7 @@ PRED8x8L_VERTICAL_LEFT ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_up_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL_UP 0 @@ -2156,7 +2193,7 @@ PRED8x8L_HORIZONTAL_UP ;----------------------------------------------------------------------------- ; void ff_pred8x8l_horizontal_down_8(uint8_t *src, int has_topleft, -; int has_topright, int stride) +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2404,7 +2441,8 @@ INIT_MMX ssse3 PRED8x8L_HORIZONTAL_DOWN ;------------------------------------------------------------------------------- -; void ff_pred4x4_dc_8_mmxext(uint8_t *src, const uint8_t *topright, int stride) +; void ff_pred4x4_dc_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- INIT_MMX mmxext @@ -2435,7 +2473,7 @@ cglobal pred4x4_dc_8, 3,5 ;----------------------------------------------------------------------------- ; void ff_pred4x4_tm_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_TM 0 @@ -2514,7 +2552,7 @@ cglobal pred4x4_tm_vp8_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_vertical_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2535,7 +2573,7 @@ cglobal pred4x4_vertical_vp8_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_down_left_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred4x4_down_left_8, 3,3 @@ -2562,7 +2600,7 @@ cglobal pred4x4_down_left_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_vertical_left_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2588,7 +2626,7 @@ cglobal pred4x4_vertical_left_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_horizontal_up_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2622,7 +2660,8 @@ cglobal pred4x4_horizontal_up_8, 3,3 ;------------------------------------------------------------------------------ ; void ff_pred4x4_horizontal_down_8_mmxext(uint8_t *src, -; const uint8_t *topright, int stride) +; const uint8_t *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------ INIT_MMX mmxext @@ -2658,7 +2697,8 @@ cglobal pred4x4_horizontal_down_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_vertical_right_8_mmxext(uint8_t *src, -; const uint8_t *topright, int stride) +; const uint8_t *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -2689,7 +2729,7 @@ cglobal pred4x4_vertical_right_8, 3,3 ;----------------------------------------------------------------------------- ; void ff_pred4x4_down_right_8_mmxext(uint8_t *src, const uint8_t *topright, -; int stride) +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext diff --git a/media/ffvpx/libavcodec/x86/h264_intrapred_10bit.asm b/media/ffvpx/libavcodec/x86/h264_intrapred_10bit.asm index 9e40cfe24..629e0a72e 100644 --- a/media/ffvpx/libavcodec/x86/h264_intrapred_10bit.asm +++ b/media/ffvpx/libavcodec/x86/h264_intrapred_10bit.asm @@ -51,7 +51,8 @@ SECTION .text %endmacro ;----------------------------------------------------------------------------- -; void ff_pred4x4_down_right(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_down_right_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_DR 0 cglobal pred4x4_down_right_10, 3, 3 @@ -89,7 +90,8 @@ PRED4x4_DR %endif ;------------------------------------------------------------------------------ -; void ff_pred4x4_vertical_right(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_vertical_right_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------ %macro PRED4x4_VR 0 cglobal pred4x4_vertical_right_10, 3, 3, 6 @@ -128,7 +130,8 @@ PRED4x4_VR %endif ;------------------------------------------------------------------------------- -; void ff_pred4x4_horizontal_down(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_horizontal_down_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- %macro PRED4x4_HD 0 cglobal pred4x4_horizontal_down_10, 3, 3 @@ -170,7 +173,7 @@ PRED4x4_HD %endif ;----------------------------------------------------------------------------- -; void ff_pred4x4_dc(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_dc_10(pixel *src, const pixel *topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext @@ -195,7 +198,8 @@ cglobal pred4x4_dc_10, 3, 3 RET ;----------------------------------------------------------------------------- -; void ff_pred4x4_down_left(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_down_left_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_DL 0 cglobal pred4x4_down_left_10, 3, 3 @@ -225,7 +229,8 @@ PRED4x4_DL %endif ;----------------------------------------------------------------------------- -; void ff_pred4x4_vertical_left(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_vertical_left_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED4x4_VL 0 cglobal pred4x4_vertical_left_10, 3, 3 @@ -254,7 +259,8 @@ PRED4x4_VL %endif ;----------------------------------------------------------------------------- -; void ff_pred4x4_horizontal_up(pixel *src, const pixel *topright, int stride) +; void ff_pred4x4_horizontal_up_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_MMX mmxext cglobal pred4x4_horizontal_up_10, 3, 3 @@ -288,7 +294,7 @@ cglobal pred4x4_horizontal_up_10, 3, 3 ;----------------------------------------------------------------------------- -; void ff_pred8x8_vertical(pixel *src, int stride) +; void ff_pred8x8_vertical_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_vertical_10, 2, 2 @@ -304,7 +310,7 @@ cglobal pred8x8_vertical_10, 2, 2 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_horizontal(pixel *src, int stride) +; void ff_pred8x8_horizontal_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_horizontal_10, 2, 3 @@ -324,7 +330,7 @@ cglobal pred8x8_horizontal_10, 2, 3 REP_RET ;----------------------------------------------------------------------------- -; void ff_predict_8x8_dc(pixel *src, int stride) +; void ff_predict_8x8_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro MOV8 2-3 ; sort of a hack, but it works @@ -411,7 +417,7 @@ INIT_XMM sse2 PRED8x8_DC pshuflw ;----------------------------------------------------------------------------- -; void ff_pred8x8_top_dc(pixel *src, int stride) +; void ff_pred8x8_top_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_top_dc_10, 2, 4 @@ -438,7 +444,7 @@ cglobal pred8x8_top_dc_10, 2, 4 RET ;----------------------------------------------------------------------------- -; void ff_pred8x8_plane(pixel *src, int stride) +; void ff_pred8x8_plane_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- INIT_XMM sse2 cglobal pred8x8_plane_10, 2, 7, 7 @@ -501,8 +507,8 @@ cglobal pred8x8_plane_10, 2, 7, 7 ;----------------------------------------------------------------------------- -; void ff_pred8x8l_128_dc(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_128_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_128_DC 0 cglobal pred8x8l_128_dc_10, 4, 4 @@ -526,8 +532,8 @@ INIT_XMM sse2 PRED8x8L_128_DC ;----------------------------------------------------------------------------- -; void ff_pred8x8l_top_dc(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_top_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_TOP_DC 0 cglobal pred8x8l_top_dc_10, 4, 4, 6 @@ -566,7 +572,8 @@ PRED8x8L_TOP_DC %endif ;------------------------------------------------------------------------------- -; void ff_pred8x8l_dc(pixel *src, int has_topleft, int has_topright, int stride) +; void ff_pred8x8l_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;------------------------------------------------------------------------------- ;TODO: see if scalar is faster %macro PRED8x8L_DC 0 @@ -625,8 +632,8 @@ PRED8x8L_DC %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_vertical(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_vertical_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL 0 cglobal pred8x8l_vertical_10, 4, 4, 6 @@ -661,8 +668,8 @@ PRED8x8L_VERTICAL %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_horizontal(uint8_t *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_horizontal_10(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL 0 cglobal pred8x8l_horizontal_10, 4, 4, 5 @@ -718,8 +725,8 @@ PRED8x8L_HORIZONTAL %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_down_left(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_down_left_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DOWN_LEFT 0 cglobal pred8x8l_down_left_10, 4, 4, 7 @@ -787,8 +794,8 @@ PRED8x8L_DOWN_LEFT %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_down_right(pixel *src, int has_topleft, int has_topright, -; int stride) +; void ff_pred8x8l_down_right_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_DOWN_RIGHT 0 ; standard forbids this when has_topleft is false @@ -862,8 +869,8 @@ PRED8x8L_DOWN_RIGHT %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_vertical_right(pixel *src, int has_topleft, -; int has_topright, int stride) +; void ff_pred8x8l_vertical_right_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_VERTICAL_RIGHT 0 ; likewise with 8x8l_down_right @@ -933,8 +940,8 @@ PRED8x8L_VERTICAL_RIGHT %endif ;----------------------------------------------------------------------------- -; void ff_pred8x8l_horizontal_up(pixel *src, int has_topleft, -; int has_topright, int stride) +; void ff_pred8x8l_horizontal_up_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED8x8L_HORIZONTAL_UP 0 cglobal pred8x8l_horizontal_up_10, 4, 4, 6 @@ -996,7 +1003,7 @@ PRED8x8L_HORIZONTAL_UP ;----------------------------------------------------------------------------- -; void ff_pred16x16_vertical(pixel *src, int stride) +; void ff_pred16x16_vertical_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro MOV16 3-5 mova [%1+ 0], %2 @@ -1032,7 +1039,7 @@ INIT_XMM sse2 PRED16x16_VERTICAL ;----------------------------------------------------------------------------- -; void ff_pred16x16_horizontal(pixel *src, int stride) +; void ff_pred16x16_horizontal_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_HORIZONTAL 0 cglobal pred16x16_horizontal_10, 2, 3 @@ -1056,7 +1063,7 @@ INIT_XMM sse2 PRED16x16_HORIZONTAL ;----------------------------------------------------------------------------- -; void ff_pred16x16_dc(pixel *src, int stride) +; void ff_pred16x16_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_DC 0 cglobal pred16x16_dc_10, 2, 6 @@ -1102,7 +1109,7 @@ INIT_XMM sse2 PRED16x16_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_top_dc(pixel *src, int stride) +; void ff_pred16x16_top_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_TOP_DC 0 cglobal pred16x16_top_dc_10, 2, 3 @@ -1134,7 +1141,7 @@ INIT_XMM sse2 PRED16x16_TOP_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_left_dc(pixel *src, int stride) +; void ff_pred16x16_left_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_LEFT_DC 0 cglobal pred16x16_left_dc_10, 2, 6 @@ -1171,7 +1178,7 @@ INIT_XMM sse2 PRED16x16_LEFT_DC ;----------------------------------------------------------------------------- -; void ff_pred16x16_128_dc(pixel *src, int stride) +; void ff_pred16x16_128_dc_10(pixel *src, ptrdiff_t stride) ;----------------------------------------------------------------------------- %macro PRED16x16_128_DC 0 cglobal pred16x16_128_dc_10, 2,3 diff --git a/media/ffvpx/libavcodec/x86/h264_intrapred_init.c b/media/ffvpx/libavcodec/x86/h264_intrapred_init.c index 528b92e49..bdd5125d6 100644 --- a/media/ffvpx/libavcodec/x86/h264_intrapred_init.c +++ b/media/ffvpx/libavcodec/x86/h264_intrapred_init.c @@ -127,6 +127,7 @@ PRED16x16(plane_svq3, 8, ssse3) PRED16x16(tm_vp8, 8, mmx) PRED16x16(tm_vp8, 8, mmxext) PRED16x16(tm_vp8, 8, sse2) +PRED16x16(tm_vp8, 8, avx2) PRED8x8(top_dc, 8, mmxext) PRED8x8(dc_rv40, 8, mmxext) @@ -323,6 +324,12 @@ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, } } } + + if(EXTERNAL_AVX2(cpu_flags)){ + if (codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_avx2; + } + } } else if (bit_depth == 10) { if (EXTERNAL_MMXEXT(cpu_flags)) { h->pred4x4[DC_PRED ] = ff_pred4x4_dc_10_mmxext; diff --git a/media/ffvpx/libavcodec/x86/videodsp.asm b/media/ffvpx/libavcodec/x86/videodsp.asm index a807d3b88..e23786070 100644 --- a/media/ffvpx/libavcodec/x86/videodsp.asm +++ b/media/ffvpx/libavcodec/x86/videodsp.asm @@ -114,7 +114,7 @@ cglobal emu_edge_hvar, 5, 6, 1, dst, dst_stride, start_x, n_words, h, w .x_loop: ; do { movu [dstq+wq*2], m0 ; write($reg, $mmsize) add wq, mmsize/2 ; w -= $mmsize/2 - cmp wq, -mmsize/2 ; } while (w > $mmsize/2) + cmp wq, -(mmsize/2) ; } while (w > $mmsize/2) jl .x_loop movu [dstq-mmsize], m0 ; write($reg, $mmsize) add dstq, dst_strideq ; dst += dst_stride diff --git a/media/ffvpx/libavcodec/x86/videodsp_init.c b/media/ffvpx/libavcodec/x86/videodsp_init.c index 26e072bb1..eeebb4154 100644 --- a/media/ffvpx/libavcodec/x86/videodsp_init.c +++ b/media/ffvpx/libavcodec/x86/videodsp_init.c @@ -29,7 +29,7 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/videodsp.h" -#if HAVE_YASM +#if HAVE_X86ASM typedef void emu_edge_vfix_func(uint8_t *dst, x86_reg dst_stride, const uint8_t *src, x86_reg src_stride, x86_reg start_y, x86_reg end_y, x86_reg bh); @@ -271,14 +271,14 @@ static av_noinline void emulated_edge_mc_avx2(uint8_t *buf, const uint8_t *src, hfixtbl_avx2, &ff_emu_edge_hvar_avx2); } #endif /* HAVE_AVX2_EXTERNAL */ -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ void ff_prefetch_mmxext(uint8_t *buf, ptrdiff_t stride, int h); void ff_prefetch_3dnow(uint8_t *buf, ptrdiff_t stride, int h); av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); #if ARCH_X86_32 @@ -305,5 +305,5 @@ av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc) ctx->emulated_edge_mc = emulated_edge_mc_avx2; } #endif -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/vp8dsp.asm b/media/ffvpx/libavcodec/x86/vp8dsp.asm index 538b3f4a9..e303b8029 100644 --- a/media/ffvpx/libavcodec/x86/vp8dsp.asm +++ b/media/ffvpx/libavcodec/x86/vp8dsp.asm @@ -156,8 +156,8 @@ SECTION .text ;------------------------------------------------------------------------------- ; subpel MC functions: ; -; void ff_put_vp8_epel<size>_h<htap>v<vtap>_<opt>(uint8_t *dst, int deststride, -; uint8_t *src, int srcstride, +; void ff_put_vp8_epel<size>_h<htap>v<vtap>_<opt>(uint8_t *dst, ptrdiff_t deststride, +; uint8_t *src, ptrdiff_t srcstride, ; int height, int mx, int my); ;------------------------------------------------------------------------------- @@ -884,7 +884,7 @@ cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height REP_RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add_<opt>(uint8_t *dst, int16_t block[16], int stride); +; void ff_vp8_idct_dc_add_<opt>(uint8_t *dst, int16_t block[16], ptrdiff_t stride); ;----------------------------------------------------------------------------- %macro ADD_DC 4 @@ -906,6 +906,7 @@ cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height %4 [dst2q+strideq+%3], m5 %endmacro +%if ARCH_X86_32 INIT_MMX mmx cglobal vp8_idct_dc_add, 3, 3, 0, dst, block, stride ; load data @@ -929,8 +930,9 @@ cglobal vp8_idct_dc_add, 3, 3, 0, dst, block, stride lea dst2q, [dst1q+strideq*2] ADD_DC m0, m1, 0, movh RET +%endif -INIT_XMM sse4 +%macro VP8_IDCT_DC_ADD 0 cglobal vp8_idct_dc_add, 3, 3, 6, dst, block, stride ; load data movd m0, [blockq] @@ -956,13 +958,28 @@ cglobal vp8_idct_dc_add, 3, 3, 6, dst, block, stride paddw m4, m0 packuswb m2, m4 movd [dst1q], m2 +%if cpuflag(sse4) pextrd [dst1q+strideq], m2, 1 pextrd [dst2q], m2, 2 pextrd [dst2q+strideq], m2, 3 +%else + psrldq m2, 4 + movd [dst1q+strideq], m2 + psrldq m2, 4 + movd [dst2q], m2 + psrldq m2, 4 + movd [dst2q+strideq], m2 +%endif RET +%endmacro + +INIT_XMM sse2 +VP8_IDCT_DC_ADD +INIT_XMM sse4 +VP8_IDCT_DC_ADD ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add4y_<opt>(uint8_t *dst, int16_t block[4][16], int stride); +; void ff_vp8_idct_dc_add4y_<opt>(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); ;----------------------------------------------------------------------------- %if ARCH_X86_32 @@ -1035,7 +1052,7 @@ cglobal vp8_idct_dc_add4y, 3, 3, 6, dst, block, stride RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_dc_add4uv_<opt>(uint8_t *dst, int16_t block[4][16], int stride); +; void ff_vp8_idct_dc_add4uv_<opt>(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); ;----------------------------------------------------------------------------- INIT_MMX mmx @@ -1077,7 +1094,7 @@ cglobal vp8_idct_dc_add4uv, 3, 3, 0, dst, block, stride RET ;----------------------------------------------------------------------------- -; void ff_vp8_idct_add_<opt>(uint8_t *dst, int16_t block[16], int stride); +; void ff_vp8_idct_add_<opt>(uint8_t *dst, int16_t block[16], ptrdiff_t stride); ;----------------------------------------------------------------------------- ; calculate %1=mul_35468(%1)-mul_20091(%2); %2=mul_20091(%1)+mul_35468(%2) diff --git a/media/ffvpx/libavcodec/x86/vp8dsp_init.c b/media/ffvpx/libavcodec/x86/vp8dsp_init.c index 897d5a0e7..397b2518c 100644 --- a/media/ffvpx/libavcodec/x86/vp8dsp_init.c +++ b/media/ffvpx/libavcodec/x86/vp8dsp_init.c @@ -26,7 +26,7 @@ #include "libavutil/x86/cpu.h" #include "libavcodec/vp8dsp.h" -#if HAVE_YASM +#if HAVE_X86ASM /* * MC functions @@ -233,6 +233,8 @@ HVBILIN(ssse3, 8, 16, 16) void ff_vp8_idct_dc_add_mmx(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +void ff_vp8_idct_dc_add_sse2(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); void ff_vp8_idct_dc_add_sse4(uint8_t *dst, int16_t block[16], ptrdiff_t stride); void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, int16_t block[4][16], @@ -288,7 +290,7 @@ DECLARE_LOOP_FILTER(sse2) DECLARE_LOOP_FILTER(ssse3) DECLARE_LOOP_FILTER(sse4) -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ #define VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) \ c->put_vp8_epel_pixels_tab[IDX][0][2] = ff_put_vp8_epel ## SIZE ## _h6_ ## OPT; \ @@ -316,7 +318,7 @@ DECLARE_LOOP_FILTER(sse4) av_cold void ff_vp78dsp_init_x86(VP8DSPContext *c) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_MMX(cpu_flags)) { @@ -346,7 +348,7 @@ av_cold void ff_vp78dsp_init_x86(VP8DSPContext *c) c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse; } - if (HAVE_SSE2_EXTERNAL && cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) { + if (EXTERNAL_SSE2(cpu_flags) || EXTERNAL_SSE2_SLOW(cpu_flags)) { VP8_LUMA_MC_FUNC(0, 16, sse2); VP8_MC_FUNC(1, 8, sse2); VP8_BILINEAR_MC_FUNC(0, 16, sse2); @@ -361,18 +363,18 @@ av_cold void ff_vp78dsp_init_x86(VP8DSPContext *c) VP8_BILINEAR_MC_FUNC(1, 8, ssse3); VP8_BILINEAR_MC_FUNC(2, 4, ssse3); } -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_MMX(cpu_flags)) { - c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx; #if ARCH_X86_32 + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmx; c->vp8_idct_add = ff_vp8_idct_add_mmx; c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmx; @@ -416,7 +418,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_sse; } - if (HAVE_SSE2_EXTERNAL && cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) { + if (EXTERNAL_SSE2(cpu_flags) || EXTERNAL_SSE2_SLOW(cpu_flags)) { c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2; c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_sse2; @@ -427,6 +429,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) } if (EXTERNAL_SSE2(cpu_flags)) { + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse2; c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_sse2; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2; @@ -460,5 +463,5 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse4; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse4; } -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm b/media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm index 98bb6696a..caeb40526 100644 --- a/media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm +++ b/media/ffvpx/libavcodec/x86/vp8dsp_loopfilter.asm @@ -43,7 +43,7 @@ cextern pb_80 SECTION .text ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter_simple_<opt>(uint8_t *dst, int stride, int flim); +; void ff_vp8_h/v_loop_filter_simple_<opt>(uint8_t *dst, ptrdiff_t stride, int flim); ;----------------------------------------------------------------------------- ; macro called with 7 mm register indexes as argument, and 4 regular registers @@ -429,7 +429,7 @@ INIT_XMM sse4 SIMPLE_LOOPFILTER h, 5 ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter<size>_inner_<opt>(uint8_t *dst, [uint8_t *v,] int stride, +; void ff_vp8_h/v_loop_filter<size>_inner_<opt>(uint8_t *dst, [uint8_t *v,] ptrdiff_t stride, ; int flimE, int flimI, int hev_thr); ;----------------------------------------------------------------------------- @@ -921,7 +921,7 @@ INNER_LOOPFILTER v, 8 INNER_LOOPFILTER h, 8 ;----------------------------------------------------------------------------- -; void ff_vp8_h/v_loop_filter<size>_mbedge_<opt>(uint8_t *dst, [uint8_t *v,] int stride, +; void ff_vp8_h/v_loop_filter<size>_mbedge_<opt>(uint8_t *dst, [uint8_t *v,] ptrdiff_t stride, ; int flimE, int flimI, int hev_thr); ;----------------------------------------------------------------------------- diff --git a/media/ffvpx/libavcodec/x86/vp9dsp_init.c b/media/ffvpx/libavcodec/x86/vp9dsp_init.c index cc781a009..837cce850 100644 --- a/media/ffvpx/libavcodec/x86/vp9dsp_init.c +++ b/media/ffvpx/libavcodec/x86/vp9dsp_init.c @@ -27,7 +27,7 @@ #include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" -#if HAVE_YASM +#if HAVE_X86ASM decl_fpel_func(put, 4, , mmx); decl_fpel_func(put, 8, , mmx); @@ -114,7 +114,7 @@ itxfm_func(idct, idct, 32, sse2); itxfm_func(idct, idct, 32, ssse3); itxfm_func(idct, idct, 32, avx); itxfm_func(iwht, iwht, 4, mmx); -itxfm_func(idct, idct, 16, avx2); +itxfm_funcs(16, avx2); itxfm_func(idct, idct, 32, avx2); #undef itxfm_func @@ -212,11 +212,11 @@ ipred_func(32, tm, avx2); #undef ipred_dir_tm_funcs #undef ipred_dc_funcs -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags; if (bpp == 10) { @@ -391,6 +391,12 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact) if (ARCH_X86_64) { #if ARCH_X86_64 && HAVE_AVX2_EXTERNAL dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_avx2; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx2; init_subpel3_32_64(0, put, 8, avx2); init_subpel3_32_64(1, avg, 8, avx2); @@ -406,5 +412,5 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact) #undef init_subpel2 #undef init_subpel3 -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c b/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c index eb67499c9..60d10a12a 100644 --- a/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c +++ b/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp.c @@ -27,7 +27,7 @@ #include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" -#if HAVE_YASM +#if HAVE_X86ASM decl_fpel_func(put, 8, , mmx); decl_fpel_func(avg, 8, _16, mmxext); @@ -51,6 +51,10 @@ decl_ipred_fns(h, 16, mmxext, sse2); decl_ipred_fns(dc, 16, mmxext, sse2); decl_ipred_fns(dc_top, 16, mmxext, sse2); decl_ipred_fns(dc_left, 16, mmxext, sse2); +decl_ipred_fn(dl, 16, 16, avx2); +decl_ipred_fn(dl, 32, 16, avx2); +decl_ipred_fn(dr, 16, 16, avx2); +decl_ipred_fn(dr, 32, 16, avx2); #define decl_ipred_dir_funcs(type) \ decl_ipred_fns(type, 16, sse2, sse2); \ @@ -63,11 +67,11 @@ decl_ipred_dir_funcs(vl); decl_ipred_dir_funcs(vr); decl_ipred_dir_funcs(hu); decl_ipred_dir_funcs(hd); -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ av_cold void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_MMX(cpu_flags)) { @@ -133,7 +137,13 @@ av_cold void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp) init_fpel_func(2, 1, 32, avg, _16, avx2); init_fpel_func(1, 1, 64, avg, _16, avx2); init_fpel_func(0, 1, 128, avg, _16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 16, 16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 32, 16, avx2); + init_ipred_func(dr, DIAG_DOWN_RIGHT, 16, 16, avx2); +#if ARCH_X86_64 + init_ipred_func(dr, DIAG_DOWN_RIGHT, 32, 16, avx2); +#endif } -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ } diff --git a/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp_template.c b/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp_template.c index 4840b2844..b56afc7f5 100644 --- a/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp_template.c +++ b/media/ffvpx/libavcodec/x86/vp9dsp_init_16bpp_template.c @@ -27,7 +27,7 @@ #include "libavcodec/vp9dsp.h" #include "libavcodec/x86/vp9dsp_init.h" -#if HAVE_YASM +#if HAVE_X86ASM extern const int16_t ff_filters_16bpp[3][15][4][16]; @@ -137,11 +137,11 @@ decl_itxfm_func(iadst, iadst, 4, BPC, sse2); decl_itxfm_funcs(8, BPC, sse2); decl_itxfm_funcs(16, BPC, sse2); decl_itxfm_func(idct, idct, 32, BPC, sse2); -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ av_cold void INIT_FUNC(VP9DSPContext *dsp, int bitexact) { -#if HAVE_YASM +#if HAVE_X86ASM int cpu_flags = av_get_cpu_flags(); #define init_lpf_8_func(idx1, idx2, dir, wd, bpp, opt) \ @@ -234,7 +234,7 @@ av_cold void INIT_FUNC(VP9DSPContext *dsp, int bitexact) #endif } -#endif /* HAVE_YASM */ +#endif /* HAVE_X86ASM */ ff_vp9dsp_init_16bpp_x86(dsp); } diff --git a/media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm b/media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm index c0ac16d3e..32b698243 100644 --- a/media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm +++ b/media/ffvpx/libavcodec/x86/vp9intrapred_16bpp.asm @@ -847,6 +847,108 @@ DL_FUNCS INIT_XMM avx DL_FUNCS +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_dl_16x16_16, 2, 4, 5, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] ; abcdefghijklmnop + vpbroadcastw xm1, [aq+30] ; pppppppp + vperm2i128 m2, m0, m1, q0201 ; ijklmnoppppppppp + vpalignr m3, m2, m0, 2 ; bcdefghijklmnopp + vpalignr m4, m2, m0, 4 ; cdefghijklmnoppp + LOWPASS 0, 3, 4 ; BCDEFGHIJKLMNOPp + vperm2i128 m2, m0, m1, q0201 ; JKLMNOPppppppppp + DEFINE_ARGS dst, stride, stride3, cnt + mov cntd, 2 + lea stride3q, [strideq*3] + +.loop: + mova [dstq+strideq*0], m0 + vpalignr m3, m2, m0, 2 + vpalignr m4, m2, m0, 4 + mova [dstq+strideq*1], m3 + mova [dstq+strideq*2], m4 + vpalignr m3, m2, m0, 6 + vpalignr m4, m2, m0, 8 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m4 + vpalignr m3, m2, m0, 10 + vpalignr m4, m2, m0, 12 + mova [dstq+strideq*1], m3 + mova [dstq+strideq*2], m4 + vpalignr m3, m2, m0, 14 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + mova m0, m2 + vperm2i128 m2, m2, m2, q0101 ; pppppppppppppppp + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dl_32x32_16, 2, 6, 7, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq+mmsize*0+ 0] ; abcdefghijklmnop + mova m1, [aq+mmsize*1+ 0] ; qrstuvwxyz012345 + vpbroadcastw xm4, [aq+mmsize*1+30] ; 55555555 + vperm2i128 m5, m0, m1, q0201 ; ijklmnopqrstuvwx + vpalignr m2, m5, m0, 2 ; bcdefghijklmnopq + vpalignr m3, m5, m0, 4 ; cdefghijklmnopqr + LOWPASS 0, 2, 3 ; BCDEFGHIJKLMNOPQ + vperm2i128 m5, m1, m4, q0201 ; yz01234555555555 + vpalignr m2, m5, m1, 2 ; rstuvwxyz0123455 + vpalignr m3, m5, m1, 4 ; stuvwxyz01234555 + LOWPASS 1, 2, 3 ; RSTUVWXYZ......5 + vperm2i128 m2, m1, m4, q0201 ; Z......555555555 + vperm2i128 m5, m0, m1, q0201 ; JKLMNOPQRSTUVWXY + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 + +.loop: + mova [dstq+strideq*0 + 0], m0 + mova [dstq+strideq*0 +32], m1 + vpalignr m3, m5, m0, 2 + vpalignr m4, m2, m1, 2 + mova [dstq+strideq*1 + 0], m3 + mova [dstq+strideq*1 +32], m4 + vpalignr m3, m5, m0, 4 + vpalignr m4, m2, m1, 4 + mova [dstq+strideq*2 + 0], m3 + mova [dstq+strideq*2 +32], m4 + vpalignr m3, m5, m0, 6 + vpalignr m4, m2, m1, 6 + mova [dstq+stride3q*1+ 0], m3 + mova [dstq+stride3q*1+32], m4 + lea dstq, [dstq+strideq*4] + vpalignr m3, m5, m0, 8 + vpalignr m4, m2, m1, 8 + mova [dstq+strideq*0 + 0], m3 + mova [dstq+strideq*0 +32], m4 + vpalignr m3, m5, m0, 10 + vpalignr m4, m2, m1, 10 + mova [dstq+strideq*1 + 0], m3 + mova [dstq+strideq*1 +32], m4 + vpalignr m3, m5, m0, 12 + vpalignr m4, m2, m1, 12 + mova [dstq+strideq*2+ 0], m3 + mova [dstq+strideq*2+32], m4 + vpalignr m3, m5, m0, 14 + vpalignr m4, m2, m1, 14 + mova [dstq+stride3q+ 0], m3 + mova [dstq+stride3q+ 32], m4 + vpalignr m3, m5, m0, 16 + vpalignr m4, m2, m1, 16 + vperm2i128 m5, m3, m4, q0201 + vperm2i128 m2, m4, m4, q0101 + mova m0, m3 + mova m1, m4 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET +%endif + %macro DR_FUNCS 1 ; stack_mem_for_32x32_32bit_function cglobal vp9_ipred_dr_4x4_16, 4, 4, 3, dst, stride, l, a movh m0, [lq] ; wxyz.... @@ -1068,6 +1170,161 @@ DR_FUNCS 2 INIT_XMM avx DR_FUNCS 2 +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_dr_16x16_16, 4, 5, 6, dst, stride, l, a + mova m0, [lq] ; klmnopqrstuvwxyz + movu m1, [aq-2] ; *abcdefghijklmno + mova m2, [aq] ; abcdefghijklmnop + vperm2i128 m4, m2, m2, q2001 ; ijklmnop........ + vpalignr m5, m4, m2, 2 ; bcdefghijklmnop. + vperm2i128 m3, m0, m1, q0201 ; stuvwxyz*abcdefg + LOWPASS 1, 2, 5 ; ABCDEFGHIJKLMNO. + vpalignr m4, m3, m0, 2 ; lmnopqrstuvwxyz* + vpalignr m5, m3, m0, 4 ; mnopqrstuvwxyz*a + LOWPASS 0, 4, 5 ; LMNOPQRSTUVWXYZ# + vperm2i128 m5, m0, m1, q0201 ; TUVWXYZ#ABCDEFGH + DEFINE_ARGS dst, stride, stride3, stride5, dst3 + lea dst3q, [dstq+strideq*4] + lea stride3q, [strideq*3] + lea stride5q, [stride3q+strideq*2] + + vpalignr m3, m5, m0, 2 + vpalignr m4, m1, m5, 2 + mova [dst3q+stride5q*2], m3 ; 14 + mova [ dstq+stride3q*2], m4 ; 6 + vpalignr m3, m5, m0, 4 + vpalignr m4, m1, m5, 4 + sub dst3q, strideq + mova [dst3q+stride5q*2], m3 ; 13 + mova [dst3q+strideq*2 ], m4 ; 5 + mova [dst3q+stride3q*4], m0 ; 15 + vpalignr m3, m5, m0, 6 + vpalignr m4, m1, m5, 6 + mova [dstq+stride3q*4], m3 ; 12 + mova [dst3q+strideq*1], m4 ; 4 + vpalignr m3, m5, m0, 8 + vpalignr m4, m1, m5, 8 + mova [dst3q+strideq*8], m3 ; 11 + mova [dst3q+strideq*0], m4 ; 3 + vpalignr m3, m5, m0, 10 + vpalignr m4, m1, m5, 10 + mova [dstq+stride5q*2], m3 ; 10 + mova [dstq+strideq*2 ], m4 ; 2 + vpalignr m3, m5, m0, 12 + vpalignr m4, m1, m5, 12 + mova [dst3q+stride3q*2], m3 ; 9 + mova [dstq+strideq*1 ], m4 ; 1 + vpalignr m3, m5, m0, 14 + vpalignr m4, m1, m5, 14 + mova [dstq+strideq*8], m3 ; 8 + mova [dstq+strideq*0], m4 ; 0 + mova [dst3q+strideq*4], m5 ; 7 + RET + +%if ARCH_X86_64 +cglobal vp9_ipred_dr_32x32_16, 4, 7, 10, dst, stride, l, a + mova m0, [lq+mmsize*0+0] ; l[0-15] + mova m1, [lq+mmsize*1+0] ; l[16-31] + movu m2, [aq+mmsize*0-2] ; *abcdefghijklmno + mova m3, [aq+mmsize*0+0] ; abcdefghijklmnop + mova m4, [aq+mmsize*1+0] ; qrstuvwxyz012345 + vperm2i128 m5, m0, m1, q0201 ; lmnopqrstuvwxyz0 + vpalignr m6, m5, m0, 2 ; mnopqrstuvwxyz01 + vpalignr m7, m5, m0, 4 ; nopqrstuvwxyz012 + LOWPASS 0, 6, 7 ; L[0-15] + vperm2i128 m7, m1, m2, q0201 ; stuvwxyz*abcdefg + vpalignr m5, m7, m1, 2 ; lmnopqrstuvwxyz* + vpalignr m6, m7, m1, 4 ; mnopqrstuvwxyz*a + LOWPASS 1, 5, 6 ; L[16-31]# + vperm2i128 m5, m3, m4, q0201 ; ijklmnopqrstuvwx + vpalignr m6, m5, m3, 2 ; bcdefghijklmnopq + LOWPASS 2, 3, 6 ; A[0-15] + movu m3, [aq+mmsize*1-2] ; pqrstuvwxyz01234 + vperm2i128 m6, m4, m4, q2001 ; yz012345........ + vpalignr m7, m6, m4, 2 ; rstuvwxyz012345. + LOWPASS 3, 4, 7 ; A[16-31]. + vperm2i128 m4, m1, m2, q0201 ; TUVWXYZ#ABCDEFGH + vperm2i128 m5, m0, m1, q0201 ; L[7-15]L[16-23] + vperm2i128 m8, m2, m3, q0201 ; IJKLMNOPQRSTUVWX + DEFINE_ARGS dst8, stride, stride3, stride7, stride5, dst24, cnt + lea stride3q, [strideq*3] + lea stride5q, [stride3q+strideq*2] + lea stride7q, [strideq*4+stride3q] + lea dst24q, [dst8q+stride3q*8] + lea dst8q, [dst8q+strideq*8] + mov cntd, 2 + +.loop: + mova [dst24q+stride7q+0 ], m0 ; 31 23 15 7 + mova [dst24q+stride7q+32], m1 + mova [dst8q+stride7q+0], m1 + mova [dst8q+stride7q+32], m2 + vpalignr m6, m4, m1, 2 + vpalignr m7, m5, m0, 2 + vpalignr m9, m8, m2, 2 + mova [dst24q+stride3q*2+0], m7 ; 30 22 14 6 + mova [dst24q+stride3q*2+32], m6 + mova [dst8q+stride3q*2+0], m6 + mova [dst8q+stride3q*2+32], m9 + vpalignr m6, m4, m1, 4 + vpalignr m7, m5, m0, 4 + vpalignr m9, m8, m2, 4 + mova [dst24q+stride5q+0], m7 ; 29 21 13 5 + mova [dst24q+stride5q+32], m6 + mova [dst8q+stride5q+0], m6 + mova [dst8q+stride5q+32], m9 + vpalignr m6, m4, m1, 6 + vpalignr m7, m5, m0, 6 + vpalignr m9, m8, m2, 6 + mova [dst24q+strideq*4+0 ], m7 ; 28 20 12 4 + mova [dst24q+strideq*4+32], m6 + mova [dst8q+strideq*4+0], m6 + mova [dst8q+strideq*4+32], m9 + vpalignr m6, m4, m1, 8 + vpalignr m7, m5, m0, 8 + vpalignr m9, m8, m2, 8 + mova [dst24q+stride3q+0 ], m7 ; 27 19 11 3 + mova [dst24q+stride3q+32], m6 + mova [dst8q+stride3q+0], m6 + mova [dst8q+stride3q+32], m9 + vpalignr m6, m4, m1, 10 + vpalignr m7, m5, m0, 10 + vpalignr m9, m8, m2, 10 + mova [dst24q+strideq*2+0 ], m7 ; 26 18 10 2 + mova [dst24q+strideq*2+32], m6 + mova [dst8q+strideq*2+0], m6 + mova [dst8q+strideq*2+32], m9 + vpalignr m6, m4, m1, 12 + vpalignr m7, m5, m0, 12 + vpalignr m9, m8, m2, 12 + mova [dst24q+strideq+0 ], m7 ; 25 17 9 1 + mova [dst24q+strideq+32], m6 + mova [dst8q+strideq+0], m6 + mova [dst8q+strideq+32], m9 + vpalignr m6, m4, m1, 14 + vpalignr m7, m5, m0, 14 + vpalignr m9, m8, m2, 14 + mova [dst24q+strideq*0+0 ], m7 ; 24 16 8 0 + mova [dst24q+strideq*0+32], m6 + mova [dst8q+strideq*0+0], m6 + mova [dst8q+strideq*0+32], m9 + mova m0, m5 + mova m5, m1 + mova m1, m4 + mova m4, m2 + mova m2, m8 + mova m8, m3 + sub dst24q, stride7q + sub dst24q, strideq + sub dst8q, stride7q + sub dst8q, strideq + dec cntd + jg .loop + RET +%endif +%endif + %macro VL_FUNCS 1 ; stack_mem_for_32x32_32bit_function cglobal vp9_ipred_vl_4x4_16, 2, 4, 3, dst, stride, l, a movifnidn aq, amp diff --git a/media/ffvpx/libavcodec/x86/vp9itxfm.asm b/media/ffvpx/libavcodec/x86/vp9itxfm.asm index 57d6d353b..2c63fe514 100644 --- a/media/ffvpx/libavcodec/x86/vp9itxfm.asm +++ b/media/ffvpx/libavcodec/x86/vp9itxfm.asm @@ -1581,33 +1581,30 @@ cglobal vp9_idct_idct_16x16_add, 4, 4, 16, dst, stride, block, eob VP9_IDCT16_YMM_1D mova [blockq+224], m7 - mova [blockq+480], m15 - pxor m15, m15 ; store - VP9_IDCT8_WRITEx2 0, 1, 6, 7, 15, [pw_512], 6 + VP9_IDCT8_WRITEx2 0, 1, 6, 7, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 2, 3, 6, 7, 15, [pw_512], 6 + VP9_IDCT8_WRITEx2 2, 3, 6, 7, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 4, 5, 6, 7, 15, [pw_512], 6 + VP9_IDCT8_WRITEx2 4, 5, 6, 7, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] mova m6, [blockq+192] mova m7, [blockq+224] - SWAP 0, 15 - mova m15, [blockq+480] - VP9_IDCT8_WRITEx2 6, 7, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 6, 7, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 8, 9, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 8, 9, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 10, 11, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 10, 11, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 12, 13, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 12, 13, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] - VP9_IDCT8_WRITEx2 14, 15, 1, 2, 0, [pw_512], 6 + VP9_IDCT8_WRITEx2 14, 15, 1, 2, unused, [pw_512], 6 lea dstq, [dstq+2*strideq] ; at the end of the loop, m0 should still be zero ; use that to zero out block coefficients + pxor m0, m0 ZERO_BLOCK blockq, 32, 16, m0 RET %endif @@ -1987,6 +1984,173 @@ IADST16_FN idct, IDCT16, iadst, IADST16, avx IADST16_FN iadst, IADST16, idct, IDCT16, avx IADST16_FN iadst, IADST16, iadst, IADST16, avx +; in: data in m[0-15] except m0/m4, which are in [blockq+0] and [blockq+128] +; out: m[0-15] except m6, which is in [blockq+192] +; uses blockq as scratch space +%macro VP9_IADST16_YMM_1D 0 + mova [blockq+ 32], m3 + mova [blockq+ 64], m7 + mova [blockq+ 96], m8 + + ; first half of round 1 + VP9_UNPACK_MULSUB_2D_4X 9, 6, 0, 3, 13160, 9760 ; m9/x=t7[d], m6/x=t6[d] + VP9_UNPACK_MULSUB_2D_4X 1, 14, 4, 7, 2404, 16207 ; m1/x=t15[d], m14/x=t14[d] + VP9_RND_SH_SUMSUB_BA 14, 6, 7, 3, 8, [pd_8192] ; m14=t6[w], m6=t14[w] + VP9_RND_SH_SUMSUB_BA 1, 9, 4, 0, 8, [pd_8192] ; m1=t7[w], m9=t15[w] + + VP9_UNPACK_MULSUB_2D_4X 13, 2, 4, 7, 15893, 3981 ; m13/x=t3[d], m2/x=t2[d] + VP9_UNPACK_MULSUB_2D_4X 5, 10, 0, 3, 8423, 14053 ; m5/x=t11[d], m10/x=t10[d] + VP9_RND_SH_SUMSUB_BA 10, 2, 3, 7, 8, [pd_8192] ; m10=t2[w], m2=t10[w] + VP9_RND_SH_SUMSUB_BA 5, 13, 0, 4, 8, [pd_8192] ; m5=t3[w], m13=t11[w] + + ; half of round 2 t8-15 + VP9_UNPACK_MULSUB_2D_4X 2, 13, 4, 7, 9102, 13623 ; m2/x=t11[d], m13/x=t10[d] + VP9_UNPACK_MULSUB_2D_4X 9, 6, 3, 0, 13623, 9102 ; m9/x=t14[d], m6/x=t15[d] + VP9_RND_SH_SUMSUB_BA 9, 13, 3, 7, 8, [pd_8192] ; m9=t10[w], m13=t14[w] + VP9_RND_SH_SUMSUB_BA 6, 2, 0, 4, 8, [pd_8192] ; m6=t11[w], m2=t15[w] + + SUMSUB_BA w, 14, 10, 8 ; m14=t2, m10=t6 + SUMSUB_BA w, 1, 5, 8 ; m1=t3, m5=t7 + + mova m0, [blockq+ 0] + mova m4, [blockq+128] + mova m3, [blockq+ 32] + mova m7, [blockq+ 64] + mova m8, [blockq+ 96] + mova [blockq+ 0], m1 + mova [blockq+128], m14 + mova [blockq+ 32], m6 + mova [blockq+ 64], m9 + mova [blockq+ 96], m10 + + ; second half of round 1 + VP9_UNPACK_MULSUB_2D_4X 15, 0, 1, 9, 16364, 804 ; m15/x=t1[d], m0/x=t0[d] + VP9_UNPACK_MULSUB_2D_4X 7, 8, 10, 6, 11003, 12140 ; m7/x=t9[d], m8/x=t8[d] + VP9_RND_SH_SUMSUB_BA 8, 0, 6, 9, 14, [pd_8192] ; m8=t0[w], m0=t8[w] + VP9_RND_SH_SUMSUB_BA 7, 15, 10, 1, 14, [pd_8192] ; m7=t1[w], m15=t9[w] + + VP9_UNPACK_MULSUB_2D_4X 11, 4, 10, 6, 14811, 7005 ; m11/x=t5[d], m4/x=t4[d] + VP9_UNPACK_MULSUB_2D_4X 3, 12, 1, 9, 5520, 15426 ; m3/x=t13[d], m12/x=t12[d] + VP9_RND_SH_SUMSUB_BA 12, 4, 9, 6, 14, [pd_8192] ; m12=t4[w], m4=t12[w] + VP9_RND_SH_SUMSUB_BA 3, 11, 1, 10, 14, [pd_8192] ; m3=t5[w], m11=t13[w] + + ; second half of round 2 t8-15 + VP9_UNPACK_MULSUB_2D_4X 0, 15, 6, 10, 16069, 3196 ; m15/x=t8[d], m0/x=t9[d] + VP9_UNPACK_MULSUB_2D_4X 11, 4, 9, 1, 3196, 16069 ; m11/x=t12[d], m4/x=t13[d] + VP9_RND_SH_SUMSUB_BA 11, 15, 9, 10, 14, [pd_8192] ; m11=t8[w], m15=t12[w] + VP9_RND_SH_SUMSUB_BA 4, 0, 1, 6, 14, [pd_8192] ; m4=t9[w], m0=t13[w] + + SUMSUB_BA w, 12, 8, 14 ; m12=t0, m8=t4 + SUMSUB_BA w, 3, 7, 14 ; m3=t1, m7=t5 + + mova m10, [blockq+ 96] + mova [blockq+ 96], m12 + + ; round 3 + VP9_UNPACK_MULSUB_2D_4X 15, 0, 9, 12, 15137, 6270 ; m15/x=t13[d], m0/x=t12[d] + VP9_UNPACK_MULSUB_2D_4X 2, 13, 1, 6, 6270, 15137 ; m2/x=t14[d], m13/x=t15[d] + VP9_RND_SH_SUMSUB_BA 2, 0, 1, 12, 14, [pd_8192] ; m2=out2[w], m0=t14a[w] + VP9_RND_SH_SUMSUB_BA 13, 15, 6, 9, 14, [pd_8192] + PSIGNW m13, [pw_m1] ; m13=out13[w], m15=t15a[w] + + VP9_UNPACK_MULSUB_2D_4X 8, 7, 12, 9, 15137, 6270 ; m8/x=t5[d], m7/x=t4[d] + VP9_UNPACK_MULSUB_2D_4X 5, 10, 1, 6, 6270, 15137 ; m5/x=t6[d], m10/x=t7[d] + VP9_RND_SH_SUMSUB_BA 5, 7, 1, 9, 14, [pd_8192] + PSIGNW m5, [pw_m1] ; m5=out3[w], m7=t6[w] + VP9_RND_SH_SUMSUB_BA 10, 8, 6, 12, 14, [pd_8192] ; m10=out12[w], m8=t7[w] + + mova m1, [blockq+ 0] + mova m14, [blockq+128] + mova m6, [blockq+ 32] + mova m9, [blockq+ 64] + mova m12, [blockq+ 96] + mova [blockq+ 0], m10 + mova [blockq+128], m5 + + SUMSUB_BA w, 14, 12, 5 ; m14=out0, m12=t2a + SUMSUB_BA w, 1, 3, 5 + PSIGNW m1, [pw_m1] ; m1=out15, m3=t3a + + SUMSUB_BA w, 9, 11, 5 + PSIGNW m9, [pw_m1] ; m9=out1, m11=t10 + SUMSUB_BA w, 6, 4, 5 ; m6=out14, m4=t11 + + VP9_UNPACK_MULSUB_2W_4X 4, 11, 11585, 11585, [pd_8192], 5, 10 ; m4=out9, m11=out6 + mova m5, [blockq+128] + mova [blockq+192], m11 + PSIGNW m15, [pw_m1] + VP9_UNPACK_MULSUB_2W_4X 15, 0, 11585, 11585, [pd_8192], 10, 11 ; m15=out5, m0=out10 + + PSIGNW m3, [pw_m1] + VP9_UNPACK_MULSUB_2W_4X 3, 12, 11585, 11585, [pd_8192], 10, 11 ; m3=out7,m12=out8 + VP9_UNPACK_MULSUB_2W_4X 8, 7, 11585, 11585, [pd_8192], 10, 11 ; m8=out11,m7=out4 + + mova m10, [blockq+ 0] + + SWAP 0, 14, 6, 11, 8, 12, 10 + SWAP 1, 9, 15, 4, 7, 3, 5 + SWAP 5, 9, 15 +%endmacro + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +%macro IADST16_YMM_FN 4 +INIT_YMM avx2 +cglobal vp9_%1_%3_16x16_add, 4, 4, 16, dst, stride, block, eob + mova m1, [blockq+ 32] + mova m2, [blockq+ 64] + mova m3, [blockq+ 96] + mova m5, [blockq+160] + mova m6, [blockq+192] + mova m7, [blockq+224] + mova m8, [blockq+256] + mova m9, [blockq+288] + mova m10, [blockq+320] + mova m11, [blockq+352] + mova m12, [blockq+384] + mova m13, [blockq+416] + mova m14, [blockq+448] + mova m15, [blockq+480] + + VP9_%2_YMM_1D + TRANSPOSE16x16W 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ + [blockq+192], [blockq+128], 1 + mova [blockq+ 0], m0 + VP9_%4_YMM_1D + + mova [blockq+224], m7 + + ; store + VP9_IDCT8_WRITEx2 0, 1, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 2, 3, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 4, 5, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + mova m6, [blockq+192] + mova m7, [blockq+224] + VP9_IDCT8_WRITEx2 6, 7, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 8, 9, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 10, 11, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 12, 13, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 14, 15, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + + ; at the end of the loop, m0 should still be zero + ; use that to zero out block coefficients + pxor m0, m0 + ZERO_BLOCK blockq, 32, 16, m0 + RET +%endmacro + +IADST16_YMM_FN idct, IDCT16, iadst, IADST16 +IADST16_YMM_FN iadst, IADST16, idct, IDCT16 +IADST16_YMM_FN iadst, IADST16, iadst, IADST16 +%endif + ;--------------------------------------------------------------------------------------------- ; void vp9_idct_idct_32x32_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); ;--------------------------------------------------------------------------------------------- diff --git a/media/ffvpx/libavcodec/x86/vp9mc.asm b/media/ffvpx/libavcodec/x86/vp9mc.asm index 9152ba541..f64161b2c 100644 --- a/media/ffvpx/libavcodec/x86/vp9mc.asm +++ b/media/ffvpx/libavcodec/x86/vp9mc.asm @@ -1,5 +1,5 @@ ;****************************************************************************** -;* VP9 MC SIMD optimizations +;* VP9 motion compensation SIMD optimizations ;* ;* Copyright (c) 2013 Ronald S. Bultje <rsbultje gmail com> ;* @@ -440,9 +440,8 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _8, 4, 7, 11, dst, dstride, src, sstride, f mova m10, [filteryq+96] %endif .loop: - ; FIXME maybe reuse loads from previous rows, or just - ; more generally unroll this to prevent multiple loads of - ; the same data? + ; FIXME maybe reuse loads from previous rows, or just more generally + ; unroll this to prevent multiple loads of the same data? movh m0, [srcq] movh m1, [srcq+sstrideq] movh m2, [srcq+sstrideq*2] |