import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,687 @@
/*
* Provide registration of all codecs, parsers and bitstream filters for libavcodec.
* Copyright (c) 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Provide registration of all codecs, parsers and bitstream filters for libavcodec.
*/
#include "config.h"
#include "avcodec.h"
#include "version.h"
#define REGISTER_HWACCEL(X, x) \
{ \
extern AVHWAccel ff_##x##_hwaccel; \
if (CONFIG_##X##_HWACCEL) \
av_register_hwaccel(&ff_##x##_hwaccel); \
}
#define REGISTER_ENCODER(X, x) \
{ \
extern AVCodec ff_##x##_encoder; \
if (CONFIG_##X##_ENCODER) \
avcodec_register(&ff_##x##_encoder); \
}
#define REGISTER_DECODER(X, x) \
{ \
extern AVCodec ff_##x##_decoder; \
if (CONFIG_##X##_DECODER) \
avcodec_register(&ff_##x##_decoder); \
}
#define REGISTER_ENCDEC(X, x) REGISTER_ENCODER(X, x); REGISTER_DECODER(X, x)
#define REGISTER_PARSER(X, x) \
{ \
extern AVCodecParser ff_##x##_parser; \
if (CONFIG_##X##_PARSER) \
av_register_codec_parser(&ff_##x##_parser); \
}
void avcodec_register_all(void)
{
static int initialized;
if (initialized)
return;
initialized = 1;
/* hardware accelerators */
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_DXVA2, h264_dxva2);
REGISTER_HWACCEL(H264_MMAL, h264_mmal);
REGISTER_HWACCEL(H264_QSV, h264_qsv);
REGISTER_HWACCEL(H264_VAAPI, h264_vaapi);
REGISTER_HWACCEL(H264_VDA, h264_vda);
REGISTER_HWACCEL(H264_VDA_OLD, h264_vda_old);
REGISTER_HWACCEL(H264_VDPAU, h264_vdpau);
REGISTER_HWACCEL(H264_VIDEOTOOLBOX, h264_videotoolbox);
REGISTER_HWACCEL(HEVC_CUVID, hevc_cuvid);
REGISTER_HWACCEL(HEVC_D3D11VA, hevc_d3d11va);
REGISTER_HWACCEL(HEVC_DXVA2, hevc_dxva2);
REGISTER_HWACCEL(HEVC_QSV, hevc_qsv);
REGISTER_HWACCEL(HEVC_VAAPI, hevc_vaapi);
REGISTER_HWACCEL(HEVC_VDPAU, hevc_vdpau);
REGISTER_HWACCEL(MPEG1_XVMC, mpeg1_xvmc);
REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau);
REGISTER_HWACCEL(MPEG1_VIDEOTOOLBOX, mpeg1_videotoolbox);
REGISTER_HWACCEL(MPEG2_XVMC, mpeg2_xvmc);
REGISTER_HWACCEL(MPEG2_D3D11VA, mpeg2_d3d11va);
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(MPEG4_MMAL, mpeg4_mmal);
REGISTER_HWACCEL(MPEG4_VAAPI, mpeg4_vaapi);
REGISTER_HWACCEL(MPEG4_VDPAU, mpeg4_vdpau);
REGISTER_HWACCEL(MPEG4_VIDEOTOOLBOX, mpeg4_videotoolbox);
REGISTER_HWACCEL(VC1_CUVID, vc1_cuvid);
REGISTER_HWACCEL(VC1_D3D11VA, vc1_d3d11va);
REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2);
REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi);
REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau);
REGISTER_HWACCEL(VC1_MMAL, vc1_mmal);
REGISTER_HWACCEL(VC1_QSV, vc1_qsv);
REGISTER_HWACCEL(VP8_CUVID, vp8_cuvid);
REGISTER_HWACCEL(VP9_CUVID, vp9_cuvid);
REGISTER_HWACCEL(VP9_D3D11VA, vp9_d3d11va);
REGISTER_HWACCEL(VP9_DXVA2, vp9_dxva2);
REGISTER_HWACCEL(VP9_VAAPI, vp9_vaapi);
REGISTER_HWACCEL(WMV3_D3D11VA, wmv3_d3d11va);
REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2);
REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi);
REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau);
/* video codecs */
REGISTER_ENCODER(A64MULTI, a64multi);
REGISTER_ENCODER(A64MULTI5, a64multi5);
REGISTER_DECODER(AASC, aasc);
REGISTER_DECODER(AIC, aic);
REGISTER_ENCDEC (ALIAS_PIX, alias_pix);
REGISTER_ENCDEC (AMV, amv);
REGISTER_DECODER(ANM, anm);
REGISTER_DECODER(ANSI, ansi);
REGISTER_ENCDEC (APNG, apng);
REGISTER_ENCDEC (ASV1, asv1);
REGISTER_ENCDEC (ASV2, asv2);
REGISTER_DECODER(AURA, aura);
REGISTER_DECODER(AURA2, aura2);
REGISTER_ENCDEC (AVRP, avrp);
REGISTER_DECODER(AVRN, avrn);
REGISTER_DECODER(AVS, avs);
REGISTER_ENCDEC (AVUI, avui);
REGISTER_ENCDEC (AYUV, ayuv);
REGISTER_DECODER(BETHSOFTVID, bethsoftvid);
REGISTER_DECODER(BFI, bfi);
REGISTER_DECODER(BINK, bink);
REGISTER_ENCDEC (BMP, bmp);
REGISTER_DECODER(BMV_VIDEO, bmv_video);
REGISTER_DECODER(BRENDER_PIX, brender_pix);
REGISTER_DECODER(C93, c93);
REGISTER_DECODER(CAVS, cavs);
REGISTER_DECODER(CDGRAPHICS, cdgraphics);
REGISTER_DECODER(CDXL, cdxl);
REGISTER_DECODER(CFHD, cfhd);
REGISTER_ENCDEC (CINEPAK, cinepak);
REGISTER_ENCDEC (CLJR, cljr);
REGISTER_DECODER(CLLC, cllc);
REGISTER_ENCDEC (COMFORTNOISE, comfortnoise);
REGISTER_DECODER(CPIA, cpia);
REGISTER_DECODER(CSCD, cscd);
REGISTER_DECODER(CYUV, cyuv);
REGISTER_DECODER(DDS, dds);
REGISTER_DECODER(DFA, dfa);
REGISTER_DECODER(DIRAC, dirac);
REGISTER_ENCDEC (DNXHD, dnxhd);
REGISTER_ENCDEC (DPX, dpx);
REGISTER_DECODER(DSICINVIDEO, dsicinvideo);
REGISTER_DECODER(DVAUDIO, dvaudio);
REGISTER_ENCDEC (DVVIDEO, dvvideo);
REGISTER_DECODER(DXA, dxa);
REGISTER_DECODER(DXTORY, dxtory);
REGISTER_DECODER(DXV, dxv);
REGISTER_DECODER(EACMV, eacmv);
REGISTER_DECODER(EAMAD, eamad);
REGISTER_DECODER(EATGQ, eatgq);
REGISTER_DECODER(EATGV, eatgv);
REGISTER_DECODER(EATQI, eatqi);
REGISTER_DECODER(EIGHTBPS, eightbps);
REGISTER_DECODER(EIGHTSVX_EXP, eightsvx_exp);
REGISTER_DECODER(EIGHTSVX_FIB, eightsvx_fib);
REGISTER_DECODER(ESCAPE124, escape124);
REGISTER_DECODER(ESCAPE130, escape130);
REGISTER_DECODER(EXR, exr);
REGISTER_ENCDEC (FFV1, ffv1);
REGISTER_ENCDEC (FFVHUFF, ffvhuff);
REGISTER_DECODER(FIC, fic);
REGISTER_ENCDEC (FLASHSV, flashsv);
REGISTER_ENCDEC (FLASHSV2, flashsv2);
REGISTER_DECODER(FLIC, flic);
REGISTER_ENCDEC (FLV, flv);
REGISTER_DECODER(FOURXM, fourxm);
REGISTER_DECODER(FRAPS, fraps);
REGISTER_DECODER(FRWU, frwu);
REGISTER_DECODER(G2M, g2m);
REGISTER_ENCDEC (GIF, gif);
REGISTER_ENCDEC (H261, h261);
REGISTER_ENCDEC (H263, h263);
REGISTER_DECODER(H263I, h263i);
REGISTER_ENCDEC (H263P, h263p);
REGISTER_DECODER(H264, h264);
REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd);
REGISTER_DECODER(H264_MEDIACODEC, h264_mediacodec);
REGISTER_DECODER(H264_MMAL, h264_mmal);
REGISTER_DECODER(H264_QSV, h264_qsv);
REGISTER_DECODER(H264_VDA, h264_vda);
#if FF_API_VDPAU
REGISTER_DECODER(H264_VDPAU, h264_vdpau);
#endif
REGISTER_ENCDEC (HAP, hap);
REGISTER_DECODER(HEVC, hevc);
REGISTER_DECODER(HEVC_QSV, hevc_qsv);
REGISTER_DECODER(HNM4_VIDEO, hnm4_video);
REGISTER_DECODER(HQ_HQA, hq_hqa);
REGISTER_DECODER(HQX, hqx);
REGISTER_ENCDEC (HUFFYUV, huffyuv);
REGISTER_DECODER(IDCIN, idcin);
REGISTER_DECODER(IFF_ILBM, iff_ilbm);
REGISTER_DECODER(INDEO2, indeo2);
REGISTER_DECODER(INDEO3, indeo3);
REGISTER_DECODER(INDEO4, indeo4);
REGISTER_DECODER(INDEO5, indeo5);
REGISTER_DECODER(INTERPLAY_VIDEO, interplay_video);
REGISTER_ENCDEC (JPEG2000, jpeg2000);
REGISTER_ENCDEC (JPEGLS, jpegls);
REGISTER_DECODER(JV, jv);
REGISTER_DECODER(KGV1, kgv1);
REGISTER_DECODER(KMVC, kmvc);
REGISTER_DECODER(LAGARITH, lagarith);
REGISTER_ENCODER(LJPEG, ljpeg);
REGISTER_DECODER(LOCO, loco);
REGISTER_DECODER(M101, m101);
REGISTER_DECODER(MAGICYUV, magicyuv);
REGISTER_DECODER(MDEC, mdec);
REGISTER_DECODER(MIMIC, mimic);
REGISTER_ENCDEC (MJPEG, mjpeg);
REGISTER_DECODER(MJPEGB, mjpegb);
REGISTER_DECODER(MMVIDEO, mmvideo);
REGISTER_DECODER(MOTIONPIXELS, motionpixels);
#if FF_API_XVMC
REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc);
#endif /* FF_API_XVMC */
REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video);
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video);
REGISTER_ENCDEC (MPEG4, mpeg4);
REGISTER_DECODER(MPEG4_CRYSTALHD, mpeg4_crystalhd);
REGISTER_DECODER(MPEG4_MMAL, mpeg4_mmal);
#if FF_API_VDPAU
REGISTER_DECODER(MPEG4_VDPAU, mpeg4_vdpau);
#endif
REGISTER_DECODER(MPEGVIDEO, mpegvideo);
#if FF_API_VDPAU
REGISTER_DECODER(MPEG_VDPAU, mpeg_vdpau);
REGISTER_DECODER(MPEG1_VDPAU, mpeg1_vdpau);
#endif
REGISTER_DECODER(MPEG2_MMAL, mpeg2_mmal);
REGISTER_DECODER(MPEG2_CRYSTALHD, mpeg2_crystalhd);
REGISTER_DECODER(MPEG2_QSV, mpeg2_qsv);
REGISTER_DECODER(MSA1, msa1);
REGISTER_DECODER(MSMPEG4_CRYSTALHD, msmpeg4_crystalhd);
REGISTER_DECODER(MSMPEG4V1, msmpeg4v1);
REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);
REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);
REGISTER_DECODER(MSRLE, msrle);
REGISTER_DECODER(MSS1, mss1);
REGISTER_DECODER(MSS2, mss2);
REGISTER_ENCDEC (MSVIDEO1, msvideo1);
REGISTER_DECODER(MSZH, mszh);
REGISTER_DECODER(MTS2, mts2);
REGISTER_DECODER(MVC1, mvc1);
REGISTER_DECODER(MVC2, mvc2);
REGISTER_DECODER(MXPEG, mxpeg);
REGISTER_DECODER(NUV, nuv);
REGISTER_DECODER(PAF_VIDEO, paf_video);
REGISTER_ENCDEC (PAM, pam);
REGISTER_ENCDEC (PBM, pbm);
REGISTER_ENCDEC (PCX, pcx);
REGISTER_ENCDEC (PGM, pgm);
REGISTER_ENCDEC (PGMYUV, pgmyuv);
REGISTER_DECODER(PICTOR, pictor);
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(PTX, ptx);
REGISTER_DECODER(QDRAW, qdraw);
REGISTER_DECODER(QPEG, qpeg);
REGISTER_ENCDEC (QTRLE, qtrle);
REGISTER_ENCDEC (R10K, r10k);
REGISTER_ENCDEC (R210, r210);
REGISTER_ENCDEC (RAWVIDEO, rawvideo);
REGISTER_DECODER(RL2, rl2);
REGISTER_ENCDEC (ROQ, roq);
REGISTER_DECODER(RPZA, rpza);
REGISTER_DECODER(RSCC, rscc);
REGISTER_ENCDEC (RV10, rv10);
REGISTER_ENCDEC (RV20, rv20);
REGISTER_DECODER(RV30, rv30);
REGISTER_DECODER(RV40, rv40);
REGISTER_ENCDEC (S302M, s302m);
REGISTER_DECODER(SANM, sanm);
REGISTER_DECODER(SCREENPRESSO, screenpresso);
REGISTER_DECODER(SDX2_DPCM, sdx2_dpcm);
REGISTER_ENCDEC (SGI, sgi);
REGISTER_DECODER(SGIRLE, sgirle);
REGISTER_DECODER(SHEERVIDEO, sheervideo);
REGISTER_DECODER(SMACKER, smacker);
REGISTER_DECODER(SMC, smc);
REGISTER_DECODER(SMVJPEG, smvjpeg);
REGISTER_ENCDEC (SNOW, snow);
REGISTER_DECODER(SP5X, sp5x);
REGISTER_ENCDEC (SUNRAST, sunrast);
REGISTER_ENCDEC (SVQ1, svq1);
REGISTER_DECODER(SVQ3, svq3);
REGISTER_ENCDEC (TARGA, targa);
REGISTER_DECODER(TARGA_Y216, targa_y216);
REGISTER_DECODER(TDSC, tdsc);
REGISTER_DECODER(THEORA, theora);
REGISTER_DECODER(THP, thp);
REGISTER_DECODER(TIERTEXSEQVIDEO, tiertexseqvideo);
REGISTER_ENCDEC (TIFF, tiff);
REGISTER_DECODER(TMV, tmv);
REGISTER_DECODER(TRUEMOTION1, truemotion1);
REGISTER_DECODER(TRUEMOTION2, truemotion2);
REGISTER_DECODER(TRUEMOTION2RT, truemotion2rt);
REGISTER_DECODER(TSCC, tscc);
REGISTER_DECODER(TSCC2, tscc2);
REGISTER_DECODER(TXD, txd);
REGISTER_DECODER(ULTI, ulti);
REGISTER_ENCDEC (UTVIDEO, utvideo);
REGISTER_ENCDEC (V210, v210);
REGISTER_DECODER(V210X, v210x);
REGISTER_ENCDEC (V308, v308);
REGISTER_ENCDEC (V408, v408);
REGISTER_ENCDEC (V410, v410);
REGISTER_DECODER(VB, vb);
REGISTER_DECODER(VBLE, vble);
REGISTER_DECODER(VC1, vc1);
REGISTER_DECODER(VC1_CRYSTALHD, vc1_crystalhd);
#if FF_API_VDPAU
REGISTER_DECODER(VC1_VDPAU, vc1_vdpau);
#endif
REGISTER_DECODER(VC1IMAGE, vc1image);
REGISTER_DECODER(VC1_MMAL, vc1_mmal);
REGISTER_DECODER(VC1_QSV, vc1_qsv);
REGISTER_ENCODER(VC2, vc2);
REGISTER_DECODER(VCR1, vcr1);
REGISTER_DECODER(VMDVIDEO, vmdvideo);
REGISTER_DECODER(VMNC, vmnc);
REGISTER_DECODER(VP3, vp3);
REGISTER_DECODER(VP5, vp5);
REGISTER_DECODER(VP6, vp6);
REGISTER_DECODER(VP6A, vp6a);
REGISTER_DECODER(VP6F, vp6f);
REGISTER_DECODER(VP7, vp7);
REGISTER_DECODER(VP8, vp8);
REGISTER_DECODER(VP9, vp9);
REGISTER_DECODER(VQA, vqa);
REGISTER_DECODER(WEBP, webp);
REGISTER_ENCODER(WRAPPED_AVFRAME, wrapped_avframe);
REGISTER_ENCDEC (WMV1, wmv1);
REGISTER_ENCDEC (WMV2, wmv2);
REGISTER_DECODER(WMV3, wmv3);
REGISTER_DECODER(WMV3_CRYSTALHD, wmv3_crystalhd);
#if FF_API_VDPAU
REGISTER_DECODER(WMV3_VDPAU, wmv3_vdpau);
#endif
REGISTER_DECODER(WMV3IMAGE, wmv3image);
REGISTER_DECODER(WNV1, wnv1);
REGISTER_DECODER(XAN_WC3, xan_wc3);
REGISTER_DECODER(XAN_WC4, xan_wc4);
REGISTER_ENCDEC (XBM, xbm);
REGISTER_ENCDEC (XFACE, xface);
REGISTER_DECODER(XL, xl);
REGISTER_ENCDEC (XWD, xwd);
REGISTER_ENCDEC (Y41P, y41p);
REGISTER_DECODER(YLC, ylc);
REGISTER_DECODER(YOP, yop);
REGISTER_ENCDEC (YUV4, yuv4);
REGISTER_DECODER(ZERO12V, zero12v);
REGISTER_DECODER(ZEROCODEC, zerocodec);
REGISTER_ENCDEC (ZLIB, zlib);
REGISTER_ENCDEC (ZMBV, zmbv);
/* audio codecs */
REGISTER_ENCDEC (AAC, aac);
REGISTER_DECODER(AAC_FIXED, aac_fixed);
REGISTER_DECODER(AAC_LATM, aac_latm);
REGISTER_ENCDEC (AC3, ac3);
REGISTER_ENCDEC (AC3_FIXED, ac3_fixed);
REGISTER_ENCDEC (ALAC, alac);
REGISTER_DECODER(ALS, als);
REGISTER_DECODER(AMRNB, amrnb);
REGISTER_DECODER(AMRWB, amrwb);
REGISTER_DECODER(APE, ape);
REGISTER_DECODER(ATRAC1, atrac1);
REGISTER_DECODER(ATRAC3, atrac3);
REGISTER_DECODER(ATRAC3P, atrac3p);
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(DSD_LSBF, dsd_lsbf);
REGISTER_DECODER(DSD_MSBF, dsd_msbf);
REGISTER_DECODER(DSD_LSBF_PLANAR, dsd_lsbf_planar);
REGISTER_DECODER(DSD_MSBF_PLANAR, dsd_msbf_planar);
REGISTER_DECODER(DSICINAUDIO, dsicinaudio);
REGISTER_DECODER(DSS_SP, dss_sp);
REGISTER_DECODER(DST, dst);
REGISTER_ENCDEC (EAC3, eac3);
REGISTER_DECODER(EVRC, evrc);
REGISTER_DECODER(FFWAVESYNTH, ffwavesynth);
REGISTER_ENCDEC (FLAC, flac);
REGISTER_ENCDEC (G723_1, g723_1);
REGISTER_DECODER(G729, g729);
REGISTER_DECODER(GSM, gsm);
REGISTER_DECODER(GSM_MS, gsm_ms);
REGISTER_DECODER(IAC, iac);
REGISTER_DECODER(IMC, imc);
REGISTER_DECODER(INTERPLAY_ACM, interplay_acm);
REGISTER_DECODER(MACE3, mace3);
REGISTER_DECODER(MACE6, mace6);
REGISTER_DECODER(METASOUND, metasound);
REGISTER_DECODER(MLP, mlp);
REGISTER_DECODER(MP1, mp1);
REGISTER_DECODER(MP1FLOAT, mp1float);
REGISTER_ENCDEC (MP2, mp2);
REGISTER_DECODER(MP2FLOAT, mp2float);
REGISTER_ENCODER(MP2FIXED, mp2fixed);
REGISTER_DECODER(MP3, mp3);
REGISTER_DECODER(MP3FLOAT, mp3float);
REGISTER_DECODER(MP3ADU, mp3adu);
REGISTER_DECODER(MP3ADUFLOAT, mp3adufloat);
REGISTER_DECODER(MP3ON4, mp3on4);
REGISTER_DECODER(MP3ON4FLOAT, mp3on4float);
REGISTER_DECODER(MPC7, mpc7);
REGISTER_DECODER(MPC8, mpc8);
REGISTER_ENCDEC (NELLYMOSER, nellymoser);
REGISTER_DECODER(ON2AVC, on2avc);
REGISTER_DECODER(OPUS, opus);
REGISTER_DECODER(PAF_AUDIO, paf_audio);
REGISTER_DECODER(QCELP, qcelp);
REGISTER_DECODER(QDM2, qdm2);
REGISTER_ENCDEC (RA_144, ra_144);
REGISTER_DECODER(RA_288, ra_288);
REGISTER_DECODER(RALF, ralf);
REGISTER_DECODER(SHORTEN, shorten);
REGISTER_DECODER(SIPR, sipr);
REGISTER_DECODER(SMACKAUD, smackaud);
REGISTER_ENCDEC (SONIC, sonic);
REGISTER_ENCODER(SONIC_LS, sonic_ls);
REGISTER_DECODER(TAK, tak);
REGISTER_DECODER(TRUEHD, truehd);
REGISTER_DECODER(TRUESPEECH, truespeech);
REGISTER_ENCDEC (TTA, tta);
REGISTER_DECODER(TWINVQ, twinvq);
REGISTER_DECODER(VMDAUDIO, vmdaudio);
REGISTER_ENCDEC (VORBIS, vorbis);
REGISTER_ENCDEC (WAVPACK, wavpack);
REGISTER_DECODER(WMALOSSLESS, wmalossless);
REGISTER_DECODER(WMAPRO, wmapro);
REGISTER_ENCDEC (WMAV1, wmav1);
REGISTER_ENCDEC (WMAV2, wmav2);
REGISTER_DECODER(WMAVOICE, wmavoice);
REGISTER_DECODER(WS_SND1, ws_snd1);
REGISTER_DECODER(XMA1, xma1);
REGISTER_DECODER(XMA2, xma2);
/* PCM codecs */
REGISTER_ENCDEC (PCM_ALAW, pcm_alaw);
REGISTER_DECODER(PCM_BLURAY, pcm_bluray);
REGISTER_DECODER(PCM_DVD, pcm_dvd);
REGISTER_ENCDEC (PCM_F32BE, pcm_f32be);
REGISTER_ENCDEC (PCM_F32LE, pcm_f32le);
REGISTER_ENCDEC (PCM_F64BE, pcm_f64be);
REGISTER_ENCDEC (PCM_F64LE, pcm_f64le);
REGISTER_DECODER(PCM_LXF, pcm_lxf);
REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw);
REGISTER_ENCDEC (PCM_S8, pcm_s8);
REGISTER_ENCDEC (PCM_S8_PLANAR, pcm_s8_planar);
REGISTER_ENCDEC (PCM_S16BE, pcm_s16be);
REGISTER_ENCDEC (PCM_S16BE_PLANAR, pcm_s16be_planar);
REGISTER_ENCDEC (PCM_S16LE, pcm_s16le);
REGISTER_ENCDEC (PCM_S16LE_PLANAR, pcm_s16le_planar);
REGISTER_ENCDEC (PCM_S24BE, pcm_s24be);
REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud);
REGISTER_ENCDEC (PCM_S24LE, pcm_s24le);
REGISTER_ENCDEC (PCM_S24LE_PLANAR, pcm_s24le_planar);
REGISTER_ENCDEC (PCM_S32BE, pcm_s32be);
REGISTER_ENCDEC (PCM_S32LE, pcm_s32le);
REGISTER_ENCDEC (PCM_S32LE_PLANAR, pcm_s32le_planar);
REGISTER_ENCDEC (PCM_U8, pcm_u8);
REGISTER_ENCDEC (PCM_U16BE, pcm_u16be);
REGISTER_ENCDEC (PCM_U16LE, pcm_u16le);
REGISTER_ENCDEC (PCM_U24BE, pcm_u24be);
REGISTER_ENCDEC (PCM_U24LE, pcm_u24le);
REGISTER_ENCDEC (PCM_U32BE, pcm_u32be);
REGISTER_ENCDEC (PCM_U32LE, pcm_u32le);
REGISTER_DECODER(PCM_ZORK, pcm_zork);
/* DPCM codecs */
REGISTER_DECODER(INTERPLAY_DPCM, interplay_dpcm);
REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm);
REGISTER_DECODER(SOL_DPCM, sol_dpcm);
REGISTER_DECODER(XAN_DPCM, xan_dpcm);
/* ADPCM codecs */
REGISTER_DECODER(ADPCM_4XM, adpcm_4xm);
REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx);
REGISTER_DECODER(ADPCM_AFC, adpcm_afc);
REGISTER_DECODER(ADPCM_AICA, adpcm_aica);
REGISTER_DECODER(ADPCM_CT, adpcm_ct);
REGISTER_DECODER(ADPCM_DTK, adpcm_dtk);
REGISTER_DECODER(ADPCM_EA, adpcm_ea);
REGISTER_DECODER(ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa);
REGISTER_DECODER(ADPCM_EA_R1, adpcm_ea_r1);
REGISTER_DECODER(ADPCM_EA_R2, adpcm_ea_r2);
REGISTER_DECODER(ADPCM_EA_R3, adpcm_ea_r3);
REGISTER_DECODER(ADPCM_EA_XAS, adpcm_ea_xas);
REGISTER_ENCDEC (ADPCM_G722, adpcm_g722);
REGISTER_ENCDEC (ADPCM_G726, adpcm_g726);
REGISTER_DECODER(ADPCM_G726LE, adpcm_g726le);
REGISTER_DECODER(ADPCM_IMA_AMV, adpcm_ima_amv);
REGISTER_DECODER(ADPCM_IMA_APC, adpcm_ima_apc);
REGISTER_DECODER(ADPCM_IMA_DAT4, adpcm_ima_dat4);
REGISTER_DECODER(ADPCM_IMA_DK3, adpcm_ima_dk3);
REGISTER_DECODER(ADPCM_IMA_DK4, adpcm_ima_dk4);
REGISTER_DECODER(ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs);
REGISTER_DECODER(ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead);
REGISTER_DECODER(ADPCM_IMA_ISS, adpcm_ima_iss);
REGISTER_DECODER(ADPCM_IMA_OKI, adpcm_ima_oki);
REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt);
REGISTER_DECODER(ADPCM_IMA_RAD, adpcm_ima_rad);
REGISTER_DECODER(ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg);
REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav);
REGISTER_DECODER(ADPCM_IMA_WS, adpcm_ima_ws);
REGISTER_ENCDEC (ADPCM_MS, adpcm_ms);
REGISTER_DECODER(ADPCM_MTAF, adpcm_mtaf);
REGISTER_DECODER(ADPCM_PSX, adpcm_psx);
REGISTER_DECODER(ADPCM_SBPRO_2, adpcm_sbpro_2);
REGISTER_DECODER(ADPCM_SBPRO_3, adpcm_sbpro_3);
REGISTER_DECODER(ADPCM_SBPRO_4, adpcm_sbpro_4);
REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf);
REGISTER_DECODER(ADPCM_THP, adpcm_thp);
REGISTER_DECODER(ADPCM_THP_LE, adpcm_thp_le);
REGISTER_DECODER(ADPCM_VIMA, adpcm_vima);
REGISTER_DECODER(ADPCM_XA, adpcm_xa);
REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha);
/* subtitles */
REGISTER_ENCDEC (SSA, ssa);
REGISTER_ENCDEC (ASS, ass);
REGISTER_DECODER(CCAPTION, ccaption);
REGISTER_ENCDEC (DVBSUB, dvbsub);
REGISTER_ENCDEC (DVDSUB, dvdsub);
REGISTER_DECODER(JACOSUB, jacosub);
REGISTER_DECODER(MICRODVD, microdvd);
REGISTER_ENCDEC (MOVTEXT, movtext);
REGISTER_DECODER(MPL2, mpl2);
REGISTER_DECODER(PGSSUB, pgssub);
REGISTER_DECODER(PJS, pjs);
REGISTER_DECODER(REALTEXT, realtext);
REGISTER_DECODER(SAMI, sami);
REGISTER_ENCDEC (SRT, srt);
REGISTER_DECODER(STL, stl);
REGISTER_ENCDEC (SUBRIP, subrip);
REGISTER_DECODER(SUBVIEWER, subviewer);
REGISTER_DECODER(SUBVIEWER1, subviewer1);
REGISTER_ENCDEC (TEXT, text);
REGISTER_DECODER(VPLAYER, vplayer);
REGISTER_ENCDEC (WEBVTT, webvtt);
REGISTER_ENCDEC (XSUB, xsub);
/* external libraries */
REGISTER_ENCDEC (AAC_AT, aac_at);
REGISTER_DECODER(AC3_AT, ac3_at);
REGISTER_DECODER(ADPCM_IMA_QT_AT, adpcm_ima_qt_at);
REGISTER_ENCDEC (ALAC_AT, alac_at);
REGISTER_DECODER(AMR_NB_AT, amr_nb_at);
REGISTER_DECODER(EAC3_AT, eac3_at);
REGISTER_DECODER(GSM_MS_AT, gsm_ms_at);
REGISTER_ENCDEC (ILBC_AT, ilbc_at);
REGISTER_DECODER(MP1_AT, mp1_at);
REGISTER_DECODER(MP2_AT, mp2_at);
REGISTER_DECODER(MP3_AT, mp3_at);
REGISTER_ENCDEC (PCM_ALAW_AT, pcm_alaw_at);
REGISTER_ENCDEC (PCM_MULAW_AT, pcm_mulaw_at);
REGISTER_DECODER(QDMC_AT, qdmc_at);
REGISTER_DECODER(QDM2_AT, qdm2_at);
REGISTER_DECODER(LIBCELT, libcelt);
REGISTER_ENCODER(LIBFAAC, libfaac);
REGISTER_ENCDEC (LIBFDK_AAC, libfdk_aac);
REGISTER_ENCDEC (LIBGSM, libgsm);
REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms);
REGISTER_ENCDEC (LIBILBC, libilbc);
REGISTER_ENCODER(LIBMP3LAME, libmp3lame);
REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb);
REGISTER_DECODER(LIBOPENCORE_AMRWB, libopencore_amrwb);
REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg);
REGISTER_ENCDEC (LIBOPUS, libopus);
REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger);
REGISTER_ENCODER(LIBSHINE, libshine);
REGISTER_ENCDEC (LIBSPEEX, libspeex);
REGISTER_ENCODER(LIBTHEORA, libtheora);
REGISTER_ENCODER(LIBTWOLAME, libtwolame);
REGISTER_ENCODER(LIBVO_AMRWBENC, libvo_amrwbenc);
REGISTER_ENCDEC (LIBVORBIS, libvorbis);
REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8);
REGISTER_ENCDEC (LIBVPX_VP9, libvpx_vp9);
REGISTER_ENCODER(LIBWAVPACK, libwavpack);
REGISTER_ENCODER(LIBWEBP_ANIM, libwebp_anim); /* preferred over libwebp */
REGISTER_ENCODER(LIBWEBP, libwebp);
REGISTER_ENCODER(LIBX262, libx262);
REGISTER_ENCODER(LIBX264, libx264);
REGISTER_ENCODER(LIBX264RGB, libx264rgb);
REGISTER_ENCODER(LIBX265, libx265);
REGISTER_ENCODER(LIBXAVS, libxavs);
REGISTER_ENCODER(LIBXVID, libxvid);
REGISTER_DECODER(LIBZVBI_TELETEXT, libzvbi_teletext);
/* text */
REGISTER_DECODER(BINTEXT, bintext);
REGISTER_DECODER(XBIN, xbin);
REGISTER_DECODER(IDF, idf);
/* external libraries, that shouldn't be used by default if one of the
* above is available */
REGISTER_ENCODER(LIBOPENH264, libopenh264);
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_VAAPI, h264_vaapi);
REGISTER_ENCODER(H264_VIDEOTOOLBOX, h264_videotoolbox);
#if FF_API_NVENC_OLD_NAME
REGISTER_ENCODER(NVENC, nvenc);
REGISTER_ENCODER(NVENC_H264, nvenc_h264);
REGISTER_ENCODER(NVENC_HEVC, nvenc_hevc);
#endif
REGISTER_DECODER(HEVC_CUVID, hevc_cuvid);
REGISTER_ENCODER(HEVC_NVENC, hevc_nvenc);
REGISTER_ENCODER(HEVC_QSV, hevc_qsv);
REGISTER_ENCODER(HEVC_VAAPI, hevc_vaapi);
REGISTER_ENCODER(LIBKVAZAAR, libkvazaar);
REGISTER_ENCODER(MJPEG_VAAPI, mjpeg_vaapi);
REGISTER_ENCODER(MPEG2_QSV, mpeg2_qsv);
REGISTER_DECODER(VC1_CUVID, vc1_cuvid);
REGISTER_DECODER(VP8_CUVID, vp8_cuvid);
REGISTER_DECODER(VP9_CUVID, vp9_cuvid);
/* parsers */
REGISTER_PARSER(AAC, aac);
REGISTER_PARSER(AAC_LATM, aac_latm);
REGISTER_PARSER(AC3, ac3);
REGISTER_PARSER(ADX, adx);
REGISTER_PARSER(BMP, bmp);
REGISTER_PARSER(CAVSVIDEO, cavsvideo);
REGISTER_PARSER(COOK, cook);
REGISTER_PARSER(DCA, dca);
REGISTER_PARSER(DIRAC, dirac);
REGISTER_PARSER(DNXHD, dnxhd);
REGISTER_PARSER(DPX, dpx);
REGISTER_PARSER(DVAUDIO, dvaudio);
REGISTER_PARSER(DVBSUB, dvbsub);
REGISTER_PARSER(DVDSUB, dvdsub);
REGISTER_PARSER(DVD_NAV, dvd_nav);
REGISTER_PARSER(FLAC, flac);
REGISTER_PARSER(G729, g729);
REGISTER_PARSER(GSM, gsm);
REGISTER_PARSER(H261, h261);
REGISTER_PARSER(H263, h263);
REGISTER_PARSER(H264, h264);
REGISTER_PARSER(HEVC, hevc);
REGISTER_PARSER(MJPEG, mjpeg);
REGISTER_PARSER(MLP, mlp);
REGISTER_PARSER(MPEG4VIDEO, mpeg4video);
REGISTER_PARSER(MPEGAUDIO, mpegaudio);
REGISTER_PARSER(MPEGVIDEO, mpegvideo);
REGISTER_PARSER(OPUS, opus);
REGISTER_PARSER(PNG, png);
REGISTER_PARSER(PNM, pnm);
REGISTER_PARSER(RV30, rv30);
REGISTER_PARSER(RV40, rv40);
REGISTER_PARSER(TAK, tak);
REGISTER_PARSER(VC1, vc1);
REGISTER_PARSER(VORBIS, vorbis);
REGISTER_PARSER(VP3, vp3);
REGISTER_PARSER(VP8, vp8);
REGISTER_PARSER(VP9, vp9);
}

View file

@ -0,0 +1,120 @@
/*
* audio conversion
* 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
*/
/**
* @file
* audio conversion
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include "libavutil/avstring.h"
#include "libavutil/common.h"
#include "libavutil/libm.h"
#include "libavutil/samplefmt.h"
#include "avcodec.h"
#include "audioconvert.h"
#if FF_API_AUDIO_CONVERT
struct AVAudioConvert {
int in_channels, out_channels;
int fmt_pair;
};
AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
enum AVSampleFormat in_fmt, int in_channels,
const float *matrix, int flags)
{
AVAudioConvert *ctx;
if (in_channels!=out_channels)
return NULL; /* FIXME: not supported */
ctx = av_malloc(sizeof(AVAudioConvert));
if (!ctx)
return NULL;
ctx->in_channels = in_channels;
ctx->out_channels = out_channels;
ctx->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt;
return ctx;
}
void av_audio_convert_free(AVAudioConvert *ctx)
{
av_free(ctx);
}
int av_audio_convert(AVAudioConvert *ctx,
void * const out[6], const int out_stride[6],
const void * const in[6], const int in_stride[6], int len)
{
int ch;
//FIXME optimize common cases
for(ch=0; ch<ctx->out_channels; ch++){
const int is= in_stride[ch];
const int os= out_stride[ch];
const uint8_t *pi= in[ch];
uint8_t *po= out[ch];
uint8_t *end= po + os*len;
if(!out[ch])
continue;
#define CONV(ofmt, otype, ifmt, expr)\
if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\
do{\
*(otype*)po = expr; pi += is; po += os;\
}while(po < end);\
}
//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
//FIXME rounding ?
CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi)
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi)
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16)
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16)
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi)
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31)))
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31)))
else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80))
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15))))
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi)
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi)
else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80))
else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15))))
else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi)
else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi)
else return -1;
}
return 0;
}
#endif /* FF_API_AUDIO_CONVERT */

View file

@ -0,0 +1,86 @@
/*
* audio conversion
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2008 Peter Ross
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_AUDIOCONVERT_H
#define AVCODEC_AUDIOCONVERT_H
#include "version.h"
/**
* @file
* Audio format conversion routines
* This interface is deprecated and will be dropped in a future
* version. You should use the libswresample library instead.
*/
#if FF_API_AUDIO_CONVERT
#include "libavutil/cpu.h"
#include "avcodec.h"
#include "libavutil/channel_layout.h"
struct AVAudioConvert;
typedef struct AVAudioConvert AVAudioConvert;
/**
* Create an audio sample format converter context
* @param out_fmt Output sample format
* @param out_channels Number of output channels
* @param in_fmt Input sample format
* @param in_channels Number of input channels
* @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore.
* @param flags See AV_CPU_FLAG_xx
* @return NULL on error
* @deprecated See libswresample
*/
attribute_deprecated
AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
enum AVSampleFormat in_fmt, int in_channels,
const float *matrix, int flags);
/**
* Free audio sample format converter context
* @deprecated See libswresample
*/
attribute_deprecated
void av_audio_convert_free(AVAudioConvert *ctx);
/**
* Convert between audio sample formats
* @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel.
* @param[in] out_stride distance between consecutive output samples (measured in bytes)
* @param[in] in array of input buffers for each channel
* @param[in] in_stride distance between consecutive input samples (measured in bytes)
* @param len length of audio frame size (measured in samples)
* @deprecated See libswresample
*/
attribute_deprecated
int av_audio_convert(AVAudioConvert *ctx,
void * const out[6], const int out_stride[6],
const void * const in[6], const int in_stride[6], int len);
#endif /* FF_API_AUDIO_CONVERT */
#endif /* AVCODEC_AUDIOCONVERT_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,129 @@
av_bitstream_filter_close
av_bitstream_filter_filter
av_bitstream_filter_init
av_bitstream_filter_next
av_codec_ffversion
av_codec_get_chroma_intra_matrix
av_codec_get_codec_descriptor
av_codec_get_codec_properties
av_codec_get_lowres
av_codec_get_max_lowres
av_codec_get_pkt_timebase
av_codec_get_seek_preroll
av_codec_is_decoder
av_codec_is_encoder
av_codec_next
av_codec_set_chroma_intra_matrix
av_codec_set_codec_descriptor
av_codec_set_lowres
av_codec_set_pkt_timebase
av_codec_set_seek_preroll
av_copy_packet
av_copy_packet_side_data
av_dup_packet
av_fast_padded_malloc
av_fast_padded_mallocz
av_free_packet
av_get_audio_frame_duration
av_get_bits_per_sample
av_get_codec_tag_string
av_get_exact_bits_per_sample
av_get_pcm_codec
av_get_profile_name
av_grow_packet
av_hwaccel_next
av_init_packet
av_lockmgr_register
av_log_ask_for_sample
av_log_missing_feature
av_new_packet
av_packet_copy_props
av_packet_free_side_data
av_packet_from_data
av_packet_get_side_data
av_packet_merge_side_data
av_packet_move_ref
av_packet_new_side_data
av_packet_pack_dictionary
av_packet_ref
av_packet_rescale_ts
av_packet_shrink_side_data
av_packet_side_data_name
av_packet_split_side_data
av_packet_unpack_dictionary
av_packet_unref
av_parser_change
av_parser_close
av_parser_init
av_parser_next
av_parser_parse2
av_picture_copy
av_picture_crop
av_picture_pad
av_qsv_alloc_context
av_register_bitstream_filter
av_register_codec_parser
av_register_hwaccel
av_resample
av_resample_close
av_resample_compensate
av_resample_init
av_shrink_packet
av_vorbis_parse_frame
av_vorbis_parse_frame_flags
av_vorbis_parse_free
av_vorbis_parse_init
av_vorbis_parse_reset
av_xiphlacing
avcodec_align_dimensions
avcodec_align_dimensions2
avcodec_alloc_context3
avcodec_chroma_pos_to_enum
avcodec_close
avcodec_configuration
avcodec_copy_context
avcodec_decode_audio4
avcodec_decode_subtitle2
avcodec_decode_video2
avcodec_default_execute
avcodec_default_execute2
avcodec_default_get_buffer2
avcodec_default_get_format
avcodec_descriptor_get
avcodec_descriptor_get_by_name
avcodec_descriptor_next
avcodec_enum_to_chroma_pos
avcodec_fill_audio_frame
avcodec_find_best_pix_fmt2
avcodec_find_best_pix_fmt_of_2
avcodec_find_best_pix_fmt_of_list
avcodec_find_decoder
avcodec_find_decoder_by_name
avcodec_find_encoder
avcodec_find_encoder_by_name
avcodec_flush_buffers
avcodec_free_context
avcodec_get_chroma_sub_sample
avcodec_get_class
avcodec_get_context_defaults3
avcodec_get_edge_width
avcodec_get_frame_class
avcodec_get_name
avcodec_get_pix_fmt_loss
avcodec_get_subtitle_rect_class
avcodec_get_type
avcodec_is_open
avcodec_license
avcodec_open2
avcodec_pix_fmt_to_codec_tag
avcodec_register
avcodec_register_all
avcodec_set_dimensions
avcodec_string
avcodec_version
avpicture_alloc
avpicture_fill
avpicture_free
avpicture_get_size
avpicture_layout
avsubtitle_free

View file

@ -0,0 +1,84 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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 */

View file

@ -0,0 +1,664 @@
/*
* AVPacket functions for libavcodec
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/internal.h"
#include "libavutil/mathematics.h"
#include "libavutil/mem.h"
#include "avcodec.h"
#include "bytestream.h"
#include "internal.h"
void av_init_packet(AVPacket *pkt)
{
pkt->pts = AV_NOPTS_VALUE;
pkt->dts = AV_NOPTS_VALUE;
pkt->pos = -1;
pkt->duration = 0;
#if FF_API_CONVERGENCE_DURATION
FF_DISABLE_DEPRECATION_WARNINGS
pkt->convergence_duration = 0;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
pkt->flags = 0;
pkt->stream_index = 0;
pkt->buf = NULL;
pkt->side_data = NULL;
pkt->side_data_elems = 0;
}
AVPacket *av_packet_alloc(void)
{
AVPacket *pkt = av_mallocz(sizeof(AVPacket));
if (!pkt)
return pkt;
av_packet_unref(pkt);
return pkt;
}
void av_packet_free(AVPacket **pkt)
{
if (!pkt || !*pkt)
return;
av_packet_unref(*pkt);
av_freep(pkt);
}
static int packet_alloc(AVBufferRef **buf, int size)
{
int ret;
if (size < 0 || size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
return AVERROR(EINVAL);
ret = av_buffer_realloc(buf, size + AV_INPUT_BUFFER_PADDING_SIZE);
if (ret < 0)
return ret;
memset((*buf)->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
return 0;
}
int av_new_packet(AVPacket *pkt, int size)
{
AVBufferRef *buf = NULL;
int ret = packet_alloc(&buf, size);
if (ret < 0)
return ret;
av_init_packet(pkt);
pkt->buf = buf;
pkt->data = buf->data;
pkt->size = size;
return 0;
}
void av_shrink_packet(AVPacket *pkt, int size)
{
if (pkt->size <= size)
return;
pkt->size = size;
memset(pkt->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
}
int av_grow_packet(AVPacket *pkt, int grow_by)
{
int new_size;
av_assert0((unsigned)pkt->size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE);
if ((unsigned)grow_by >
INT_MAX - (pkt->size + AV_INPUT_BUFFER_PADDING_SIZE))
return -1;
new_size = pkt->size + grow_by + AV_INPUT_BUFFER_PADDING_SIZE;
if (pkt->buf) {
size_t data_offset;
uint8_t *old_data = pkt->data;
if (pkt->data == NULL) {
data_offset = 0;
pkt->data = pkt->buf->data;
} else {
data_offset = pkt->data - pkt->buf->data;
if (data_offset > INT_MAX - new_size)
return -1;
}
if (new_size + data_offset > pkt->buf->size) {
int ret = av_buffer_realloc(&pkt->buf, new_size + data_offset);
if (ret < 0) {
pkt->data = old_data;
return ret;
}
pkt->data = pkt->buf->data + data_offset;
}
} else {
pkt->buf = av_buffer_alloc(new_size);
if (!pkt->buf)
return AVERROR(ENOMEM);
memcpy(pkt->buf->data, pkt->data, pkt->size);
pkt->data = pkt->buf->data;
}
pkt->size += grow_by;
memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
return 0;
}
int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
{
if (size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
return AVERROR(EINVAL);
pkt->buf = av_buffer_create(data, size + AV_INPUT_BUFFER_PADDING_SIZE,
av_buffer_default_free, NULL, 0);
if (!pkt->buf)
return AVERROR(ENOMEM);
pkt->data = data;
pkt->size = size;
return 0;
}
#if FF_API_AVPACKET_OLD_API
FF_DISABLE_DEPRECATION_WARNINGS
#define ALLOC_MALLOC(data, size) data = av_malloc(size)
#define ALLOC_BUF(data, size) \
do { \
av_buffer_realloc(&pkt->buf, size); \
data = pkt->buf ? pkt->buf->data : NULL; \
} while (0)
#define DUP_DATA(dst, src, size, padding, ALLOC) \
do { \
void *data; \
if (padding) { \
if ((unsigned)(size) > \
(unsigned)(size) + AV_INPUT_BUFFER_PADDING_SIZE) \
goto failed_alloc; \
ALLOC(data, size + AV_INPUT_BUFFER_PADDING_SIZE); \
} else { \
ALLOC(data, size); \
} \
if (!data) \
goto failed_alloc; \
memcpy(data, src, size); \
if (padding) \
memset((uint8_t *)data + size, 0, \
AV_INPUT_BUFFER_PADDING_SIZE); \
dst = data; \
} while (0)
/* Makes duplicates of data, side_data, but does not copy any other fields */
static int copy_packet_data(AVPacket *pkt, const AVPacket *src, int dup)
{
pkt->data = NULL;
pkt->side_data = NULL;
if (pkt->buf) {
AVBufferRef *ref = av_buffer_ref(src->buf);
if (!ref)
return AVERROR(ENOMEM);
pkt->buf = ref;
pkt->data = ref->data;
} else {
DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
}
if (pkt->side_data_elems && dup)
pkt->side_data = src->side_data;
if (pkt->side_data_elems && !dup) {
return av_copy_packet_side_data(pkt, src);
}
return 0;
failed_alloc:
av_packet_unref(pkt);
return AVERROR(ENOMEM);
}
int av_copy_packet_side_data(AVPacket *pkt, const AVPacket *src)
{
if (src->side_data_elems) {
int i;
DUP_DATA(pkt->side_data, src->side_data,
src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC);
if (src != pkt) {
memset(pkt->side_data, 0,
src->side_data_elems * sizeof(*src->side_data));
}
for (i = 0; i < src->side_data_elems; i++) {
DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
src->side_data[i].size, 1, ALLOC_MALLOC);
pkt->side_data[i].size = src->side_data[i].size;
pkt->side_data[i].type = src->side_data[i].type;
}
}
pkt->side_data_elems = src->side_data_elems;
return 0;
failed_alloc:
av_packet_unref(pkt);
return AVERROR(ENOMEM);
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
int av_dup_packet(AVPacket *pkt)
{
AVPacket tmp_pkt;
if (!pkt->buf && pkt->data) {
tmp_pkt = *pkt;
return copy_packet_data(pkt, &tmp_pkt, 1);
}
return 0;
}
int av_copy_packet(AVPacket *dst, const AVPacket *src)
{
*dst = *src;
return copy_packet_data(dst, src, 0);
}
void av_packet_free_side_data(AVPacket *pkt)
{
int i;
for (i = 0; i < pkt->side_data_elems; i++)
av_freep(&pkt->side_data[i].data);
av_freep(&pkt->side_data);
pkt->side_data_elems = 0;
}
#if FF_API_AVPACKET_OLD_API
FF_DISABLE_DEPRECATION_WARNINGS
void av_free_packet(AVPacket *pkt)
{
if (pkt) {
if (pkt->buf)
av_buffer_unref(&pkt->buf);
pkt->data = NULL;
pkt->size = 0;
av_packet_free_side_data(pkt);
}
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
uint8_t *data, size_t size)
{
int elems = pkt->side_data_elems;
if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
return AVERROR(ERANGE);
pkt->side_data = av_realloc(pkt->side_data,
(elems + 1) * sizeof(*pkt->side_data));
if (!pkt->side_data)
return AVERROR(ENOMEM);
pkt->side_data[elems].data = data;
pkt->side_data[elems].size = size;
pkt->side_data[elems].type = type;
pkt->side_data_elems++;
return 0;
}
uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int size)
{
int ret;
uint8_t *data;
if ((unsigned)size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
return NULL;
data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!data)
return NULL;
ret = av_packet_add_side_data(pkt, type, data, size);
if (ret < 0) {
av_freep(&data);
return NULL;
}
return data;
}
uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int *size)
{
int i;
for (i = 0; i < pkt->side_data_elems; i++) {
if (pkt->side_data[i].type == type) {
if (size)
*size = pkt->side_data[i].size;
return pkt->side_data[i].data;
}
}
return NULL;
}
const char *av_packet_side_data_name(enum AVPacketSideDataType type)
{
switch(type) {
case AV_PKT_DATA_PALETTE: return "Palette";
case AV_PKT_DATA_NEW_EXTRADATA: return "New Extradata";
case AV_PKT_DATA_PARAM_CHANGE: return "Param Change";
case AV_PKT_DATA_H263_MB_INFO: return "H263 MB Info";
case AV_PKT_DATA_REPLAYGAIN: return "Replay Gain";
case AV_PKT_DATA_DISPLAYMATRIX: return "Display Matrix";
case AV_PKT_DATA_STEREO3D: return "Stereo 3D";
case AV_PKT_DATA_AUDIO_SERVICE_TYPE: return "Audio Service Type";
case AV_PKT_DATA_SKIP_SAMPLES: return "Skip Samples";
case AV_PKT_DATA_JP_DUALMONO: return "JP Dual Mono";
case AV_PKT_DATA_STRINGS_METADATA: return "Strings Metadata";
case AV_PKT_DATA_SUBTITLE_POSITION: return "Subtitle Position";
case AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL: return "Matroska BlockAdditional";
case AV_PKT_DATA_WEBVTT_IDENTIFIER: return "WebVTT ID";
case AV_PKT_DATA_WEBVTT_SETTINGS: return "WebVTT Settings";
case AV_PKT_DATA_METADATA_UPDATE: return "Metadata Update";
case AV_PKT_DATA_MPEGTS_STREAM_ID: return "MPEGTS Stream ID";
case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata";
}
return NULL;
}
#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
int av_packet_merge_side_data(AVPacket *pkt){
if(pkt->side_data_elems){
AVBufferRef *buf;
int i;
uint8_t *p;
uint64_t size= pkt->size + 8LL + AV_INPUT_BUFFER_PADDING_SIZE;
AVPacket old= *pkt;
for (i=0; i<old.side_data_elems; i++) {
size += old.side_data[i].size + 5LL;
}
if (size > INT_MAX)
return AVERROR(EINVAL);
buf = av_buffer_alloc(size);
if (!buf)
return AVERROR(ENOMEM);
pkt->buf = buf;
pkt->data = p = buf->data;
pkt->size = size - AV_INPUT_BUFFER_PADDING_SIZE;
bytestream_put_buffer(&p, old.data, old.size);
for (i=old.side_data_elems-1; i>=0; i--) {
bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
bytestream_put_be32(&p, old.side_data[i].size);
*p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
}
bytestream_put_be64(&p, FF_MERGE_MARKER);
av_assert0(p-pkt->data == pkt->size);
memset(p, 0, AV_INPUT_BUFFER_PADDING_SIZE);
av_packet_unref(&old);
pkt->side_data_elems = 0;
pkt->side_data = NULL;
return 1;
}
return 0;
}
int av_packet_split_side_data(AVPacket *pkt){
if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
int i;
unsigned int size;
uint8_t *p;
p = pkt->data + pkt->size - 8 - 5;
for (i=1; ; i++){
size = AV_RB32(p);
if (size>INT_MAX - 5 || p - pkt->data < size)
return 0;
if (p[4]&128)
break;
if (p - pkt->data < size + 5)
return 0;
p-= size+5;
}
pkt->side_data = av_malloc_array(i, sizeof(*pkt->side_data));
if (!pkt->side_data)
return AVERROR(ENOMEM);
p= pkt->data + pkt->size - 8 - 5;
for (i=0; ; i++){
size= AV_RB32(p);
av_assert0(size<=INT_MAX - 5 && p - pkt->data >= size);
pkt->side_data[i].data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
pkt->side_data[i].size = size;
pkt->side_data[i].type = p[4]&127;
if (!pkt->side_data[i].data)
return AVERROR(ENOMEM);
memcpy(pkt->side_data[i].data, p-size, size);
pkt->size -= size + 5;
if(p[4]&128)
break;
p-= size+5;
}
pkt->size -= 8;
pkt->side_data_elems = i+1;
return 1;
}
return 0;
}
uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)
{
AVDictionaryEntry *t = NULL;
uint8_t *data = NULL;
*size = 0;
if (!dict)
return NULL;
while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
const size_t keylen = strlen(t->key);
const size_t valuelen = strlen(t->value);
const size_t new_size = *size + keylen + 1 + valuelen + 1;
uint8_t *const new_data = av_realloc(data, new_size);
if (!new_data)
goto fail;
data = new_data;
if (new_size > INT_MAX)
goto fail;
memcpy(data + *size, t->key, keylen + 1);
memcpy(data + *size + keylen + 1, t->value, valuelen + 1);
*size = new_size;
}
return data;
fail:
av_freep(&data);
*size = 0;
return NULL;
}
int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict)
{
const uint8_t *end = data + size;
int ret = 0;
if (!dict || !data || !size)
return ret;
if (size && end[-1])
return AVERROR_INVALIDDATA;
while (data < end) {
const uint8_t *key = data;
const uint8_t *val = data + strlen(key) + 1;
if (val >= end)
return AVERROR_INVALIDDATA;
ret = av_dict_set(dict, key, val, 0);
if (ret < 0)
break;
data = val + strlen(val) + 1;
}
return ret;
}
int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int size)
{
int i;
for (i = 0; i < pkt->side_data_elems; i++) {
if (pkt->side_data[i].type == type) {
if (size > pkt->side_data[i].size)
return AVERROR(ENOMEM);
pkt->side_data[i].size = size;
return 0;
}
}
return AVERROR(ENOENT);
}
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
{
int i;
dst->pts = src->pts;
dst->dts = src->dts;
dst->pos = src->pos;
dst->duration = src->duration;
#if FF_API_CONVERGENCE_DURATION
FF_DISABLE_DEPRECATION_WARNINGS
dst->convergence_duration = src->convergence_duration;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
dst->flags = src->flags;
dst->stream_index = src->stream_index;
for (i = 0; i < src->side_data_elems; i++) {
enum AVPacketSideDataType type = src->side_data[i].type;
int size = src->side_data[i].size;
uint8_t *src_data = src->side_data[i].data;
uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
if (!dst_data) {
av_packet_free_side_data(dst);
return AVERROR(ENOMEM);
}
memcpy(dst_data, src_data, size);
}
return 0;
}
void av_packet_unref(AVPacket *pkt)
{
av_packet_free_side_data(pkt);
av_buffer_unref(&pkt->buf);
av_init_packet(pkt);
pkt->data = NULL;
pkt->size = 0;
}
int av_packet_ref(AVPacket *dst, const AVPacket *src)
{
int ret;
ret = av_packet_copy_props(dst, src);
if (ret < 0)
return ret;
if (!src->buf) {
ret = packet_alloc(&dst->buf, src->size);
if (ret < 0)
goto fail;
memcpy(dst->buf->data, src->data, src->size);
dst->data = dst->buf->data;
} else {
dst->buf = av_buffer_ref(src->buf);
if (!dst->buf) {
ret = AVERROR(ENOMEM);
goto fail;
}
dst->data = src->data;
}
dst->size = src->size;
return 0;
fail:
av_packet_free_side_data(dst);
return ret;
}
AVPacket *av_packet_clone(AVPacket *src)
{
AVPacket *ret = av_packet_alloc();
if (!ret)
return ret;
if (av_packet_ref(ret, src))
av_packet_free(&ret);
return ret;
}
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
{
*dst = *src;
av_init_packet(src);
src->data = NULL;
src->size = 0;
}
void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
{
if (pkt->pts != AV_NOPTS_VALUE)
pkt->pts = av_rescale_q(pkt->pts, src_tb, dst_tb);
if (pkt->dts != AV_NOPTS_VALUE)
pkt->dts = av_rescale_q(pkt->dts, src_tb, dst_tb);
if (pkt->duration > 0)
pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb);
#if FF_API_CONVERGENCE_DURATION
FF_DISABLE_DEPRECATION_WARNINGS
if (pkt->convergence_duration > 0)
pkt->convergence_duration = av_rescale_q(pkt->convergence_duration, src_tb, dst_tb);
FF_ENABLE_DEPRECATION_WARNINGS
#endif
}
int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type)
{
uint8_t *side_data;
int side_data_size;
int i;
side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size);
if (!side_data) {
side_data_size = 4+4+8*error_count;
side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
side_data_size);
}
if (!side_data || side_data_size < 4+4+8*error_count)
return AVERROR(ENOMEM);
AV_WL32(side_data , quality );
side_data[4] = pict_type;
side_data[5] = error_count;
for (i = 0; i<error_count; i++)
AV_WL64(side_data+8 + 8*i , error[i]);
return 0;
}

View file

@ -0,0 +1,82 @@
/*
* AVPicture management routines
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* AVPicture management routines
*/
#include "avcodec.h"
#include "internal.h"
#include "libavutil/common.h"
#include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "libavutil/colorspace.h"
#if FF_API_AVPICTURE
FF_DISABLE_DEPRECATION_WARNINGS
int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
enum AVPixelFormat pix_fmt, int width, int height)
{
return av_image_fill_arrays(picture->data, picture->linesize,
ptr, pix_fmt, width, height, 1);
}
int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt, int width, int height,
unsigned char *dest, int dest_size)
{
return av_image_copy_to_buffer(dest, dest_size,
(const uint8_t * const*)src->data, src->linesize,
pix_fmt, width, height, 1);
}
int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
{
return av_image_get_buffer_size(pix_fmt, width, height, 1);
}
int avpicture_alloc(AVPicture *picture,
enum AVPixelFormat pix_fmt, int width, int height)
{
int ret = av_image_alloc(picture->data, picture->linesize,
width, height, pix_fmt, 1);
if (ret < 0) {
memset(picture, 0, sizeof(AVPicture));
return ret;
}
return 0;
}
void avpicture_free(AVPicture *picture)
{
av_freep(&picture->data[0]);
}
void av_picture_copy(AVPicture *dst, const AVPicture *src,
enum AVPixelFormat pix_fmt, int width, int height)
{
av_image_copy(dst->data, dst->linesize, (const uint8_t **)src->data,
src->linesize, pix_fmt, width, height);
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif /* FF_API_AVPICTURE */

View file

@ -0,0 +1,93 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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 "mathops.h"
#include "rnd_avg.h"
#include "libavutil/intreadwrite.h"
#ifndef BIT_DEPTH
#define BIT_DEPTH 8
#endif
#ifdef AVCODEC_BIT_DEPTH_TEMPLATE_C
# undef pixel
# undef pixel2
# undef pixel4
# undef dctcoef
# undef INIT_CLIP
# undef no_rnd_avg_pixel4
# undef rnd_avg_pixel4
# undef AV_RN2P
# undef AV_RN4P
# undef AV_RN4PA
# undef AV_WN2P
# undef AV_WN4P
# undef AV_WN4PA
# undef CLIP
# undef FUNC
# undef FUNCC
# undef av_clip_pixel
# undef PIXEL_SPLAT_X4
#else
# define AVCODEC_BIT_DEPTH_TEMPLATE_C
#endif
#if BIT_DEPTH > 8
# define pixel uint16_t
# define pixel2 uint32_t
# define pixel4 uint64_t
# define dctcoef int32_t
# define INIT_CLIP
# define no_rnd_avg_pixel4 no_rnd_avg64
# define rnd_avg_pixel4 rnd_avg64
# define AV_RN2P AV_RN32
# define AV_RN4P AV_RN64
# define AV_RN4PA AV_RN64A
# define AV_WN2P AV_WN32
# define AV_WN4P AV_WN64
# define AV_WN4PA AV_WN64A
# define PIXEL_SPLAT_X4(x) ((x)*0x0001000100010001ULL)
# define av_clip_pixel(a) av_clip_uintp2(a, BIT_DEPTH)
# define CLIP(a) av_clip_uintp2(a, BIT_DEPTH)
#else
# define pixel uint8_t
# define pixel2 uint16_t
# define pixel4 uint32_t
# define dctcoef int16_t
# define INIT_CLIP
# define no_rnd_avg_pixel4 no_rnd_avg32
# define rnd_avg_pixel4 rnd_avg32
# define AV_RN2P AV_RN16
# define AV_RN4P AV_RN32
# define AV_RN4PA AV_RN32A
# define AV_WN2P AV_WN16
# define AV_WN4P AV_WN32
# define AV_WN4PA AV_WN32A
# define PIXEL_SPLAT_X4(x) ((x)*0x01010101U)
# define av_clip_pixel(a) av_clip_uint8(a)
# define CLIP(a) av_clip_uint8(a)
#endif
#define FUNC3(a, b, c) a ## _ ## b ## c
#define FUNC2(a, b, c) FUNC3(a, b, c)
#define FUNC(a) FUNC2(a, BIT_DEPTH,)
#define FUNCC(a) FUNC2(a, BIT_DEPTH, _c)

View file

@ -0,0 +1,363 @@
/*
* Common bit i/o utils
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2010 Loren Merritt
*
* alternative bitstream reader & writer by 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
* bitstream api.
*/
#include "libavutil/atomic.h"
#include "libavutil/avassert.h"
#include "libavutil/qsort.h"
#include "avcodec.h"
#include "internal.h"
#include "mathops.h"
#include "put_bits.h"
#include "vlc.h"
const uint8_t ff_log2_run[41]={
0, 0, 0, 0, 1, 1, 1, 1,
2, 2, 2, 2, 3, 3, 3, 3,
4, 4, 5, 5, 6, 6, 7, 7,
8, 9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,
24,
};
void avpriv_align_put_bits(PutBitContext *s)
{
put_bits(s, s->bit_left & 7, 0);
}
void avpriv_put_string(PutBitContext *pb, const char *string,
int terminate_string)
{
while (*string) {
put_bits(pb, 8, *string);
string++;
}
if (terminate_string)
put_bits(pb, 8, 0);
}
void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
{
int words = length >> 4;
int bits = length & 15;
int i;
if (length == 0)
return;
av_assert0(length <= put_bits_left(pb));
if (CONFIG_SMALL || words < 16 || put_bits_count(pb) & 7) {
for (i = 0; i < words; i++)
put_bits(pb, 16, AV_RB16(src + 2 * i));
} else {
for (i = 0; put_bits_count(pb) & 31; i++)
put_bits(pb, 8, src[i]);
flush_put_bits(pb);
memcpy(put_bits_ptr(pb), src + i, 2 * words - i);
skip_put_bytes(pb, 2 * words - i);
}
put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits));
}
/* VLC decoding */
#define GET_DATA(v, table, i, wrap, size) \
{ \
const uint8_t *ptr = (const uint8_t *)table + i * wrap; \
switch(size) { \
case 1: \
v = *(const uint8_t *)ptr; \
break; \
case 2: \
v = *(const uint16_t *)ptr; \
break; \
default: \
v = *(const uint32_t *)ptr; \
break; \
} \
}
static int alloc_table(VLC *vlc, int size, int use_static)
{
int index = vlc->table_size;
vlc->table_size += size;
if (vlc->table_size > vlc->table_allocated) {
if (use_static)
abort(); // cannot do anything, init_vlc() is used with too little memory
vlc->table_allocated += (1 << vlc->bits);
vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2);
if (!vlc->table) {
vlc->table_allocated = 0;
vlc->table_size = 0;
return AVERROR(ENOMEM);
}
memset(vlc->table + vlc->table_allocated - (1 << vlc->bits), 0, sizeof(VLC_TYPE) * 2 << vlc->bits);
}
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;
/** codeword, with the first bit-to-be-read in the msb
* (even if intended for a little-endian bitstream reader) */
uint32_t code;
} VLCcode;
static int compare_vlcspec(const void *a, const void *b)
{
const VLCcode *sa = a, *sb = b;
return (sa->code >> 1) - (sb->code >> 1);
}
/**
* Build VLC decoding tables suitable for use with get_vlc().
*
* @param vlc the context to be initialized
*
* @param table_nb_bits max length of vlc codes to store directly in this table
* (Longer codes are delegated to subtables.)
*
* @param nb_codes number of elements in codes[]
*
* @param codes descriptions of the vlc codes
* These must be ordered such that codes going into the same subtable are contiguous.
* Sorting by VLCcode.code is sufficient, though not necessary.
*/
static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
VLCcode *codes, int flags)
{
int table_size, table_index, index, code_prefix, symbol, subtable_bits;
int i, j, k, n, nb, inc;
uint32_t code;
volatile VLC_TYPE (* volatile table)[2]; // the double volatile is needed to prevent an internal compiler error in gcc 4.2
table_size = 1 << table_nb_bits;
if (table_nb_bits > 30)
return -1;
table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
ff_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
if (table_index < 0)
return table_index;
table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
/* first pass: map codes and compute auxiliary table sizes */
for (i = 0; i < nb_codes; i++) {
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);
if (n <= table_nb_bits) {
/* no need to add another table */
j = code >> (32 - table_nb_bits);
nb = 1 << (table_nb_bits - n);
inc = 1;
if (flags & INIT_VLC_LE) {
j = bitswap_32(code);
inc = 1 << n;
}
for (k = 0; k < nb; k++) {
int bits = table[j][1];
ff_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
if (bits != 0 && bits != n) {
av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
return AVERROR_INVALIDDATA;
}
table[j][1] = n; //bits
table[j][0] = symbol;
j += inc;
}
} else {
/* fill auxiliary table recursively */
n -= table_nb_bits;
code_prefix = code >> (32 - table_nb_bits);
subtable_bits = n;
codes[i].bits = n;
codes[i].code = code << table_nb_bits;
for (k = i+1; k < nb_codes; k++) {
n = codes[k].bits - table_nb_bits;
if (n <= 0)
break;
code = codes[k].code;
if (code >> (32 - table_nb_bits) != code_prefix)
break;
codes[k].bits = n;
codes[k].code = code << table_nb_bits;
subtable_bits = FFMAX(subtable_bits, n);
}
subtable_bits = FFMIN(subtable_bits, table_nb_bits);
j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix;
table[j][1] = -subtable_bits;
ff_dlog(NULL, "%4x: n=%d (subtable)\n",
j, codes[i].bits + table_nb_bits);
index = build_table(vlc, subtable_bits, k-i, codes+i, flags);
if (index < 0)
return index;
/* note: realloc has been done, so reload tables */
table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
table[j][0] = index; //code
i = k-1;
}
}
for (i = 0; i < table_size; i++) {
if (table[i][1] == 0) //bits
table[i][0] = -1; //codes
}
return table_index;
}
/* Build VLC decoding tables suitable for use with get_vlc().
'nb_bits' sets the decoding table size (2^nb_bits) entries. The
bigger it is, the faster is the decoding. But it should not be too
big to save memory and L1 cache. '9' is a good compromise.
'nb_codes' : number of vlcs codes
'bits' : table which gives the size (in bits) of each vlc code.
'codes' : table which gives the bit pattern of of each vlc code.
'symbols' : table which gives the values to be returned from get_vlc().
'xxx_wrap' : give the number of bytes between each entry of the
'bits' or 'codes' tables.
'xxx_size' : gives the number of bytes of each entry of the 'bits'
or 'codes' tables.
'wrap' and 'size' make it possible to use any memory configuration and types
(byte/word/long) to store the 'bits', 'codes', and 'symbols' tables.
'use_static' should be set to 1 for tables, which should be freed
with av_free_static(), 0 if ff_free_vlc() will be used.
*/
int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
const void *symbols, int symbols_wrap, int symbols_size,
int flags)
{
VLCcode *buf;
int i, j, ret;
VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34
VLC localvlc, *vlc;
vlc = vlc_arg;
vlc->bits = nb_bits;
if (flags & INIT_VLC_USE_NEW_STATIC) {
av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
buf = localbuf;
localvlc = *vlc_arg;
vlc = &localvlc;
vlc->table_size = 0;
} else {
vlc->table = NULL;
vlc->table_allocated = 0;
vlc->table_size = 0;
buf = av_malloc_array((nb_codes + 1), sizeof(VLCcode));
if (!buf)
return AVERROR(ENOMEM);
}
av_assert0(symbols_size <= 2 || !symbols);
j = 0;
#define COPY(condition)\
for (i = 0; i < nb_codes; i++) { \
GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size); \
if (!(condition)) \
continue; \
if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \
av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
av_free(buf); \
return -1; \
} \
GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \
if (buf[j].code >= (1LL<<buf[j].bits)) { \
av_log(NULL, AV_LOG_ERROR, "Invalid code %x for %d in init_vlc\n", buf[j].code, i);\
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
av_free(buf); \
return -1; \
} \
if (flags & INIT_VLC_LE) \
buf[j].code = bitswap_32(buf[j].code); \
else \
buf[j].code <<= 32 - buf[j].bits; \
if (symbols) \
GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \
else \
buf[j].symbol = i; \
j++; \
}
COPY(buf[j].bits > nb_bits);
// qsort is the slowest part of init_vlc, and could probably be improved or avoided
AV_QSORT(buf, j, struct VLCcode, compare_vlcspec);
COPY(buf[j].bits && buf[j].bits <= nb_bits);
nb_codes = j;
ret = build_table(vlc, nb_bits, nb_codes, buf, flags);
if (flags & INIT_VLC_USE_NEW_STATIC) {
if(vlc->table_size != vlc->table_allocated)
av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
av_assert0(ret >= 0);
*vlc_arg = *vlc;
} else {
av_free(buf);
if (ret < 0) {
av_freep(&vlc->table);
return ret;
}
}
return 0;
}
void ff_free_vlc(VLC *vlc)
{
av_freep(&vlc->table);
}

View file

@ -0,0 +1,49 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_BLOCKDSP_H
#define AVCODEC_BLOCKDSP_H
#include <stdint.h>
#include "avcodec.h"
#include "version.h"
/* add and put pixel (decoding)
* Block sizes for op_pixels_func are 8x4,8x8 16x8 16x16.
* 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);
typedef struct BlockDSPContext {
void (*clear_block)(int16_t *block /* align 16 */);
void (*clear_blocks)(int16_t *blocks /* align 16 */);
op_fill_func fill_block_tab[2];
} BlockDSPContext;
void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx);
void ff_blockdsp_init_alpha(BlockDSPContext *c);
void ff_blockdsp_init_arm(BlockDSPContext *c);
void ff_blockdsp_init_ppc(BlockDSPContext *c);
void ff_blockdsp_init_x86(BlockDSPContext *c, AVCodecContext *avctx);
void ff_blockdsp_init_mips(BlockDSPContext *c);
#endif /* AVCODEC_BLOCKDSP_H */

View file

@ -0,0 +1,33 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_BSF_H
#define AVCODEC_BSF_H
#include "avcodec.h"
/**
* Called by the bitstream filters to get the next packet for filtering.
* The filter is responsible for either freeing the packet or passing it to the
* caller.
*/
int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt);
const AVClass *ff_bsf_child_class_next(const AVClass *prev);
#endif /* AVCODEC_BSF_H */

View file

@ -0,0 +1,376 @@
/*
* Bytestream functions
* copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
* Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_BYTESTREAM_H
#define AVCODEC_BYTESTREAM_H
#include <stdint.h>
#include <string.h>
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
typedef struct GetByteContext {
const uint8_t *buffer, *buffer_end, *buffer_start;
} GetByteContext;
typedef struct PutByteContext {
uint8_t *buffer, *buffer_end, *buffer_start;
int eof;
} PutByteContext;
#define DEF(type, name, bytes, read, write) \
static av_always_inline type bytestream_get_ ## name(const uint8_t **b) \
{ \
(*b) += bytes; \
return read(*b - bytes); \
} \
static av_always_inline void bytestream_put_ ## name(uint8_t **b, \
const type value) \
{ \
write(*b, value); \
(*b) += bytes; \
} \
static av_always_inline void bytestream2_put_ ## name ## u(PutByteContext *p, \
const type value) \
{ \
bytestream_put_ ## name(&p->buffer, value); \
} \
static av_always_inline void bytestream2_put_ ## name(PutByteContext *p, \
const type value) \
{ \
if (!p->eof && (p->buffer_end - p->buffer >= bytes)) { \
write(p->buffer, value); \
p->buffer += bytes; \
} else \
p->eof = 1; \
} \
static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g) \
{ \
return bytestream_get_ ## name(&g->buffer); \
} \
static av_always_inline type bytestream2_get_ ## name(GetByteContext *g) \
{ \
if (g->buffer_end - g->buffer < bytes) { \
g->buffer = g->buffer_end; \
return 0; \
} \
return bytestream2_get_ ## name ## u(g); \
} \
static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g) \
{ \
if (g->buffer_end - g->buffer < bytes) \
return 0; \
return read(g->buffer); \
}
DEF(uint64_t, le64, 8, AV_RL64, AV_WL64)
DEF(unsigned int, le32, 4, AV_RL32, AV_WL32)
DEF(unsigned int, le24, 3, AV_RL24, AV_WL24)
DEF(unsigned int, le16, 2, AV_RL16, AV_WL16)
DEF(uint64_t, be64, 8, AV_RB64, AV_WB64)
DEF(unsigned int, be32, 4, AV_RB32, AV_WB32)
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
# define bytestream2_get_ne16 bytestream2_get_be16
# define bytestream2_get_ne24 bytestream2_get_be24
# define bytestream2_get_ne32 bytestream2_get_be32
# define bytestream2_get_ne64 bytestream2_get_be64
# define bytestream2_get_ne16u bytestream2_get_be16u
# define bytestream2_get_ne24u bytestream2_get_be24u
# define bytestream2_get_ne32u bytestream2_get_be32u
# define bytestream2_get_ne64u bytestream2_get_be64u
# define bytestream2_put_ne16 bytestream2_put_be16
# define bytestream2_put_ne24 bytestream2_put_be24
# define bytestream2_put_ne32 bytestream2_put_be32
# define bytestream2_put_ne64 bytestream2_put_be64
# define bytestream2_peek_ne16 bytestream2_peek_be16
# define bytestream2_peek_ne24 bytestream2_peek_be24
# define bytestream2_peek_ne32 bytestream2_peek_be32
# define bytestream2_peek_ne64 bytestream2_peek_be64
#else
# define bytestream2_get_ne16 bytestream2_get_le16
# define bytestream2_get_ne24 bytestream2_get_le24
# define bytestream2_get_ne32 bytestream2_get_le32
# define bytestream2_get_ne64 bytestream2_get_le64
# define bytestream2_get_ne16u bytestream2_get_le16u
# define bytestream2_get_ne24u bytestream2_get_le24u
# define bytestream2_get_ne32u bytestream2_get_le32u
# define bytestream2_get_ne64u bytestream2_get_le64u
# define bytestream2_put_ne16 bytestream2_put_le16
# define bytestream2_put_ne24 bytestream2_put_le24
# define bytestream2_put_ne32 bytestream2_put_le32
# define bytestream2_put_ne64 bytestream2_put_le64
# define bytestream2_peek_ne16 bytestream2_peek_le16
# define bytestream2_peek_ne24 bytestream2_peek_le24
# define bytestream2_peek_ne32 bytestream2_peek_le32
# define bytestream2_peek_ne64 bytestream2_peek_le64
#endif
static av_always_inline void bytestream2_init(GetByteContext *g,
const uint8_t *buf,
int buf_size)
{
av_assert0(buf_size >= 0);
g->buffer = buf;
g->buffer_start = buf;
g->buffer_end = buf + buf_size;
}
static av_always_inline void bytestream2_init_writer(PutByteContext *p,
uint8_t *buf,
int buf_size)
{
av_assert0(buf_size >= 0);
p->buffer = buf;
p->buffer_start = buf;
p->buffer_end = buf + buf_size;
p->eof = 0;
}
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
{
return g->buffer_end - g->buffer;
}
static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p)
{
return p->buffer_end - p->buffer;
}
static av_always_inline void bytestream2_skip(GetByteContext *g,
unsigned int size)
{
g->buffer += FFMIN(g->buffer_end - g->buffer, size);
}
static av_always_inline void bytestream2_skipu(GetByteContext *g,
unsigned int size)
{
g->buffer += size;
}
static av_always_inline void bytestream2_skip_p(PutByteContext *p,
unsigned int size)
{
int size2;
if (p->eof)
return;
size2 = FFMIN(p->buffer_end - p->buffer, size);
if (size2 != size)
p->eof = 1;
p->buffer += size2;
}
static av_always_inline int bytestream2_tell(GetByteContext *g)
{
return (int)(g->buffer - g->buffer_start);
}
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
{
return (int)(p->buffer - p->buffer_start);
}
static av_always_inline int bytestream2_size(GetByteContext *g)
{
return (int)(g->buffer_end - g->buffer_start);
}
static av_always_inline int bytestream2_size_p(PutByteContext *p)
{
return (int)(p->buffer_end - p->buffer_start);
}
static av_always_inline int bytestream2_seek(GetByteContext *g,
int offset,
int whence)
{
switch (whence) {
case SEEK_CUR:
offset = av_clip(offset, -(g->buffer - g->buffer_start),
g->buffer_end - g->buffer);
g->buffer += offset;
break;
case SEEK_END:
offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0);
g->buffer = g->buffer_end + offset;
break;
case SEEK_SET:
offset = av_clip(offset, 0, g->buffer_end - g->buffer_start);
g->buffer = g->buffer_start + offset;
break;
default:
return AVERROR(EINVAL);
}
return bytestream2_tell(g);
}
static av_always_inline int bytestream2_seek_p(PutByteContext *p,
int offset,
int whence)
{
p->eof = 0;
switch (whence) {
case SEEK_CUR:
if (p->buffer_end - p->buffer < offset)
p->eof = 1;
offset = av_clip(offset, -(p->buffer - p->buffer_start),
p->buffer_end - p->buffer);
p->buffer += offset;
break;
case SEEK_END:
if (offset > 0)
p->eof = 1;
offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0);
p->buffer = p->buffer_end + offset;
break;
case SEEK_SET:
if (p->buffer_end - p->buffer_start < offset)
p->eof = 1;
offset = av_clip(offset, 0, p->buffer_end - p->buffer_start);
p->buffer = p->buffer_start + offset;
break;
default:
return AVERROR(EINVAL);
}
return bytestream2_tell_p(p);
}
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
uint8_t *dst,
unsigned int size)
{
int size2 = FFMIN(g->buffer_end - g->buffer, size);
memcpy(dst, g->buffer, size2);
g->buffer += size2;
return size2;
}
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g,
uint8_t *dst,
unsigned int size)
{
memcpy(dst, g->buffer, size);
g->buffer += size;
return size;
}
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
const uint8_t *src,
unsigned int size)
{
int size2;
if (p->eof)
return 0;
size2 = FFMIN(p->buffer_end - p->buffer, size);
if (size2 != size)
p->eof = 1;
memcpy(p->buffer, src, size2);
p->buffer += size2;
return size2;
}
static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p,
const uint8_t *src,
unsigned int size)
{
memcpy(p->buffer, src, size);
p->buffer += size;
return size;
}
static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
const uint8_t c,
unsigned int size)
{
int size2;
if (p->eof)
return;
size2 = FFMIN(p->buffer_end - p->buffer, size);
if (size2 != size)
p->eof = 1;
memset(p->buffer, c, size2);
p->buffer += size2;
}
static av_always_inline void bytestream2_set_bufferu(PutByteContext *p,
const uint8_t c,
unsigned int size)
{
memset(p->buffer, c, size);
p->buffer += size;
}
static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
{
return p->eof;
}
static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p,
GetByteContext *g,
unsigned int size)
{
memcpy(p->buffer, g->buffer, size);
p->buffer += size;
g->buffer += size;
return size;
}
static av_always_inline unsigned int bytestream2_copy_buffer(PutByteContext *p,
GetByteContext *g,
unsigned int size)
{
int size2;
if (p->eof)
return 0;
size = FFMIN(g->buffer_end - g->buffer, size);
size2 = FFMIN(p->buffer_end - p->buffer, size);
if (size2 != size)
p->eof = 1;
return bytestream2_copy_bufferu(p, g, size2);
}
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b,
uint8_t *dst,
unsigned int size)
{
memcpy(dst, *b, size);
(*b) += size;
return size;
}
static av_always_inline void bytestream_put_buffer(uint8_t **b,
const uint8_t *src,
unsigned int size)
{
memcpy(*b, src, size);
(*b) += size;
}
#endif /* AVCODEC_BYTESTREAM_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,68 @@
/*
* (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 */

View file

@ -0,0 +1,801 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "avcodec.h"
typedef struct H264PredContext H264PredContext;
typedef struct VideoDSPContext VideoDSPContext;
typedef struct VP8DSPContext VP8DSPContext;
typedef struct VP9DSPContext VP9DSPContext;
typedef struct FLACDSPContext FLACDSPContext;
AVHWAccel ff_h263_vaapi_hwaccel;
AVHWAccel ff_h263_vdpau_hwaccel;
AVHWAccel ff_h263_videotoolbox_hwaccel;
AVHWAccel ff_h264_d3d11va_hwaccel;
AVHWAccel ff_h264_dxva2_hwaccel;
AVHWAccel ff_h264_mmal_hwaccel;
AVHWAccel ff_h264_qsv_hwaccel;
AVHWAccel ff_h264_vaapi_hwaccel;
AVHWAccel ff_h264_vda_hwaccel;
AVHWAccel ff_h264_vda_old_hwaccel;
AVHWAccel ff_h264_vdpau_hwaccel;
AVHWAccel ff_h264_videotoolbox_hwaccel;
AVHWAccel ff_hevc_d3d11va_hwaccel;
AVHWAccel ff_hevc_dxva2_hwaccel;
AVHWAccel ff_hevc_qsv_hwaccel;
AVHWAccel ff_hevc_vaapi_hwaccel;
AVHWAccel ff_hevc_vdpau_hwaccel;
AVHWAccel ff_mpeg1_xvmc_hwaccel;
AVHWAccel ff_mpeg1_vdpau_hwaccel;
AVHWAccel ff_mpeg1_videotoolbox_hwaccel;
AVHWAccel ff_mpeg2_xvmc_hwaccel;
AVHWAccel ff_mpeg2_d3d11va_hwaccel;
AVHWAccel ff_mpeg2_dxva2_hwaccel;
AVHWAccel ff_mpeg2_qsv_hwaccel;
AVHWAccel ff_mpeg2_vaapi_hwaccel;
AVHWAccel ff_mpeg2_vdpau_hwaccel;
AVHWAccel ff_mpeg2_videotoolbox_hwaccel;
AVHWAccel ff_mpeg4_mmal_hwaccel;
AVHWAccel ff_mpeg4_vaapi_hwaccel;
AVHWAccel ff_mpeg4_vdpau_hwaccel;
AVHWAccel ff_mpeg4_videotoolbox_hwaccel;
AVHWAccel ff_vc1_d3d11va_hwaccel;
AVHWAccel ff_vc1_dxva2_hwaccel;
AVHWAccel ff_vc1_vaapi_hwaccel;
AVHWAccel ff_vc1_vdpau_hwaccel;
AVHWAccel ff_vc1_qsv_hwaccel;
AVHWAccel ff_wmv3_d3d11va_hwaccel;
AVHWAccel ff_wmv3_dxva2_hwaccel;
AVHWAccel ff_wmv3_vaapi_hwaccel;
AVHWAccel ff_wmv3_vdpau_hwaccel;
AVHWAccel ff_mpeg2_mmal_hwaccel;
AVHWAccel ff_vc1_mmal_hwaccel;
AVHWAccel ff_vp9_d3d11va_hwaccel;
AVHWAccel ff_vp9_dxva2_hwaccel;
AVHWAccel ff_vp9_vaapi_hwaccel;
AVHWAccel ff_vp9_cuvid_hwaccel;
AVHWAccel ff_vp8_cuvid_hwaccel;
AVHWAccel ff_vc1_cuvid_hwaccel;
AVHWAccel ff_hevc_cuvid_hwaccel;
AVHWAccel ff_h264_cuvid_hwaccel;
AVCodec ff_a64multi_encoder;
AVCodec ff_a64multi5_encoder;
AVCodec ff_aasc_decoder;
AVCodec ff_aic_decoder;
AVCodec ff_alias_pix_encoder;
AVCodec ff_alias_pix_decoder;
AVCodec ff_amv_encoder;
AVCodec ff_amv_decoder;
AVCodec ff_anm_decoder;
AVCodec ff_ansi_decoder;
AVCodec ff_apng_encoder;
AVCodec ff_apng_decoder;
AVCodec ff_asv1_encoder;
AVCodec ff_asv1_decoder;
AVCodec ff_asv2_encoder;
AVCodec ff_asv2_decoder;
AVCodec ff_aura_decoder;
AVCodec ff_aura2_decoder;
AVCodec ff_avrp_encoder;
AVCodec ff_avrp_decoder;
AVCodec ff_avrn_decoder;
AVCodec ff_avs_decoder;
AVCodec ff_avui_encoder;
AVCodec ff_avui_decoder;
AVCodec ff_ayuv_encoder;
AVCodec ff_ayuv_decoder;
AVCodec ff_bethsoftvid_decoder;
AVCodec ff_bfi_decoder;
AVCodec ff_bink_decoder;
AVCodec ff_bmp_encoder;
AVCodec ff_bmp_decoder;
AVCodec ff_bmv_video_decoder;
AVCodec ff_brender_pix_decoder;
AVCodec ff_c93_decoder;
AVCodec ff_cavs_decoder;
AVCodec ff_cdgraphics_decoder;
AVCodec ff_cdxl_decoder;
AVCodec ff_cfhd_decoder;
AVCodec ff_cinepak_encoder;
AVCodec ff_cinepak_decoder;
AVCodec ff_cljr_encoder;
AVCodec ff_cljr_decoder;
AVCodec ff_cllc_decoder;
AVCodec ff_comfortnoise_encoder;
AVCodec ff_comfortnoise_decoder;
AVCodec ff_cpia_decoder;
AVCodec ff_cscd_decoder;
AVCodec ff_cyuv_decoder;
AVCodec ff_dds_decoder;
AVCodec ff_dfa_decoder;
AVCodec ff_dirac_decoder;
AVCodec ff_dnxhd_encoder;
AVCodec ff_dnxhd_decoder;
AVCodec ff_dpx_encoder;
AVCodec ff_dpx_decoder;
AVCodec ff_dsicinvideo_decoder;
AVCodec ff_dvaudio_decoder;
AVCodec ff_dvvideo_encoder;
AVCodec ff_dvvideo_decoder;
AVCodec ff_dxa_decoder;
AVCodec ff_dxtory_decoder;
AVCodec ff_eacmv_decoder;
AVCodec ff_eamad_decoder;
AVCodec ff_eatgq_decoder;
AVCodec ff_eatgv_decoder;
AVCodec ff_eatqi_decoder;
AVCodec ff_eightbps_decoder;
AVCodec ff_eightsvx_exp_decoder;
AVCodec ff_eightsvx_fib_decoder;
AVCodec ff_escape124_decoder;
AVCodec ff_escape130_decoder;
AVCodec ff_exr_decoder;
AVCodec ff_ffv1_encoder;
AVCodec ff_ffv1_decoder;
AVCodec ff_ffvhuff_encoder;
AVCodec ff_ffvhuff_decoder;
AVCodec ff_fic_decoder;
AVCodec ff_flashsv_encoder;
AVCodec ff_flashsv_decoder;
AVCodec ff_flashsv2_encoder;
AVCodec ff_flashsv2_decoder;
AVCodec ff_flic_decoder;
AVCodec ff_flv_encoder;
AVCodec ff_flv_decoder;
AVCodec ff_fourxm_decoder;
AVCodec ff_fraps_decoder;
AVCodec ff_frwu_decoder;
AVCodec ff_g2m_decoder;
AVCodec ff_gif_encoder;
AVCodec ff_gif_decoder;
AVCodec ff_h261_encoder;
AVCodec ff_h261_decoder;
AVCodec ff_h263_encoder;
AVCodec ff_h263_decoder;
AVCodec ff_h263i_decoder;
AVCodec ff_h263p_encoder;
AVCodec ff_h263p_decoder;
AVCodec ff_h264_decoder;
AVCodec ff_h264_crystalhd_decoder;
AVCodec ff_h264_mmal_decoder;
AVCodec ff_h264_qsv_decoder;
AVCodec ff_h264_vda_decoder;
AVCodec ff_h264_vdpau_decoder;
AVCodec ff_hap_encoder;
AVCodec ff_hap_decoder;
AVCodec ff_hevc_decoder;
AVCodec ff_hevc_qsv_decoder;
AVCodec ff_hnm4_video_decoder;
AVCodec ff_hq_hqa_decoder;
AVCodec ff_hqx_decoder;
AVCodec ff_huffyuv_encoder;
AVCodec ff_huffyuv_decoder;
AVCodec ff_idcin_decoder;
AVCodec ff_iff_byterun1_decoder;
AVCodec ff_iff_ilbm_decoder;
AVCodec ff_indeo2_decoder;
AVCodec ff_indeo3_decoder;
AVCodec ff_indeo4_decoder;
AVCodec ff_indeo5_decoder;
AVCodec ff_interplay_video_decoder;
AVCodec ff_jpeg2000_encoder;
AVCodec ff_jpeg2000_decoder;
AVCodec ff_jpegls_encoder;
AVCodec ff_jpegls_decoder;
AVCodec ff_jv_decoder;
AVCodec ff_kgv1_decoder;
AVCodec ff_kmvc_decoder;
AVCodec ff_lagarith_decoder;
AVCodec ff_ljpeg_encoder;
AVCodec ff_loco_decoder;
AVCodec ff_mdec_decoder;
AVCodec ff_mimic_decoder;
AVCodec ff_mjpeg_encoder;
AVCodec ff_mjpeg_decoder;
AVCodec ff_mjpegb_decoder;
AVCodec ff_mmvideo_decoder;
AVCodec ff_motionpixels_decoder;
AVCodec ff_mpeg_xvmc_decoder;
AVCodec ff_mpeg1video_encoder;
AVCodec ff_mpeg1video_decoder;
AVCodec ff_mpeg2video_encoder;
AVCodec ff_mpeg2video_decoder;
AVCodec ff_mpeg4_encoder;
AVCodec ff_mpeg4_decoder;
AVCodec ff_mpeg4_crystalhd_decoder;
AVCodec ff_mpeg4_mmal_decoder;
AVCodec ff_mpeg4_vdpau_decoder;
AVCodec ff_mpegvideo_decoder;
AVCodec ff_mpeg_vdpau_decoder;
AVCodec ff_mpeg1_vdpau_decoder;
AVCodec ff_mpeg2_crystalhd_decoder;
AVCodec ff_mpeg2_qsv_decoder;
AVCodec ff_msa1_decoder;
AVCodec ff_msmpeg4_crystalhd_decoder;
AVCodec ff_msmpeg4v1_decoder;
AVCodec ff_msmpeg4v2_encoder;
AVCodec ff_msmpeg4v2_decoder;
AVCodec ff_msmpeg4v3_encoder;
AVCodec ff_msmpeg4v3_decoder;
AVCodec ff_msrle_decoder;
AVCodec ff_mss1_decoder;
AVCodec ff_mss2_decoder;
AVCodec ff_msvideo1_encoder;
AVCodec ff_msvideo1_decoder;
AVCodec ff_mszh_decoder;
AVCodec ff_mts2_decoder;
AVCodec ff_mvc1_decoder;
AVCodec ff_mvc2_decoder;
AVCodec ff_mxpeg_decoder;
AVCodec ff_nuv_decoder;
AVCodec ff_paf_video_decoder;
AVCodec ff_pam_encoder;
AVCodec ff_pam_decoder;
AVCodec ff_pbm_encoder;
AVCodec ff_pbm_decoder;
AVCodec ff_pcx_encoder;
AVCodec ff_pcx_decoder;
AVCodec ff_pgm_encoder;
AVCodec ff_pgm_decoder;
AVCodec ff_pgmyuv_encoder;
AVCodec ff_pgmyuv_decoder;
AVCodec ff_pictor_decoder;
AVCodec ff_png_encoder;
AVCodec ff_png_decoder;
AVCodec ff_ppm_encoder;
AVCodec ff_ppm_decoder;
AVCodec ff_prores_encoder;
AVCodec ff_prores_decoder;
AVCodec ff_prores_aw_encoder;
AVCodec ff_prores_ks_encoder;
AVCodec ff_prores_lgpl_decoder;
AVCodec ff_ptx_decoder;
AVCodec ff_qdraw_decoder;
AVCodec ff_qpeg_decoder;
AVCodec ff_qtrle_encoder;
AVCodec ff_qtrle_decoder;
AVCodec ff_r10k_encoder;
AVCodec ff_r10k_decoder;
AVCodec ff_r210_encoder;
AVCodec ff_r210_decoder;
AVCodec ff_rawvideo_encoder;
AVCodec ff_rawvideo_decoder;
AVCodec ff_rl2_decoder;
AVCodec ff_roq_encoder;
AVCodec ff_roq_decoder;
AVCodec ff_rpza_decoder;
AVCodec ff_rv10_encoder;
AVCodec ff_rv10_decoder;
AVCodec ff_rv20_encoder;
AVCodec ff_rv20_decoder;
AVCodec ff_rv30_decoder;
AVCodec ff_rv40_decoder;
AVCodec ff_s302m_encoder;
AVCodec ff_s302m_decoder;
AVCodec ff_sanm_decoder;
AVCodec ff_sgi_encoder;
AVCodec ff_sgi_decoder;
AVCodec ff_sgirle_decoder;
AVCodec ff_smacker_decoder;
AVCodec ff_smc_decoder;
AVCodec ff_smvjpeg_decoder;
AVCodec ff_snow_encoder;
AVCodec ff_snow_decoder;
AVCodec ff_sp5x_decoder;
AVCodec ff_sunrast_encoder;
AVCodec ff_sunrast_decoder;
AVCodec ff_svq1_encoder;
AVCodec ff_svq1_decoder;
AVCodec ff_svq3_decoder;
AVCodec ff_targa_encoder;
AVCodec ff_targa_decoder;
AVCodec ff_targa_y216_decoder;
AVCodec ff_tdsc_decoder;
AVCodec ff_theora_decoder;
AVCodec ff_thp_decoder;
AVCodec ff_tiertexseqvideo_decoder;
AVCodec ff_tiff_encoder;
AVCodec ff_tiff_decoder;
AVCodec ff_tmv_decoder;
AVCodec ff_truemotion1_decoder;
AVCodec ff_truemotion2_decoder;
AVCodec ff_tscc_decoder;
AVCodec ff_tscc2_decoder;
AVCodec ff_txd_decoder;
AVCodec ff_ulti_decoder;
AVCodec ff_utvideo_encoder;
AVCodec ff_utvideo_decoder;
AVCodec ff_v210_encoder;
AVCodec ff_v210_decoder;
AVCodec ff_v210x_decoder;
AVCodec ff_v308_encoder;
AVCodec ff_v308_decoder;
AVCodec ff_v408_encoder;
AVCodec ff_v408_decoder;
AVCodec ff_v410_encoder;
AVCodec ff_v410_decoder;
AVCodec ff_vb_decoder;
AVCodec ff_vble_decoder;
AVCodec ff_vc1_decoder;
AVCodec ff_vc1_crystalhd_decoder;
AVCodec ff_vc1_vdpau_decoder;
AVCodec ff_vc1image_decoder;
AVCodec ff_vc1_qsv_decoder;
AVCodec ff_vc2_encoder;
AVCodec ff_vcr1_decoder;
AVCodec ff_vmdvideo_decoder;
AVCodec ff_vmnc_decoder;
AVCodec ff_vp3_decoder;
AVCodec ff_vp5_decoder;
AVCodec ff_vp6_decoder;
AVCodec ff_vp6a_decoder;
AVCodec ff_vp6f_decoder;
AVCodec ff_vp7_decoder;
AVCodec ff_vqa_decoder;
AVCodec ff_webp_decoder;
AVCodec ff_wmv1_encoder;
AVCodec ff_wmv1_decoder;
AVCodec ff_wmv2_encoder;
AVCodec ff_wmv2_decoder;
AVCodec ff_wmv3_decoder;
AVCodec ff_wmv3_crystalhd_decoder;
AVCodec ff_wmv3_vdpau_decoder;
AVCodec ff_wmv3image_decoder;
AVCodec ff_wnv1_decoder;
AVCodec ff_xan_wc3_decoder;
AVCodec ff_xan_wc4_decoder;
AVCodec ff_xbm_encoder;
AVCodec ff_xbm_decoder;
AVCodec ff_xface_encoder;
AVCodec ff_xface_decoder;
AVCodec ff_xl_decoder;
AVCodec ff_xwd_encoder;
AVCodec ff_xwd_decoder;
AVCodec ff_y41p_encoder;
AVCodec ff_y41p_decoder;
AVCodec ff_yop_decoder;
AVCodec ff_yuv4_encoder;
AVCodec ff_yuv4_decoder;
AVCodec ff_zero12v_decoder;
AVCodec ff_zerocodec_decoder;
AVCodec ff_zlib_encoder;
AVCodec ff_zlib_decoder;
AVCodec ff_zmbv_encoder;
AVCodec ff_zmbv_decoder;
AVCodec ff_aac_encoder;
AVCodec ff_aac_decoder;
AVCodec ff_aac_fixed_decoder;
AVCodec ff_aac_latm_decoder;
AVCodec ff_ac3_encoder;
AVCodec ff_ac3_decoder;
AVCodec ff_ac3_fixed_encoder;
AVCodec ff_ac3_fixed_decoder;
AVCodec ff_alac_encoder;
AVCodec ff_alac_decoder;
AVCodec ff_als_decoder;
AVCodec ff_amrnb_decoder;
AVCodec ff_amrwb_decoder;
AVCodec ff_ape_decoder;
AVCodec ff_atrac1_decoder;
AVCodec ff_atrac3_decoder;
AVCodec ff_atrac3p_decoder;
AVCodec ff_binkaudio_dct_decoder;
AVCodec ff_binkaudio_rdft_decoder;
AVCodec ff_bmv_audio_decoder;
AVCodec ff_cook_decoder;
AVCodec ff_dca_encoder;
AVCodec ff_dca_decoder;
AVCodec ff_dsd_lsbf_decoder;
AVCodec ff_dsd_msbf_decoder;
AVCodec ff_dsd_lsbf_planar_decoder;
AVCodec ff_dsd_msbf_planar_decoder;
AVCodec ff_dsicinaudio_decoder;
AVCodec ff_dss_sp_decoder;
AVCodec ff_eac3_encoder;
AVCodec ff_eac3_decoder;
AVCodec ff_evrc_decoder;
AVCodec ff_ffwavesynth_decoder;
AVCodec ff_flac_encoder;
AVCodec ff_g723_1_encoder;
AVCodec ff_g723_1_decoder;
AVCodec ff_g729_decoder;
AVCodec ff_gsm_decoder;
AVCodec ff_gsm_ms_decoder;
AVCodec ff_iac_decoder;
AVCodec ff_imc_decoder;
AVCodec ff_mace3_decoder;
AVCodec ff_mace6_decoder;
AVCodec ff_metasound_decoder;
AVCodec ff_mlp_decoder;
AVCodec ff_mp1_decoder;
AVCodec ff_mp1float_decoder;
AVCodec ff_mp2_encoder;
AVCodec ff_mp2_decoder;
AVCodec ff_mp2float_decoder;
AVCodec ff_mp2fixed_encoder;
AVCodec ff_mp3_decoder;
AVCodec ff_mp3float_decoder;
AVCodec ff_mp3adu_decoder;
AVCodec ff_mp3adufloat_decoder;
AVCodec ff_mp3on4_decoder;
AVCodec ff_mp3on4float_decoder;
AVCodec ff_mpc7_decoder;
AVCodec ff_mpc8_decoder;
AVCodec ff_nellymoser_encoder;
AVCodec ff_nellymoser_decoder;
AVCodec ff_on2avc_decoder;
AVCodec ff_opus_decoder;
AVCodec ff_paf_audio_decoder;
AVCodec ff_qcelp_decoder;
AVCodec ff_qdm2_decoder;
AVCodec ff_ra_144_encoder;
AVCodec ff_ra_144_decoder;
AVCodec ff_ra_288_decoder;
AVCodec ff_ralf_decoder;
AVCodec ff_shorten_decoder;
AVCodec ff_sipr_decoder;
AVCodec ff_smackaud_decoder;
AVCodec ff_sonic_encoder;
AVCodec ff_sonic_decoder;
AVCodec ff_sonic_ls_encoder;
AVCodec ff_tak_decoder;
AVCodec ff_truehd_decoder;
AVCodec ff_truespeech_decoder;
AVCodec ff_tta_encoder;
AVCodec ff_tta_decoder;
AVCodec ff_twinvq_decoder;
AVCodec ff_vmdaudio_decoder;
AVCodec ff_vorbis_encoder;
AVCodec ff_vorbis_decoder;
AVCodec ff_wavpack_encoder;
AVCodec ff_wavpack_decoder;
AVCodec ff_wmalossless_decoder;
AVCodec ff_wmapro_decoder;
AVCodec ff_wmav1_encoder;
AVCodec ff_wmav1_decoder;
AVCodec ff_wmav2_encoder;
AVCodec ff_wmav2_decoder;
AVCodec ff_wmavoice_decoder;
AVCodec ff_ws_snd1_decoder;
AVCodec ff_pcm_alaw_encoder;
AVCodec ff_pcm_alaw_decoder;
AVCodec ff_pcm_bluray_decoder;
AVCodec ff_pcm_dvd_decoder;
AVCodec ff_pcm_f32be_encoder;
AVCodec ff_pcm_f32be_decoder;
AVCodec ff_pcm_f32le_encoder;
AVCodec ff_pcm_f32le_decoder;
AVCodec ff_pcm_f64be_encoder;
AVCodec ff_pcm_f64be_decoder;
AVCodec ff_pcm_f64le_encoder;
AVCodec ff_pcm_f64le_decoder;
AVCodec ff_pcm_lxf_decoder;
AVCodec ff_pcm_mulaw_encoder;
AVCodec ff_pcm_mulaw_decoder;
AVCodec ff_pcm_s8_encoder;
AVCodec ff_pcm_s8_decoder;
AVCodec ff_pcm_s8_planar_encoder;
AVCodec ff_pcm_s8_planar_decoder;
AVCodec ff_pcm_s16be_encoder;
AVCodec ff_pcm_s16be_decoder;
AVCodec ff_pcm_s16be_planar_encoder;
AVCodec ff_pcm_s16be_planar_decoder;
AVCodec ff_pcm_s16le_encoder;
AVCodec ff_pcm_s16le_decoder;
AVCodec ff_pcm_s16le_planar_encoder;
AVCodec ff_pcm_s16le_planar_decoder;
AVCodec ff_pcm_s24be_encoder;
AVCodec ff_pcm_s24be_decoder;
AVCodec ff_pcm_s24daud_encoder;
AVCodec ff_pcm_s24daud_decoder;
AVCodec ff_pcm_s24le_encoder;
AVCodec ff_pcm_s24le_decoder;
AVCodec ff_pcm_s24le_planar_encoder;
AVCodec ff_pcm_s24le_planar_decoder;
AVCodec ff_pcm_s32be_encoder;
AVCodec ff_pcm_s32be_decoder;
AVCodec ff_pcm_s32le_encoder;
AVCodec ff_pcm_s32le_decoder;
AVCodec ff_pcm_s32le_planar_encoder;
AVCodec ff_pcm_s32le_planar_decoder;
AVCodec ff_pcm_u8_encoder;
AVCodec ff_pcm_u8_decoder;
AVCodec ff_pcm_u16be_encoder;
AVCodec ff_pcm_u16be_decoder;
AVCodec ff_pcm_u16le_encoder;
AVCodec ff_pcm_u16le_decoder;
AVCodec ff_pcm_u24be_encoder;
AVCodec ff_pcm_u24be_decoder;
AVCodec ff_pcm_u24le_encoder;
AVCodec ff_pcm_u24le_decoder;
AVCodec ff_pcm_u32be_encoder;
AVCodec ff_pcm_u32be_decoder;
AVCodec ff_pcm_u32le_encoder;
AVCodec ff_pcm_u32le_decoder;
AVCodec ff_pcm_zork_decoder;
AVCodec ff_interplay_dpcm_decoder;
AVCodec ff_roq_dpcm_encoder;
AVCodec ff_roq_dpcm_decoder;
AVCodec ff_sol_dpcm_decoder;
AVCodec ff_xan_dpcm_decoder;
AVCodec ff_adpcm_4xm_decoder;
AVCodec ff_adpcm_adx_encoder;
AVCodec ff_adpcm_adx_decoder;
AVCodec ff_adpcm_afc_decoder;
AVCodec ff_adpcm_ct_decoder;
AVCodec ff_adpcm_dtk_decoder;
AVCodec ff_adpcm_ea_decoder;
AVCodec ff_adpcm_ea_maxis_xa_decoder;
AVCodec ff_adpcm_ea_r1_decoder;
AVCodec ff_adpcm_ea_r2_decoder;
AVCodec ff_adpcm_ea_r3_decoder;
AVCodec ff_adpcm_ea_xas_decoder;
AVCodec ff_adpcm_g722_encoder;
AVCodec ff_adpcm_g722_decoder;
AVCodec ff_adpcm_g726_encoder;
AVCodec ff_adpcm_g726_decoder;
AVCodec ff_adpcm_g726le_decoder;
AVCodec ff_adpcm_ima_amv_decoder;
AVCodec ff_adpcm_ima_apc_decoder;
AVCodec ff_adpcm_ima_dk3_decoder;
AVCodec ff_adpcm_ima_dk4_decoder;
AVCodec ff_adpcm_ima_ea_eacs_decoder;
AVCodec ff_adpcm_ima_ea_sead_decoder;
AVCodec ff_adpcm_ima_iss_decoder;
AVCodec ff_adpcm_ima_oki_decoder;
AVCodec ff_adpcm_ima_qt_encoder;
AVCodec ff_adpcm_ima_qt_decoder;
AVCodec ff_adpcm_ima_rad_decoder;
AVCodec ff_adpcm_ima_smjpeg_decoder;
AVCodec ff_adpcm_ima_wav_encoder;
AVCodec ff_adpcm_ima_wav_decoder;
AVCodec ff_adpcm_ima_ws_decoder;
AVCodec ff_adpcm_ms_encoder;
AVCodec ff_adpcm_ms_decoder;
AVCodec ff_adpcm_sbpro_2_decoder;
AVCodec ff_adpcm_sbpro_3_decoder;
AVCodec ff_adpcm_sbpro_4_decoder;
AVCodec ff_adpcm_swf_encoder;
AVCodec ff_adpcm_swf_decoder;
AVCodec ff_adpcm_thp_decoder;
AVCodec ff_adpcm_thp_le_decoder;
AVCodec ff_adpcm_vima_decoder;
AVCodec ff_adpcm_xa_decoder;
AVCodec ff_adpcm_yamaha_encoder;
AVCodec ff_adpcm_yamaha_decoder;
AVCodec ff_vima_decoder;
AVCodec ff_ssa_encoder;
AVCodec ff_ssa_decoder;
AVCodec ff_ass_encoder;
AVCodec ff_ass_decoder;
AVCodec ff_ccaption_decoder;
AVCodec ff_dvbsub_encoder;
AVCodec ff_dvbsub_decoder;
AVCodec ff_dvdsub_encoder;
AVCodec ff_dvdsub_decoder;
AVCodec ff_jacosub_decoder;
AVCodec ff_microdvd_decoder;
AVCodec ff_movtext_encoder;
AVCodec ff_movtext_decoder;
AVCodec ff_mpl2_decoder;
AVCodec ff_pgssub_decoder;
AVCodec ff_pjs_decoder;
AVCodec ff_realtext_decoder;
AVCodec ff_sami_decoder;
AVCodec ff_srt_encoder;
AVCodec ff_srt_decoder;
AVCodec ff_stl_decoder;
AVCodec ff_subrip_encoder;
AVCodec ff_subrip_decoder;
AVCodec ff_subviewer_decoder;
AVCodec ff_subviewer1_decoder;
AVCodec ff_text_decoder;
AVCodec ff_vplayer_decoder;
AVCodec ff_webvtt_encoder;
AVCodec ff_webvtt_decoder;
AVCodec ff_xsub_encoder;
AVCodec ff_xsub_decoder;
AVCodec ff_libcelt_decoder;
AVCodec ff_libdcadec_decoder;
AVCodec ff_libfaac_encoder;
AVCodec ff_libfdk_aac_encoder;
AVCodec ff_libfdk_aac_decoder;
AVCodec ff_libgsm_encoder;
AVCodec ff_libgsm_decoder;
AVCodec ff_libgsm_ms_encoder;
AVCodec ff_libgsm_ms_decoder;
AVCodec ff_libilbc_encoder;
AVCodec ff_libilbc_decoder;
AVCodec ff_libmp3lame_encoder;
AVCodec ff_libopencore_amrnb_encoder;
AVCodec ff_libopencore_amrnb_decoder;
AVCodec ff_libopencore_amrwb_decoder;
AVCodec ff_libopenjpeg_encoder;
AVCodec ff_libopenjpeg_decoder;
AVCodec ff_libopus_encoder;
AVCodec ff_libopus_decoder;
AVCodec ff_libschroedinger_encoder;
AVCodec ff_libschroedinger_decoder;
AVCodec ff_libshine_encoder;
AVCodec ff_libspeex_encoder;
AVCodec ff_libspeex_decoder;
AVCodec ff_libstagefright_h264_decoder;
AVCodec ff_libtheora_encoder;
AVCodec ff_libtwolame_encoder;
AVCodec ff_libutvideo_encoder;
AVCodec ff_libutvideo_decoder;
AVCodec ff_libvo_aacenc_encoder;
AVCodec ff_libvo_amrwbenc_encoder;
AVCodec ff_libvorbis_encoder;
AVCodec ff_libvorbis_decoder;
AVCodec ff_libvpx_vp8_encoder;
AVCodec ff_libvpx_vp8_decoder;
AVCodec ff_libvpx_vp9_encoder;
AVCodec ff_libvpx_vp9_decoder;
AVCodec ff_libwavpack_encoder;
AVCodec ff_libwebp_anim_encoder;
AVCodec ff_libwebp_encoder;
AVCodec ff_libx262_encoder;
AVCodec ff_libx264_encoder;
AVCodec ff_libx264rgb_encoder;
AVCodec ff_libx265_encoder;
AVCodec ff_libxavs_encoder;
AVCodec ff_libxvid_encoder;
AVCodec ff_libzvbi_teletext_decoder;
AVCodec ff_libaacplus_encoder;
AVCodec ff_bintext_decoder;
AVCodec ff_xbin_decoder;
AVCodec ff_idf_decoder;
AVCodec ff_libopenh264_encoder;
AVCodec ff_h264_qsv_encoder;
AVCodec ff_nvenc_encoder;
AVCodec ff_nvenc_h264_encoder;
AVCodec ff_nvenc_hevc_encoder;
AVCodec ff_hevc_qsv_encoder;
AVCodec ff_libkvazaar_encoder;
AVCodec ff_mpeg2_qsv_encoder;
AVCodec ff_dxv_decoder;
AVCodec ff_mpeg2_mmal_decoder;
AVCodec ff_rscc_decoder;
AVCodec ff_screenpresso_decoder;
AVCodec ff_sdx2_dpcm_decoder;
AVCodec ff_vc1_mmal_decoder;
AVCodec ff_wrapped_avframe_encoder;
AVCodec ff_interplay_acm_decoder;
AVCodec ff_xma1_decoder;
AVCodec ff_xma2_decoder;
AVCodec ff_adpcm_aica_decoder;
AVCodec ff_adpcm_psx_decoder;
AVCodec ff_text_encoder;
AVCodec ff_vp9_cuvid_decoder;
AVCodec ff_vp8_cuvid_decoder;
AVCodec ff_vc1_cuvid_decoder;
AVCodec ff_mjpeg_vaapi_encoder;
AVCodec ff_hevc_vaapi_encoder;
AVCodec ff_hevc_nvenc_encoder;
AVCodec ff_hevc_cuvid_decoder;
AVCodec ff_h264_videotoolbox_encoder;
AVCodec ff_h264_vaapi_encoder;
AVCodec ff_h264_omx_encoder;
AVCodec ff_h264_nvenc_encoder;
AVCodec ff_h264_cuvid_decoder;
AVCodec ff_qdm2_at_decoder;
AVCodec ff_qdmc_at_decoder;
AVCodec ff_pcm_mulaw_at_decoder;
AVCodec ff_pcm_mulaw_at_encoder;
AVCodec ff_pcm_alaw_at_decoder;
AVCodec ff_pcm_alaw_at_encoder;
AVCodec ff_mp3_at_decoder;
AVCodec ff_mp2_at_decoder;
AVCodec ff_mp1_at_decoder;
AVCodec ff_ilbc_at_decoder;
AVCodec ff_ilbc_at_encoder;
AVCodec ff_gsm_ms_at_decoder;
AVCodec ff_eac3_at_decoder;
AVCodec ff_amr_nb_at_decoder;
AVCodec ff_alac_at_decoder;
AVCodec ff_alac_at_encoder;
AVCodec ff_adpcm_ima_qt_at_decoder;
AVCodec ff_ac3_at_decoder;
AVCodec ff_aac_at_decoder;
AVCodec ff_aac_at_encoder;
AVCodec ff_adpcm_mtaf_decoder;
AVCodec ff_adpcm_ima_dat4_decoder;
AVCodec ff_dst_decoder;
AVCodec ff_ylc_decoder;
AVCodec ff_truemotion2rt_decoder;
AVCodec ff_sheervideo_decoder;
AVCodec ff_magicyuv_decoder;
AVCodec ff_m101_decoder;
AVCodec ff_h264_mediacodec_decoder;
AVCodecParser ff_aac_parser;
AVCodecParser ff_aac_latm_parser;
AVCodecParser ff_ac3_parser;
AVCodecParser ff_adx_parser;
AVCodecParser ff_bmp_parser;
AVCodecParser ff_cavsvideo_parser;
AVCodecParser ff_cook_parser;
AVCodecParser ff_dca_parser;
AVCodecParser ff_dirac_parser;
AVCodecParser ff_dnxhd_parser;
AVCodecParser ff_dpx_parser;
AVCodecParser ff_dvaudio_parser;
AVCodecParser ff_dvbsub_parser;
AVCodecParser ff_dvdsub_parser;
AVCodecParser ff_dvd_nav_parser;
AVCodecParser ff_g729_parser;
AVCodecParser ff_gsm_parser;
AVCodecParser ff_h261_parser;
AVCodecParser ff_h263_parser;
AVCodecParser ff_h264_parser;
AVCodecParser ff_hevc_parser;
AVCodecParser ff_mjpeg_parser;
AVCodecParser ff_mlp_parser;
AVCodecParser ff_mpeg4video_parser;
AVCodecParser ff_mpegaudio_parser;
AVCodecParser ff_mpegvideo_parser;
AVCodecParser ff_opus_parser;
AVCodecParser ff_png_parser;
AVCodecParser ff_pnm_parser;
AVCodecParser ff_rv30_parser;
AVCodecParser ff_rv40_parser;
AVCodecParser ff_tak_parser;
AVCodecParser ff_vc1_parser;
AVCodecParser ff_vorbis_parser;
AVCodecParser ff_vp3_parser;
AVBitStreamFilter ff_aac_adtstoasc_bsf;
AVBitStreamFilter ff_chomp_bsf;
AVBitStreamFilter ff_dump_extradata_bsf;
AVBitStreamFilter ff_h264_mp4toannexb_bsf;
AVBitStreamFilter ff_hevc_mp4toannexb_bsf;
AVBitStreamFilter ff_imx_dump_header_bsf;
AVBitStreamFilter ff_mjpeg2jpeg_bsf;
AVBitStreamFilter ff_mjpega_dump_header_bsf;
AVBitStreamFilter ff_mp3_header_decompress_bsf;
AVBitStreamFilter ff_mpeg4_unpack_bframes_bsf;
AVBitStreamFilter ff_mov2textsub_bsf;
AVBitStreamFilter ff_noise_bsf;
AVBitStreamFilter ff_remove_extradata_bsf;
AVBitStreamFilter ff_text2movsub_bsf;
void ff_h264_pred_init_aarch64(H264PredContext *h, int codec_id,
const int bit_depth,
const int chroma_format_idc) {}
void ff_h264_pred_init_arm(H264PredContext *h, int codec_id,
const int bit_depth, const int chroma_format_idc) {}
void ff_h264_pred_init_mips(H264PredContext *h, int codec_id,
const int bit_depth, const int chroma_format_idc) {}
void ff_me_cmp_init_static(void) {}
int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options) { return 0; }
void ff_frame_thread_encoder_free(AVCodecContext *avctx) {}
int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr) { return 0; }
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_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_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) {}
void ff_flac_decorrelate_indep8_32_avx(uint8_t **out, int32_t **in, int channels, int len, int shift) {}
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) {}

View file

@ -0,0 +1,96 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_ERROR_RESILIENCE_H
#define AVCODEC_ERROR_RESILIENCE_H
#include <stdint.h>
#include "avcodec.h"
#include "me_cmp.h"
#include "thread.h"
///< current MB is the first after a resync marker
#define VP_START 1
#define ER_AC_ERROR 2
#define ER_DC_ERROR 4
#define ER_MV_ERROR 8
#define ER_AC_END 16
#define ER_DC_END 32
#define ER_MV_END 64
#define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR)
#define ER_MB_END (ER_AC_END|ER_DC_END|ER_MV_END)
typedef struct ERPicture {
AVFrame *f;
ThreadFrame *tf;
// it is the caller's responsibility to allocate these buffers
int16_t (*motion_val[2])[2];
int8_t *ref_index[2];
uint32_t *mb_type;
int field_picture;
} ERPicture;
typedef struct ERContext {
AVCodecContext *avctx;
MECmpContext mecc;
int mecc_inited;
int *mb_index2xy;
int mb_num;
int mb_width, mb_height;
int mb_stride;
int b8_stride;
volatile int error_count;
int error_occurred;
uint8_t *error_status_table;
uint8_t *er_temp_buffer;
int16_t *dc_val[3];
uint8_t *mbskip_table;
uint8_t *mbintra_table;
int mv[2][4][2];
ERPicture cur_pic;
ERPicture last_pic;
ERPicture next_pic;
AVBufferRef *ref_index_buf[2];
AVBufferRef *motion_val_buf[2];
uint16_t pp_time;
uint16_t pb_time;
int quarter_sample;
int partitioned_frame;
int ref_count;
void (*decode_mb)(void *opaque, int ref, int mv_dir, int mv_type,
int (*mv)[2][4][2],
int mb_x, int mb_y, int mb_intra, int mb_skipped);
void *opaque;
} ERContext;
void ff_er_frame_start(ERContext *s);
void ff_er_frame_end(ERContext *s);
void ff_er_add_slice(ERContext *s, int startx, int starty, int endx, int endy,
int status);
#endif /* AVCODEC_ERROR_RESILIENCE_H */

View file

@ -0,0 +1,37 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_FDCTDSP_H
#define AVCODEC_FDCTDSP_H
#include <stdint.h>
#include "avcodec.h"
typedef struct FDCTDSPContext {
void (*fdct)(int16_t *block /* align 16 */);
void (*fdct248)(int16_t *block /* align 16 */);
} FDCTDSPContext;
void ff_fdctdsp_init(FDCTDSPContext *c, AVCodecContext *avctx);
void ff_fdctdsp_init_ppc(FDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_fdctdsp_init_x86(FDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
#endif /* AVCODEC_FDCTDSP_H */

View file

@ -0,0 +1,30 @@
/*
* 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 "libavutil/opt.h"
static const AVOption avcodec_options[] = {
{NULL},
};
#endif /* AVCODEC_OPTIONS_TABLE_H */

View file

@ -0,0 +1,237 @@
/*
* FLAC common code
* Copyright (c) 2009 Justin Ruggles
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
#include "libavutil/log.h"
#include "bytestream.h"
#include "get_bits.h"
#include "flac.h"
#include "flacdata.h"
static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
static const uint64_t flac_channel_layouts[8] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_SURROUND,
AV_CH_LAYOUT_QUAD,
AV_CH_LAYOUT_5POINT0,
AV_CH_LAYOUT_5POINT1,
AV_CH_LAYOUT_6POINT1,
AV_CH_LAYOUT_7POINT1
};
static int64_t get_utf8(GetBitContext *gb)
{
int64_t val;
GET_UTF8(val, get_bits(gb, 8), return -1;)
return val;
}
int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
FLACFrameInfo *fi, int log_level_offset)
{
int bs_code, sr_code, bps_code;
/* frame sync code */
if ((get_bits(gb, 15) & 0x7FFF) != 0x7FFC) {
av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid sync code\n");
return AVERROR_INVALIDDATA;
}
/* variable block size stream code */
fi->is_var_size = get_bits1(gb);
/* block size and sample rate codes */
bs_code = get_bits(gb, 4);
sr_code = get_bits(gb, 4);
/* channels and decorrelation */
fi->ch_mode = get_bits(gb, 4);
if (fi->ch_mode < FLAC_MAX_CHANNELS) {
fi->channels = fi->ch_mode + 1;
fi->ch_mode = FLAC_CHMODE_INDEPENDENT;
} else if (fi->ch_mode < FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE) {
fi->channels = 2;
fi->ch_mode -= FLAC_MAX_CHANNELS - 1;
} else {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"invalid channel mode: %d\n", fi->ch_mode);
return AVERROR_INVALIDDATA;
}
/* bits per sample */
bps_code = get_bits(gb, 3);
if (bps_code == 3 || bps_code == 7) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"invalid sample size code (%d)\n",
bps_code);
return AVERROR_INVALIDDATA;
}
fi->bps = sample_size_table[bps_code];
/* reserved bit */
if (get_bits1(gb)) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"broken stream, invalid padding\n");
return AVERROR_INVALIDDATA;
}
/* sample or frame count */
fi->frame_or_sample_num = get_utf8(gb);
if (fi->frame_or_sample_num < 0) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"sample/frame number invalid; utf8 fscked\n");
return AVERROR_INVALIDDATA;
}
/* blocksize */
if (bs_code == 0) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"reserved blocksize code: 0\n");
return AVERROR_INVALIDDATA;
} else if (bs_code == 6) {
fi->blocksize = get_bits(gb, 8) + 1;
} else if (bs_code == 7) {
fi->blocksize = get_bits(gb, 16) + 1;
} else {
fi->blocksize = ff_flac_blocksize_table[bs_code];
}
/* sample rate */
if (sr_code < 12) {
fi->samplerate = ff_flac_sample_rate_table[sr_code];
} else if (sr_code == 12) {
fi->samplerate = get_bits(gb, 8) * 1000;
} else if (sr_code == 13) {
fi->samplerate = get_bits(gb, 16);
} else if (sr_code == 14) {
fi->samplerate = get_bits(gb, 16) * 10;
} else {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"illegal sample rate code %d\n",
sr_code);
return AVERROR_INVALIDDATA;
}
/* header CRC-8 check */
skip_bits(gb, 8);
if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer,
get_bits_count(gb)/8)) {
av_log(avctx, AV_LOG_ERROR + log_level_offset,
"header crc mismatch\n");
return AVERROR_INVALIDDATA;
}
return 0;
}
int ff_flac_get_max_frame_size(int blocksize, int ch, int bps)
{
/* Technically, there is no limit to FLAC frame size, but an encoder
should not write a frame that is larger than if verbatim encoding mode
were to be used. */
int count;
count = 16; /* frame header */
count += ch * ((7+bps+7)/8); /* subframe headers */
if (ch == 2) {
/* for stereo, need to account for using decorrelation */
count += (( 2*bps+1) * blocksize + 7) / 8;
} else {
count += ( ch*bps * blocksize + 7) / 8;
}
count += 2; /* frame footer */
return count;
}
int ff_flac_is_extradata_valid(AVCodecContext *avctx,
enum FLACExtradataFormat *format,
uint8_t **streaminfo_start)
{
if (!avctx->extradata || avctx->extradata_size < FLAC_STREAMINFO_SIZE) {
av_log(avctx, AV_LOG_ERROR, "extradata NULL or too small.\n");
return 0;
}
if (AV_RL32(avctx->extradata) != MKTAG('f','L','a','C')) {
/* extradata contains STREAMINFO only */
if (avctx->extradata_size != FLAC_STREAMINFO_SIZE) {
av_log(avctx, AV_LOG_WARNING, "extradata contains %d bytes too many.\n",
FLAC_STREAMINFO_SIZE-avctx->extradata_size);
}
*format = FLAC_EXTRADATA_FORMAT_STREAMINFO;
*streaminfo_start = avctx->extradata;
} else {
if (avctx->extradata_size < 8+FLAC_STREAMINFO_SIZE) {
av_log(avctx, AV_LOG_ERROR, "extradata too small.\n");
return 0;
}
*format = FLAC_EXTRADATA_FORMAT_FULL_HEADER;
*streaminfo_start = &avctx->extradata[8];
}
return 1;
}
void ff_flac_set_channel_layout(AVCodecContext *avctx)
{
if (avctx->channels <= FF_ARRAY_ELEMS(flac_channel_layouts))
avctx->channel_layout = flac_channel_layouts[avctx->channels - 1];
else
avctx->channel_layout = 0;
}
void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
const uint8_t *buffer)
{
GetBitContext gb;
init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8);
skip_bits(&gb, 16); /* skip min blocksize */
s->max_blocksize = get_bits(&gb, 16);
if (s->max_blocksize < FLAC_MIN_BLOCKSIZE) {
av_log(avctx, AV_LOG_WARNING, "invalid max blocksize: %d\n",
s->max_blocksize);
s->max_blocksize = 16;
}
skip_bits(&gb, 24); /* skip min frame size */
s->max_framesize = get_bits_long(&gb, 24);
s->samplerate = get_bits_long(&gb, 20);
s->channels = get_bits(&gb, 3) + 1;
s->bps = get_bits(&gb, 5) + 1;
avctx->channels = s->channels;
avctx->sample_rate = s->samplerate;
avctx->bits_per_raw_sample = s->bps;
if (!avctx->channel_layout ||
av_get_channel_layout_nb_channels(avctx->channel_layout) != avctx->channels)
ff_flac_set_channel_layout(avctx);
s->samples = get_bits64(&gb, 36);
skip_bits_long(&gb, 64); /* md5 sum */
skip_bits_long(&gb, 64); /* md5 sum */
}

View file

@ -0,0 +1,153 @@
/*
* FLAC (Free Lossless Audio Codec) decoder/demuxer common functions
* Copyright (c) 2008 Justin Ruggles
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* FLAC (Free Lossless Audio Codec) decoder/demuxer common functions
*/
#ifndef AVCODEC_FLAC_H
#define AVCODEC_FLAC_H
#include "avcodec.h"
#include "bytestream.h"
#include "get_bits.h"
#define FLAC_STREAMINFO_SIZE 34
#define FLAC_MAX_CHANNELS 8
#define FLAC_MIN_BLOCKSIZE 16
#define FLAC_MAX_BLOCKSIZE 65535
#define FLAC_MIN_FRAME_SIZE 11
enum {
FLAC_CHMODE_INDEPENDENT = 0,
FLAC_CHMODE_LEFT_SIDE = 1,
FLAC_CHMODE_RIGHT_SIDE = 2,
FLAC_CHMODE_MID_SIDE = 3,
};
enum {
FLAC_METADATA_TYPE_STREAMINFO = 0,
FLAC_METADATA_TYPE_PADDING,
FLAC_METADATA_TYPE_APPLICATION,
FLAC_METADATA_TYPE_SEEKTABLE,
FLAC_METADATA_TYPE_VORBIS_COMMENT,
FLAC_METADATA_TYPE_CUESHEET,
FLAC_METADATA_TYPE_PICTURE,
FLAC_METADATA_TYPE_INVALID = 127
};
enum FLACExtradataFormat {
FLAC_EXTRADATA_FORMAT_STREAMINFO = 0,
FLAC_EXTRADATA_FORMAT_FULL_HEADER = 1
};
#define FLACCOMMONINFO \
int samplerate; /**< sample rate */\
int channels; /**< number of channels */\
int bps; /**< bits-per-sample */\
/**
* Data needed from the Streaminfo header for use by the raw FLAC demuxer
* and/or the FLAC decoder.
*/
#define FLACSTREAMINFO \
FLACCOMMONINFO \
int max_blocksize; /**< maximum block size, in samples */\
int max_framesize; /**< maximum frame size, in bytes */\
int64_t samples; /**< total number of samples */\
typedef struct FLACStreaminfo {
FLACSTREAMINFO
} FLACStreaminfo;
typedef struct FLACFrameInfo {
FLACCOMMONINFO
int blocksize; /**< block size of the frame */
int ch_mode; /**< channel decorrelation mode */
int64_t frame_or_sample_num; /**< frame number or sample number */
int is_var_size; /**< specifies if the stream uses variable
block sizes or a fixed block size;
also determines the meaning of
frame_or_sample_num */
} FLACFrameInfo;
/**
* Parse the Streaminfo metadata block
* @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
*/
void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
const uint8_t *buffer);
/**
* Validate the FLAC extradata.
* @param[in] avctx codec context containing the extradata.
* @param[out] format extradata format.
* @param[out] streaminfo_start pointer to start of 34-byte STREAMINFO data.
* @return 1 if valid, 0 if not valid.
*/
int ff_flac_is_extradata_valid(AVCodecContext *avctx,
enum FLACExtradataFormat *format,
uint8_t **streaminfo_start);
/**
* Calculate an estimate for the maximum frame size based on verbatim mode.
* @param blocksize block size, in samples
* @param ch number of channels
* @param bps bits-per-sample
*/
int ff_flac_get_max_frame_size(int blocksize, int ch, int bps);
/**
* Validate and decode a frame header.
* @param avctx AVCodecContext to use as av_log() context
* @param gb GetBitContext from which to read frame header
* @param[out] fi frame information
* @param log_level_offset log level offset. can be used to silence error messages.
* @return non-zero on error, 0 if ok
*/
int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
FLACFrameInfo *fi, int log_level_offset);
void ff_flac_set_channel_layout(AVCodecContext *avctx);
/**
* Parse the metadata block parameters from the header.
* @param[in] block_header header data, at least 4 bytes
* @param[out] last indicator for last metadata block
* @param[out] type metadata block type
* @param[out] size metadata block size
*/
static av_always_inline void flac_parse_block_header(const uint8_t *block_header,
int *last, int *type, int *size)
{
int tmp = bytestream_get_byte(&block_header);
if (last)
*last = tmp & 0x80;
if (type)
*type = tmp & 0x7F;
if (size)
*size = bytestream_get_be24(&block_header);
}
#endif /* AVCODEC_FLAC_H */

View file

@ -0,0 +1,755 @@
/*
* FLAC parser
* Copyright (c) 2010 Michael Chinen
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* FLAC parser
*
* The FLAC parser buffers input until FLAC_MIN_HEADERS has been found.
* Each time it finds and verifies a CRC-8 header it sees which of the
* FLAC_MAX_SEQUENTIAL_HEADERS that came before it have a valid CRC-16 footer
* that ends at the newly found header.
* Headers are scored by FLAC_HEADER_BASE_SCORE plus the max of its crc-verified
* children, penalized by changes in sample rate, frame number, etc.
* The parser returns the frame with the highest score.
**/
#include "libavutil/attributes.h"
#include "libavutil/crc.h"
#include "libavutil/fifo.h"
#include "bytestream.h"
#include "parser.h"
#include "flac.h"
/** maximum number of adjacent headers that compare CRCs against each other */
#define FLAC_MAX_SEQUENTIAL_HEADERS 4
/** minimum number of headers buffered and checked before returning frames */
#define FLAC_MIN_HEADERS 10
/** estimate for average size of a FLAC frame */
#define FLAC_AVG_FRAME_SIZE 8192
/** scoring settings for score_header */
#define FLAC_HEADER_BASE_SCORE 10
#define FLAC_HEADER_CHANGED_PENALTY 7
#define FLAC_HEADER_CRC_FAIL_PENALTY 50
#define FLAC_HEADER_NOT_PENALIZED_YET 100000
#define FLAC_HEADER_NOT_SCORED_YET -100000
/** largest possible size of flac header */
#define MAX_FRAME_HEADER_SIZE 16
typedef struct FLACHeaderMarker {
int offset; /**< byte offset from start of FLACParseContext->buffer */
int *link_penalty; /**< pointer to array of local scores between this header
and the one at a distance equal array position */
int max_score; /**< maximum score found after checking each child that
has a valid CRC */
FLACFrameInfo fi; /**< decoded frame header info */
struct FLACHeaderMarker *next; /**< next CRC-8 verified header that
immediately follows this one in
the bytestream */
struct FLACHeaderMarker *best_child; /**< following frame header with
which this frame has the best
score with */
} FLACHeaderMarker;
typedef struct FLACParseContext {
AVCodecParserContext *pc; /**< parent context */
AVCodecContext *avctx; /**< codec context pointer for logging */
FLACHeaderMarker *headers; /**< linked-list that starts at the first
CRC-8 verified header within buffer */
FLACHeaderMarker *best_header; /**< highest scoring header within buffer */
int nb_headers_found; /**< number of headers found in the last
flac_parse() call */
int nb_headers_buffered; /**< number of headers that are buffered */
int best_header_valid; /**< flag set when the parser returns junk;
if set return best_header next time */
AVFifoBuffer *fifo_buf; /**< buffer to store all data until headers
can be verified */
int end_padded; /**< specifies if fifo_buf's end is padded */
uint8_t *wrap_buf; /**< general fifo read buffer when wrapped */
int wrap_buf_allocated_size; /**< actual allocated size of the buffer */
FLACFrameInfo last_fi; /**< last decoded frame header info */
int last_fi_valid; /**< set if last_fi is valid */
} FLACParseContext;
static int frame_header_is_valid(AVCodecContext *avctx, const uint8_t *buf,
FLACFrameInfo *fi)
{
GetBitContext gb;
init_get_bits(&gb, buf, MAX_FRAME_HEADER_SIZE * 8);
return !ff_flac_decode_frame_header(avctx, &gb, fi, 127);
}
/**
* Non-destructive fast fifo pointer fetching
* Returns a pointer from the specified offset.
* If possible the pointer points within the fifo buffer.
* Otherwise (if it would cause a wrap around,) a pointer to a user-specified
* buffer is used.
* The pointer can be NULL. In any case it will be reallocated to hold the size.
* If the returned pointer will be used after subsequent calls to flac_fifo_read_wrap
* then the subsequent calls should pass in a different wrap_buf so as to not
* overwrite the contents of the previous wrap_buf.
* This function is based on av_fifo_generic_read, which is why there is a comment
* about a memory barrier for SMP.
*/
static uint8_t* flac_fifo_read_wrap(FLACParseContext *fpc, int offset, int len,
uint8_t** wrap_buf, int* allocated_size)
{
AVFifoBuffer *f = fpc->fifo_buf;
uint8_t *start = f->rptr + offset;
uint8_t *tmp_buf;
if (start >= f->end)
start -= f->end - f->buffer;
if (f->end - start >= len)
return start;
tmp_buf = av_fast_realloc(*wrap_buf, allocated_size, len);
if (!tmp_buf) {
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't reallocate wrap buffer of size %d", len);
return NULL;
}
*wrap_buf = tmp_buf;
do {
int seg_len = FFMIN(f->end - start, len);
memcpy(tmp_buf, start, seg_len);
tmp_buf = (uint8_t*)tmp_buf + seg_len;
// memory barrier needed for SMP here in theory
start += seg_len - (f->end - f->buffer);
len -= seg_len;
} while (len > 0);
return *wrap_buf;
}
/**
* Return a pointer in the fifo buffer where the offset starts at until
* the wrap point or end of request.
* len will contain the valid length of the returned buffer.
* A second call to flac_fifo_read (with new offset and len) should be called
* to get the post-wrap buf if the returned len is less than the requested.
**/
static uint8_t* flac_fifo_read(FLACParseContext *fpc, int offset, int *len)
{
AVFifoBuffer *f = fpc->fifo_buf;
uint8_t *start = f->rptr + offset;
if (start >= f->end)
start -= f->end - f->buffer;
*len = FFMIN(*len, f->end - start);
return start;
}
static int find_headers_search_validate(FLACParseContext *fpc, int offset)
{
FLACFrameInfo fi;
uint8_t *header_buf;
int size = 0;
header_buf = flac_fifo_read_wrap(fpc, offset,
MAX_FRAME_HEADER_SIZE,
&fpc->wrap_buf,
&fpc->wrap_buf_allocated_size);
if (frame_header_is_valid(fpc->avctx, header_buf, &fi)) {
FLACHeaderMarker **end_handle = &fpc->headers;
int i;
size = 0;
while (*end_handle) {
end_handle = &(*end_handle)->next;
size++;
}
*end_handle = av_mallocz(sizeof(**end_handle));
if (!*end_handle) {
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't allocate FLACHeaderMarker\n");
return AVERROR(ENOMEM);
}
(*end_handle)->fi = fi;
(*end_handle)->offset = offset;
(*end_handle)->link_penalty = av_malloc(sizeof(int) *
FLAC_MAX_SEQUENTIAL_HEADERS);
if (!(*end_handle)->link_penalty) {
av_freep(end_handle);
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't allocate link_penalty\n");
return AVERROR(ENOMEM);
}
for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS; i++)
(*end_handle)->link_penalty[i] = FLAC_HEADER_NOT_PENALIZED_YET;
fpc->nb_headers_found++;
size++;
}
return size;
}
static int find_headers_search(FLACParseContext *fpc, uint8_t *buf, int buf_size,
int search_start)
{
int size = 0, mod_offset = (buf_size - 1) % 4, i, j;
uint32_t x;
for (i = 0; i < mod_offset; i++) {
if ((AV_RB16(buf + i) & 0xFFFE) == 0xFFF8)
size = find_headers_search_validate(fpc, search_start + i);
}
for (; i < buf_size - 1; i += 4) {
x = AV_RB32(buf + i);
if (((x & ~(x + 0x01010101)) & 0x80808080)) {
for (j = 0; j < 4; j++) {
if ((AV_RB16(buf + i + j) & 0xFFFE) == 0xFFF8)
size = find_headers_search_validate(fpc, search_start + i + j);
}
}
}
return size;
}
static int find_new_headers(FLACParseContext *fpc, int search_start)
{
FLACHeaderMarker *end;
int search_end, size = 0, read_len, temp;
uint8_t *buf;
fpc->nb_headers_found = 0;
/* Search for a new header of at most 16 bytes. */
search_end = av_fifo_size(fpc->fifo_buf) - (MAX_FRAME_HEADER_SIZE - 1);
read_len = search_end - search_start + 1;
buf = flac_fifo_read(fpc, search_start, &read_len);
size = find_headers_search(fpc, buf, read_len, search_start);
search_start += read_len - 1;
/* If fifo end was hit do the wrap around. */
if (search_start != search_end) {
uint8_t wrap[2];
wrap[0] = buf[read_len - 1];
read_len = search_end - search_start + 1;
/* search_start + 1 is the post-wrap offset in the fifo. */
buf = flac_fifo_read(fpc, search_start + 1, &read_len);
wrap[1] = buf[0];
if ((AV_RB16(wrap) & 0xFFFE) == 0xFFF8) {
temp = find_headers_search_validate(fpc, search_start);
size = FFMAX(size, temp);
}
search_start++;
/* Continue to do the last half of the wrap. */
temp = find_headers_search(fpc, buf, read_len, search_start);
size = FFMAX(size, temp);
search_start += read_len - 1;
}
/* Return the size even if no new headers were found. */
if (!size && fpc->headers)
for (end = fpc->headers; end; end = end->next)
size++;
return size;
}
static int check_header_fi_mismatch(FLACParseContext *fpc,
FLACFrameInfo *header_fi,
FLACFrameInfo *child_fi,
int log_level_offset)
{
int deduction = 0;
if (child_fi->samplerate != header_fi->samplerate) {
deduction += FLAC_HEADER_CHANGED_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"sample rate change detected in adjacent frames\n");
}
if (child_fi->bps != header_fi->bps) {
deduction += FLAC_HEADER_CHANGED_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"bits per sample change detected in adjacent frames\n");
}
if (child_fi->is_var_size != header_fi->is_var_size) {
/* Changing blocking strategy not allowed per the spec */
deduction += FLAC_HEADER_BASE_SCORE;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"blocking strategy change detected in adjacent frames\n");
}
if (child_fi->channels != header_fi->channels) {
deduction += FLAC_HEADER_CHANGED_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"number of channels change detected in adjacent frames\n");
}
return deduction;
}
static int check_header_mismatch(FLACParseContext *fpc,
FLACHeaderMarker *header,
FLACHeaderMarker *child,
int log_level_offset)
{
FLACFrameInfo *header_fi = &header->fi, *child_fi = &child->fi;
int deduction, deduction_expected = 0, i;
deduction = check_header_fi_mismatch(fpc, header_fi, child_fi,
log_level_offset);
/* Check sample and frame numbers. */
if ((child_fi->frame_or_sample_num - header_fi->frame_or_sample_num
!= header_fi->blocksize) &&
(child_fi->frame_or_sample_num
!= header_fi->frame_or_sample_num + 1)) {
FLACHeaderMarker *curr;
int expected_frame_num, expected_sample_num;
/* If there are frames in the middle we expect this deduction,
as they are probably valid and this one follows it */
expected_frame_num = expected_sample_num = header_fi->frame_or_sample_num;
curr = header;
while (curr != child) {
/* Ignore frames that failed all crc checks */
for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS; i++) {
if (curr->link_penalty[i] < FLAC_HEADER_CRC_FAIL_PENALTY) {
expected_frame_num++;
expected_sample_num += curr->fi.blocksize;
break;
}
}
curr = curr->next;
}
if (expected_frame_num == child_fi->frame_or_sample_num ||
expected_sample_num == child_fi->frame_or_sample_num)
deduction_expected = deduction ? 0 : 1;
deduction += FLAC_HEADER_CHANGED_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"sample/frame number mismatch in adjacent frames\n");
}
/* If we have suspicious headers, check the CRC between them */
if (deduction && !deduction_expected) {
FLACHeaderMarker *curr;
int read_len;
uint8_t *buf;
uint32_t crc = 1;
int inverted_test = 0;
/* Since CRC is expensive only do it if we haven't yet.
This assumes a CRC penalty is greater than all other check penalties */
curr = header->next;
for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS && curr != child; i++)
curr = curr->next;
if (header->link_penalty[i] < FLAC_HEADER_CRC_FAIL_PENALTY ||
header->link_penalty[i] == FLAC_HEADER_NOT_PENALIZED_YET) {
FLACHeaderMarker *start, *end;
/* Although overlapping chains are scored, the crc should never
have to be computed twice for a single byte. */
start = header;
end = child;
if (i > 0 &&
header->link_penalty[i - 1] >= FLAC_HEADER_CRC_FAIL_PENALTY) {
while (start->next != child)
start = start->next;
inverted_test = 1;
} else if (i > 0 &&
header->next->link_penalty[i-1] >=
FLAC_HEADER_CRC_FAIL_PENALTY ) {
end = header->next;
inverted_test = 1;
}
read_len = end->offset - start->offset;
buf = flac_fifo_read(fpc, start->offset, &read_len);
crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf, read_len);
read_len = (end->offset - start->offset) - read_len;
if (read_len) {
buf = flac_fifo_read(fpc, end->offset - read_len, &read_len);
crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI), crc, buf, read_len);
}
}
if (!crc ^ !inverted_test) {
deduction += FLAC_HEADER_CRC_FAIL_PENALTY;
av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
"crc check failed from offset %i (frame %"PRId64") to %i (frame %"PRId64")\n",
header->offset, header_fi->frame_or_sample_num,
child->offset, child_fi->frame_or_sample_num);
}
}
return deduction;
}
/**
* Score a header.
*
* Give FLAC_HEADER_BASE_SCORE points to a frame for existing.
* If it has children, (subsequent frames of which the preceding CRC footer
* validates against this one,) then take the maximum score of the children,
* with a penalty of FLAC_HEADER_CHANGED_PENALTY applied for each change to
* bps, sample rate, channels, but not decorrelation mode, or blocksize,
* because it can change often.
**/
static int score_header(FLACParseContext *fpc, FLACHeaderMarker *header)
{
FLACHeaderMarker *child;
int dist = 0;
int child_score;
int base_score = FLAC_HEADER_BASE_SCORE;
if (header->max_score != FLAC_HEADER_NOT_SCORED_YET)
return header->max_score;
/* Modify the base score with changes from the last output header */
if (fpc->last_fi_valid) {
/* Silence the log since this will be repeated if selected */
base_score -= check_header_fi_mismatch(fpc, &fpc->last_fi, &header->fi,
AV_LOG_DEBUG);
}
header->max_score = base_score;
/* Check and compute the children's scores. */
child = header->next;
for (dist = 0; dist < FLAC_MAX_SEQUENTIAL_HEADERS && child; dist++) {
/* Look at the child's frame header info and penalize suspicious
changes between the headers. */
if (header->link_penalty[dist] == FLAC_HEADER_NOT_PENALIZED_YET) {
header->link_penalty[dist] = check_header_mismatch(fpc, header,
child, AV_LOG_DEBUG);
}
child_score = score_header(fpc, child) - header->link_penalty[dist];
if (FLAC_HEADER_BASE_SCORE + child_score > header->max_score) {
/* Keep the child because the frame scoring is dynamic. */
header->best_child = child;
header->max_score = base_score + child_score;
}
child = child->next;
}
return header->max_score;
}
static void score_sequences(FLACParseContext *fpc)
{
FLACHeaderMarker *curr;
int best_score = 0;//FLAC_HEADER_NOT_SCORED_YET;
/* First pass to clear all old scores. */
for (curr = fpc->headers; curr; curr = curr->next)
curr->max_score = FLAC_HEADER_NOT_SCORED_YET;
/* Do a second pass to score them all. */
for (curr = fpc->headers; curr; curr = curr->next) {
if (score_header(fpc, curr) > best_score) {
fpc->best_header = curr;
best_score = curr->max_score;
}
}
}
static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf,
int *poutbuf_size)
{
FLACHeaderMarker *header = fpc->best_header;
FLACHeaderMarker *child = header->best_child;
if (!child) {
*poutbuf_size = av_fifo_size(fpc->fifo_buf) - header->offset;
} else {
*poutbuf_size = child->offset - header->offset;
/* If the child has suspicious changes, log them */
check_header_mismatch(fpc, header, child, 0);
}
if (header->fi.channels != fpc->avctx->channels ||
!fpc->avctx->channel_layout) {
fpc->avctx->channels = header->fi.channels;
ff_flac_set_channel_layout(fpc->avctx);
}
fpc->avctx->sample_rate = header->fi.samplerate;
fpc->pc->duration = header->fi.blocksize;
*poutbuf = flac_fifo_read_wrap(fpc, header->offset, *poutbuf_size,
&fpc->wrap_buf,
&fpc->wrap_buf_allocated_size);
if (fpc->pc->flags & PARSER_FLAG_USE_CODEC_TS){
if (header->fi.is_var_size)
fpc->pc->pts = header->fi.frame_or_sample_num;
else if (header->best_child)
fpc->pc->pts = header->fi.frame_or_sample_num * header->fi.blocksize;
}
fpc->best_header_valid = 0;
fpc->last_fi_valid = 1;
fpc->last_fi = header->fi;
/* Return the negative overread index so the client can compute pos.
This should be the amount overread to the beginning of the child */
if (child)
return child->offset - av_fifo_size(fpc->fifo_buf);
return 0;
}
static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
FLACParseContext *fpc = s->priv_data;
FLACHeaderMarker *curr;
int nb_headers;
const uint8_t *read_end = buf;
const uint8_t *read_start = buf;
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
FLACFrameInfo fi;
if (frame_header_is_valid(avctx, buf, &fi)) {
s->duration = fi.blocksize;
if (!avctx->sample_rate)
avctx->sample_rate = fi.samplerate;
if (fpc->pc->flags & PARSER_FLAG_USE_CODEC_TS){
fpc->pc->pts = fi.frame_or_sample_num;
if (!fi.is_var_size)
fpc->pc->pts *= fi.blocksize;
}
}
*poutbuf = buf;
*poutbuf_size = buf_size;
return buf_size;
}
fpc->avctx = avctx;
if (fpc->best_header_valid)
return get_best_header(fpc, poutbuf, poutbuf_size);
/* If a best_header was found last call remove it with the buffer data. */
if (fpc->best_header && fpc->best_header->best_child) {
FLACHeaderMarker *temp;
FLACHeaderMarker *best_child = fpc->best_header->best_child;
/* Remove headers in list until the end of the best_header. */
for (curr = fpc->headers; curr != best_child; curr = temp) {
if (curr != fpc->best_header) {
av_log(avctx, AV_LOG_DEBUG,
"dropping low score %i frame header from offset %i to %i\n",
curr->max_score, curr->offset, curr->next->offset);
}
temp = curr->next;
av_freep(&curr->link_penalty);
av_free(curr);
fpc->nb_headers_buffered--;
}
/* Release returned data from ring buffer. */
av_fifo_drain(fpc->fifo_buf, best_child->offset);
/* Fix the offset for the headers remaining to match the new buffer. */
for (curr = best_child->next; curr; curr = curr->next)
curr->offset -= best_child->offset;
fpc->nb_headers_buffered--;
best_child->offset = 0;
fpc->headers = best_child;
if (fpc->nb_headers_buffered >= FLAC_MIN_HEADERS) {
fpc->best_header = best_child;
return get_best_header(fpc, poutbuf, poutbuf_size);
}
fpc->best_header = NULL;
} else if (fpc->best_header) {
/* No end frame no need to delete the buffer; probably eof */
FLACHeaderMarker *temp;
for (curr = fpc->headers; curr != fpc->best_header; curr = temp) {
temp = curr->next;
av_freep(&curr->link_penalty);
av_free(curr);
}
fpc->headers = fpc->best_header->next;
av_freep(&fpc->best_header->link_penalty);
av_freep(&fpc->best_header);
}
/* Find and score new headers. */
/* buf_size is to zero when padding, so check for this since we do */
/* not want to try to read more input once we have found the end. */
/* Note that as (non-modified) parameters, buf can be non-NULL, */
/* while buf_size is 0. */
while ((buf && buf_size && read_end < buf + buf_size &&
fpc->nb_headers_buffered < FLAC_MIN_HEADERS)
|| ((!buf || !buf_size) && !fpc->end_padded)) {
int start_offset;
/* Pad the end once if EOF, to check the final region for headers. */
if (!buf || !buf_size) {
fpc->end_padded = 1;
buf_size = MAX_FRAME_HEADER_SIZE;
read_end = read_start + MAX_FRAME_HEADER_SIZE;
} else {
/* The maximum read size is the upper-bound of what the parser
needs to have the required number of frames buffered */
int nb_desired = FLAC_MIN_HEADERS - fpc->nb_headers_buffered + 1;
read_end = read_end + FFMIN(buf + buf_size - read_end,
nb_desired * FLAC_AVG_FRAME_SIZE);
}
if (!av_fifo_space(fpc->fifo_buf) &&
av_fifo_size(fpc->fifo_buf) / FLAC_AVG_FRAME_SIZE >
fpc->nb_headers_buffered * 20) {
/* There is less than one valid flac header buffered for 20 headers
* buffered. Therefore the fifo is most likely filled with invalid
* data and the input is not a flac file. */
goto handle_error;
}
/* Fill the buffer. */
if ( av_fifo_space(fpc->fifo_buf) < read_end - read_start
&& av_fifo_realloc2(fpc->fifo_buf, (read_end - read_start) + 2*av_fifo_size(fpc->fifo_buf)) < 0) {
av_log(avctx, AV_LOG_ERROR,
"couldn't reallocate buffer of size %"PTRDIFF_SPECIFIER"\n",
(read_end - read_start) + av_fifo_size(fpc->fifo_buf));
goto handle_error;
}
if (buf && buf_size) {
av_fifo_generic_write(fpc->fifo_buf, (void*) read_start,
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);
}
/* Tag headers and update sequences. */
start_offset = av_fifo_size(fpc->fifo_buf) -
((read_end - read_start) + (MAX_FRAME_HEADER_SIZE - 1));
start_offset = FFMAX(0, start_offset);
nb_headers = find_new_headers(fpc, start_offset);
if (nb_headers < 0) {
av_log(avctx, AV_LOG_ERROR,
"find_new_headers couldn't allocate FLAC header\n");
goto handle_error;
}
fpc->nb_headers_buffered = nb_headers;
/* Wait till FLAC_MIN_HEADERS to output a valid frame. */
if (!fpc->end_padded && fpc->nb_headers_buffered < FLAC_MIN_HEADERS) {
if (buf && read_end < buf + buf_size) {
read_start = read_end;
continue;
} else {
goto handle_error;
}
}
/* If headers found, update the scores since we have longer chains. */
if (fpc->end_padded || fpc->nb_headers_found)
score_sequences(fpc);
/* restore the state pre-padding */
if (fpc->end_padded) {
int warp = fpc->fifo_buf->wptr - fpc->fifo_buf->buffer < MAX_FRAME_HEADER_SIZE;
/* HACK: drain the tail of the fifo */
fpc->fifo_buf->wptr -= MAX_FRAME_HEADER_SIZE;
fpc->fifo_buf->wndx -= MAX_FRAME_HEADER_SIZE;
if (warp) {
fpc->fifo_buf->wptr += fpc->fifo_buf->end -
fpc->fifo_buf->buffer;
}
buf_size = 0;
read_start = read_end = NULL;
}
}
for (curr = fpc->headers; curr; curr = curr->next) {
if (curr->max_score > 0 &&
(!fpc->best_header || curr->max_score > fpc->best_header->max_score)) {
fpc->best_header = curr;
}
}
if (fpc->best_header) {
fpc->best_header_valid = 1;
if (fpc->best_header->offset > 0) {
/* Output a junk frame. */
av_log(avctx, AV_LOG_DEBUG, "Junk frame till offset %i\n",
fpc->best_header->offset);
/* Set duration to 0. It is unknown or invalid in a junk frame. */
s->duration = 0;
*poutbuf_size = fpc->best_header->offset;
*poutbuf = flac_fifo_read_wrap(fpc, 0, *poutbuf_size,
&fpc->wrap_buf,
&fpc->wrap_buf_allocated_size);
return buf_size ? (read_end - buf) : (fpc->best_header->offset -
av_fifo_size(fpc->fifo_buf));
}
if (!buf_size)
return get_best_header(fpc, poutbuf, poutbuf_size);
}
handle_error:
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size ? read_end - buf : 0;
}
static av_cold int flac_parse_init(AVCodecParserContext *c)
{
FLACParseContext *fpc = c->priv_data;
fpc->pc = c;
/* There will generally be FLAC_MIN_HEADERS buffered in the fifo before
it drains. This is allocated early to avoid slow reallocation. */
fpc->fifo_buf = av_fifo_alloc_array(FLAC_MIN_HEADERS + 3, FLAC_AVG_FRAME_SIZE);
if (!fpc->fifo_buf) {
av_log(fpc->avctx, AV_LOG_ERROR,
"couldn't allocate fifo_buf\n");
return AVERROR(ENOMEM);
}
return 0;
}
static void flac_parse_close(AVCodecParserContext *c)
{
FLACParseContext *fpc = c->priv_data;
FLACHeaderMarker *curr = fpc->headers, *temp;
while (curr) {
temp = curr->next;
av_freep(&curr->link_penalty);
av_free(curr);
curr = temp;
}
av_fifo_freep(&fpc->fifo_buf);
av_freep(&fpc->wrap_buf);
}
AVCodecParser ff_flac_parser = {
.codec_ids = { AV_CODEC_ID_FLAC },
.priv_data_size = sizeof(FLACParseContext),
.parser_init = flac_parse_init,
.parser_parse = flac_parse,
.parser_close = flac_parse_close,
};

View file

@ -0,0 +1,33 @@
/*
* FLAC data
* Copyright (c) 2003 Alex Beregszaszi
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "internal.h"
const int ff_flac_sample_rate_table[16] =
{ 0,
88200, 176400, 192000,
8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
0, 0, 0, 0 };
const int32_t ff_flac_blocksize_table[16] = {
0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0,
256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7
};

View file

@ -0,0 +1,31 @@
/*
* FLAC data header
* Copyright (c) 2003 Alex Beregszaszi
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_FLACDATA_H
#define AVCODEC_FLACDATA_H
#include "internal.h"
extern const int ff_flac_sample_rate_table[16];
extern const int32_t ff_flac_blocksize_table[16];
#endif /* AVCODEC_FLACDATA_H */

View file

@ -0,0 +1,677 @@
/*
* FLAC (Free Lossless Audio Codec) decoder
* Copyright (c) 2003 Alex Beregszaszi
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* FLAC (Free Lossless Audio Codec) decoder
* @author Alex Beregszaszi
* @see http://flac.sourceforge.net/
*
* This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed
* through, starting from the initial 'fLaC' signature; or by passing the
* 34-byte streaminfo structure through avctx->extradata[_size] followed
* by data starting with the 0xFFF8 marker.
*/
#include <limits.h>
#include "libavutil/avassert.h"
#include "libavutil/crc.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
#include "bytestream.h"
#include "golomb.h"
#include "flac.h"
#include "flacdata.h"
#include "flacdsp.h"
#include "thread.h"
#include "unary.h"
typedef struct FLACContext {
AVClass *class;
struct FLACStreaminfo flac_stream_info;
AVCodecContext *avctx; ///< parent AVCodecContext
GetBitContext gb; ///< GetBitContext initialized to start at the current frame
int blocksize; ///< number of samples in the current frame
int sample_shift; ///< shift required to make output samples 16-bit or 32-bit
int ch_mode; ///< channel decorrelation type in the current frame
int got_streaminfo; ///< indicates if the STREAMINFO has been read
int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples
uint8_t *decoded_buffer;
unsigned int decoded_buffer_size;
int buggy_lpc; ///< use workaround for old lavc encoded files
FLACDSPContext dsp;
} FLACContext;
static int allocate_buffers(FLACContext *s);
static void flac_set_bps(FLACContext *s)
{
enum AVSampleFormat req = s->avctx->request_sample_fmt;
int need32 = s->flac_stream_info.bps > 16;
int want32 = av_get_bytes_per_sample(req) > 2;
int planar = av_sample_fmt_is_planar(req);
if (need32 || want32) {
if (planar)
s->avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
else
s->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
s->sample_shift = 32 - s->flac_stream_info.bps;
} else {
if (planar)
s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
else
s->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
s->sample_shift = 16 - s->flac_stream_info.bps;
}
}
static av_cold int flac_decode_init(AVCodecContext *avctx)
{
enum FLACExtradataFormat format;
uint8_t *streaminfo;
int ret;
FLACContext *s = avctx->priv_data;
s->avctx = avctx;
/* for now, the raw FLAC header is allowed to be passed to the decoder as
frame data instead of extradata. */
if (!avctx->extradata)
return 0;
if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
return AVERROR_INVALIDDATA;
/* initialize based on the demuxer-supplied streamdata header */
ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
flac_set_bps(s);
ff_flacdsp_init(&s->dsp, avctx->sample_fmt,
s->flac_stream_info.channels, s->flac_stream_info.bps);
s->got_streaminfo = 1;
return 0;
}
static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s)
{
av_log(avctx, AV_LOG_DEBUG, " Max Blocksize: %d\n", s->max_blocksize);
av_log(avctx, AV_LOG_DEBUG, " Max Framesize: %d\n", s->max_framesize);
av_log(avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate);
av_log(avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels);
av_log(avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps);
}
static int allocate_buffers(FLACContext *s)
{
int buf_size;
int ret;
av_assert0(s->flac_stream_info.max_blocksize);
buf_size = av_samples_get_buffer_size(NULL, s->flac_stream_info.channels,
s->flac_stream_info.max_blocksize,
AV_SAMPLE_FMT_S32P, 0);
if (buf_size < 0)
return buf_size;
av_fast_malloc(&s->decoded_buffer, &s->decoded_buffer_size, buf_size);
if (!s->decoded_buffer)
return AVERROR(ENOMEM);
ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
s->decoded_buffer,
s->flac_stream_info.channels,
s->flac_stream_info.max_blocksize,
AV_SAMPLE_FMT_S32P, 0);
return ret < 0 ? ret : 0;
}
/**
* Parse the STREAMINFO from an inline header.
* @param s the flac decoding context
* @param buf input buffer, starting with the "fLaC" marker
* @param buf_size buffer size
* @return non-zero if metadata is invalid
*/
static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
{
int metadata_type, metadata_size, ret;
if (buf_size < FLAC_STREAMINFO_SIZE+8) {
/* need more data */
return 0;
}
flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size);
if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO ||
metadata_size != FLAC_STREAMINFO_SIZE) {
return AVERROR_INVALIDDATA;
}
ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
flac_set_bps(s);
ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
s->flac_stream_info.channels, s->flac_stream_info.bps);
s->got_streaminfo = 1;
return 0;
}
/**
* Determine the size of an inline header.
* @param buf input buffer, starting with the "fLaC" marker
* @param buf_size buffer size
* @return number of bytes in the header, or 0 if more data is needed
*/
static int get_metadata_size(const uint8_t *buf, int buf_size)
{
int metadata_last, metadata_size;
const uint8_t *buf_end = buf + buf_size;
buf += 4;
do {
if (buf_end - buf < 4)
return 0;
flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
buf += 4;
if (buf_end - buf < metadata_size) {
/* need more data in order to read the complete header */
return 0;
}
buf += metadata_size;
} while (!metadata_last);
return buf_size - (buf_end - buf);
}
static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order)
{
int i, tmp, partition, method_type, rice_order;
int rice_bits, rice_esc;
int samples;
method_type = get_bits(&s->gb, 2);
if (method_type > 1) {
av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n",
method_type);
return AVERROR_INVALIDDATA;
}
rice_order = get_bits(&s->gb, 4);
samples= s->blocksize >> rice_order;
if (samples << rice_order != s->blocksize) {
av_log(s->avctx, AV_LOG_ERROR, "invalid rice order: %i blocksize %i\n",
rice_order, s->blocksize);
return AVERROR_INVALIDDATA;
}
if (pred_order > samples) {
av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n",
pred_order, samples);
return AVERROR_INVALIDDATA;
}
rice_bits = 4 + method_type;
rice_esc = (1 << rice_bits) - 1;
decoded += pred_order;
i= pred_order;
for (partition = 0; partition < (1 << rice_order); partition++) {
tmp = get_bits(&s->gb, rice_bits);
if (tmp == rice_esc) {
tmp = get_bits(&s->gb, 5);
for (; i < samples; i++)
*decoded++ = get_sbits_long(&s->gb, tmp);
} else {
for (; i < samples; i++) {
*decoded++ = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0);
}
}
i= 0;
}
return 0;
}
static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
int pred_order, int bps)
{
const int blocksize = s->blocksize;
int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i;
int ret;
/* warm up samples */
for (i = 0; i < pred_order; i++) {
decoded[i] = get_sbits_long(&s->gb, bps);
}
if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
return ret;
if (pred_order > 0)
a = decoded[pred_order-1];
if (pred_order > 1)
b = a - decoded[pred_order-2];
if (pred_order > 2)
c = b - decoded[pred_order-2] + decoded[pred_order-3];
if (pred_order > 3)
d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4];
switch (pred_order) {
case 0:
break;
case 1:
for (i = pred_order; i < blocksize; i++)
decoded[i] = a += decoded[i];
break;
case 2:
for (i = pred_order; i < blocksize; i++)
decoded[i] = a += b += decoded[i];
break;
case 3:
for (i = pred_order; i < blocksize; i++)
decoded[i] = a += b += c += decoded[i];
break;
case 4:
for (i = pred_order; i < blocksize; i++)
decoded[i] = a += b += c += d += decoded[i];
break;
default:
av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order);
return AVERROR_INVALIDDATA;
}
return 0;
}
static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32],
int order, int qlevel, int len, int bps)
{
int i, j;
int ebps = 1 << (bps-1);
unsigned sigma = 0;
for (i = order; i < len; i++)
sigma |= decoded[i] + ebps;
if (sigma < 2*ebps)
return;
for (i = len - 1; i >= order; i--) {
int64_t p = 0;
for (j = 0; j < order; j++)
p += coeffs[j] * (int64_t)decoded[i-order+j];
decoded[i] -= p >> qlevel;
}
for (i = order; i < len; i++, decoded++) {
int32_t p = 0;
for (j = 0; j < order; j++)
p += coeffs[j] * (uint32_t)decoded[j];
decoded[j] += p >> qlevel;
}
}
static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
int bps)
{
int i, ret;
int coeff_prec, qlevel;
int coeffs[32];
/* warm up samples */
for (i = 0; i < pred_order; i++) {
decoded[i] = get_sbits_long(&s->gb, bps);
}
coeff_prec = get_bits(&s->gb, 4) + 1;
if (coeff_prec == 16) {
av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n");
return AVERROR_INVALIDDATA;
}
qlevel = get_sbits(&s->gb, 5);
if (qlevel < 0) {
av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n",
qlevel);
return AVERROR_INVALIDDATA;
}
for (i = 0; i < pred_order; i++) {
coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec);
}
if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
return ret;
if ( ( s->buggy_lpc && s->flac_stream_info.bps <= 16)
|| ( !s->buggy_lpc && bps <= 16
&& bps + coeff_prec + av_log2(pred_order) <= 32)) {
s->dsp.lpc16(decoded, coeffs, pred_order, qlevel, s->blocksize);
} else {
s->dsp.lpc32(decoded, coeffs, pred_order, qlevel, s->blocksize);
if (s->flac_stream_info.bps <= 16)
lpc_analyze_remodulate(decoded, coeffs, pred_order, qlevel, s->blocksize, bps);
}
return 0;
}
static inline int decode_subframe(FLACContext *s, int channel)
{
int32_t *decoded = s->decoded[channel];
int type, wasted = 0;
int bps = s->flac_stream_info.bps;
int i, tmp, ret;
if (channel == 0) {
if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE)
bps++;
} else {
if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE)
bps++;
}
if (get_bits1(&s->gb)) {
av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n");
return AVERROR_INVALIDDATA;
}
type = get_bits(&s->gb, 6);
if (get_bits1(&s->gb)) {
int left = get_bits_left(&s->gb);
if ( left <= 0 ||
(left < bps && !show_bits_long(&s->gb, left)) ||
!show_bits_long(&s->gb, bps)) {
av_log(s->avctx, AV_LOG_ERROR,
"Invalid number of wasted bits > available bits (%d) - left=%d\n",
bps, left);
return AVERROR_INVALIDDATA;
}
wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb));
bps -= wasted;
}
if (bps > 32) {
avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32");
return AVERROR_PATCHWELCOME;
}
//FIXME use av_log2 for types
if (type == 0) {
tmp = get_sbits_long(&s->gb, bps);
for (i = 0; i < s->blocksize; i++)
decoded[i] = tmp;
} else if (type == 1) {
for (i = 0; i < s->blocksize; i++)
decoded[i] = get_sbits_long(&s->gb, bps);
} else if ((type >= 8) && (type <= 12)) {
if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0)
return ret;
} else if (type >= 32) {
if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0)
return ret;
} else {
av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n");
return AVERROR_INVALIDDATA;
}
if (wasted) {
int i;
for (i = 0; i < s->blocksize; i++)
decoded[i] <<= wasted;
}
return 0;
}
static int decode_frame(FLACContext *s)
{
int i, ret;
GetBitContext *gb = &s->gb;
FLACFrameInfo fi;
if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) {
av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n");
return ret;
}
if ( s->flac_stream_info.channels
&& fi.channels != s->flac_stream_info.channels
&& s->got_streaminfo) {
s->flac_stream_info.channels = s->avctx->channels = fi.channels;
ff_flac_set_channel_layout(s->avctx);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
}
s->flac_stream_info.channels = s->avctx->channels = fi.channels;
if (!s->avctx->channel_layout)
ff_flac_set_channel_layout(s->avctx);
s->ch_mode = fi.ch_mode;
if (!s->flac_stream_info.bps && !fi.bps) {
av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n");
return AVERROR_INVALIDDATA;
}
if (!fi.bps) {
fi.bps = s->flac_stream_info.bps;
} else if (s->flac_stream_info.bps && fi.bps != s->flac_stream_info.bps) {
av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not "
"supported\n");
return AVERROR_INVALIDDATA;
}
if (!s->flac_stream_info.bps) {
s->flac_stream_info.bps = s->avctx->bits_per_raw_sample = fi.bps;
flac_set_bps(s);
}
if (!s->flac_stream_info.max_blocksize)
s->flac_stream_info.max_blocksize = FLAC_MAX_BLOCKSIZE;
if (fi.blocksize > s->flac_stream_info.max_blocksize) {
av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize,
s->flac_stream_info.max_blocksize);
return AVERROR_INVALIDDATA;
}
s->blocksize = fi.blocksize;
if (!s->flac_stream_info.samplerate && !fi.samplerate) {
av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO"
" or frame header\n");
return AVERROR_INVALIDDATA;
}
if (fi.samplerate == 0)
fi.samplerate = s->flac_stream_info.samplerate;
s->flac_stream_info.samplerate = s->avctx->sample_rate = fi.samplerate;
if (!s->got_streaminfo) {
ret = allocate_buffers(s);
if (ret < 0)
return ret;
s->got_streaminfo = 1;
dump_headers(s->avctx, &s->flac_stream_info);
}
ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
s->flac_stream_info.channels, s->flac_stream_info.bps);
// dump_headers(s->avctx, &s->flac_stream_info);
/* subframes */
for (i = 0; i < s->flac_stream_info.channels; i++) {
if ((ret = decode_subframe(s, i)) < 0)
return ret;
}
align_get_bits(gb);
/* frame footer */
skip_bits(gb, 16); /* data crc */
return 0;
}
static int flac_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame_ptr, AVPacket *avpkt)
{
AVFrame *frame = data;
ThreadFrame tframe = { .f = data };
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
FLACContext *s = avctx->priv_data;
int bytes_read = 0;
int ret;
*got_frame_ptr = 0;
if (s->flac_stream_info.max_framesize == 0) {
s->flac_stream_info.max_framesize =
ff_flac_get_max_frame_size(s->flac_stream_info.max_blocksize ? s->flac_stream_info.max_blocksize : FLAC_MAX_BLOCKSIZE,
FLAC_MAX_CHANNELS, 32);
}
if (buf_size > 5 && !memcmp(buf, "\177FLAC", 5)) {
av_log(s->avctx, AV_LOG_DEBUG, "skipping flac header packet 1\n");
return buf_size;
}
if (buf_size > 0 && (*buf & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
av_log(s->avctx, AV_LOG_DEBUG, "skipping vorbis comment\n");
return buf_size;
}
/* check that there is at least the smallest decodable amount of data.
this amount corresponds to the smallest valid FLAC frame possible.
FF F8 69 02 00 00 9A 00 00 34 46 */
if (buf_size < FLAC_MIN_FRAME_SIZE)
return buf_size;
/* check for inline header */
if (AV_RB32(buf) == MKBETAG('f','L','a','C')) {
if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) {
av_log(s->avctx, AV_LOG_ERROR, "invalid header\n");
return ret;
}
return get_metadata_size(buf, buf_size);
}
/* decode frame */
if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0)
return ret;
if ((ret = decode_frame(s)) < 0) {
av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");
return ret;
}
bytes_read = get_bits_count(&s->gb)/8;
if ((s->avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) &&
av_crc(av_crc_get_table(AV_CRC_16_ANSI),
0, buf, bytes_read)) {
av_log(s->avctx, AV_LOG_ERROR, "CRC error at PTS %"PRId64"\n", avpkt->pts);
if (s->avctx->err_recognition & AV_EF_EXPLODE)
return AVERROR_INVALIDDATA;
}
/* get output buffer */
frame->nb_samples = s->blocksize;
if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
return ret;
s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded,
s->flac_stream_info.channels,
s->blocksize, s->sample_shift);
if (bytes_read > buf_size) {
av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size);
return AVERROR_INVALIDDATA;
}
if (bytes_read < buf_size) {
av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n",
buf_size - bytes_read, buf_size);
}
*got_frame_ptr = 1;
return bytes_read;
}
#if HAVE_THREADS
static int init_thread_copy(AVCodecContext *avctx)
{
FLACContext *s = avctx->priv_data;
s->decoded_buffer = NULL;
s->decoded_buffer_size = 0;
s->avctx = avctx;
if (s->flac_stream_info.max_blocksize)
return allocate_buffers(s);
return 0;
}
#endif
static av_cold int flac_decode_close(AVCodecContext *avctx)
{
FLACContext *s = avctx->priv_data;
av_freep(&s->decoded_buffer);
return 0;
}
static const AVOption options[] = {
{ "use_buggy_lpc", "emulate old buggy lavc behavior", offsetof(FLACContext, buggy_lpc), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM },
{ NULL },
};
static const AVClass flac_decoder_class = {
"FLAC decoder",
av_default_item_name,
options,
LIBAVUTIL_VERSION_INT,
};
AVCodec ff_flac_decoder = {
.name = "flac",
.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_CODEC_ID_FLAC,
.priv_data_size = sizeof(FLACContext),
.init = flac_decode_init,
.close = flac_decode_close,
.decode = flac_decode_frame,
.init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_NONE },
.priv_class = &flac_decoder_class,
};

View file

@ -0,0 +1,130 @@
/*
* Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/attributes.h"
#include "libavutil/samplefmt.h"
#include "flacdsp.h"
#include "config.h"
#define SAMPLE_SIZE 16
#define PLANAR 0
#include "flacdsp_template.c"
#include "flacdsp_lpc_template.c"
#undef PLANAR
#define PLANAR 1
#include "flacdsp_template.c"
#undef SAMPLE_SIZE
#undef PLANAR
#define SAMPLE_SIZE 32
#define PLANAR 0
#include "flacdsp_template.c"
#include "flacdsp_lpc_template.c"
#undef PLANAR
#define PLANAR 1
#include "flacdsp_template.c"
static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32],
int pred_order, int qlevel, int len)
{
int i, j;
for (i = pred_order; i < len - 1; i += 2, decoded += 2) {
int c = coeffs[0];
int d = decoded[0];
int s0 = 0, s1 = 0;
for (j = 1; j < pred_order; j++) {
s0 += c*d;
d = decoded[j];
s1 += c*d;
c = coeffs[j];
}
s0 += c*d;
d = decoded[j] += s0 >> qlevel;
s1 += c*d;
decoded[j + 1] += s1 >> qlevel;
}
if (i < len) {
int sum = 0;
for (j = 0; j < pred_order; j++)
sum += coeffs[j] * decoded[j];
decoded[j] += sum >> qlevel;
}
}
static void flac_lpc_32_c(int32_t *decoded, const int coeffs[32],
int pred_order, int qlevel, int len)
{
int i, j;
for (i = pred_order; i < len; i++, decoded++) {
int64_t sum = 0;
for (j = 0; j < pred_order; j++)
sum += (int64_t)coeffs[j] * decoded[j];
decoded[j] += sum >> qlevel;
}
}
av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels,
int bps)
{
c->lpc16 = flac_lpc_16_c;
c->lpc32 = flac_lpc_32_c;
c->lpc16_encode = flac_lpc_encode_c_16;
c->lpc32_encode = flac_lpc_encode_c_32;
switch (fmt) {
case AV_SAMPLE_FMT_S32:
c->decorrelate[0] = flac_decorrelate_indep_c_32;
c->decorrelate[1] = flac_decorrelate_ls_c_32;
c->decorrelate[2] = flac_decorrelate_rs_c_32;
c->decorrelate[3] = flac_decorrelate_ms_c_32;
break;
case AV_SAMPLE_FMT_S32P:
c->decorrelate[0] = flac_decorrelate_indep_c_32p;
c->decorrelate[1] = flac_decorrelate_ls_c_32p;
c->decorrelate[2] = flac_decorrelate_rs_c_32p;
c->decorrelate[3] = flac_decorrelate_ms_c_32p;
break;
case AV_SAMPLE_FMT_S16:
c->decorrelate[0] = flac_decorrelate_indep_c_16;
c->decorrelate[1] = flac_decorrelate_ls_c_16;
c->decorrelate[2] = flac_decorrelate_rs_c_16;
c->decorrelate[3] = flac_decorrelate_ms_c_16;
break;
case AV_SAMPLE_FMT_S16P:
c->decorrelate[0] = flac_decorrelate_indep_c_16p;
c->decorrelate[1] = flac_decorrelate_ls_c_16p;
c->decorrelate[2] = flac_decorrelate_rs_c_16p;
c->decorrelate[3] = flac_decorrelate_ms_c_16p;
break;
}
if (ARCH_ARM)
ff_flacdsp_init_arm(c, fmt, channels, bps);
if (ARCH_X86)
ff_flacdsp_init_x86(c, fmt, channels, bps);
}

View file

@ -0,0 +1,42 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_FLACDSP_H
#define AVCODEC_FLACDSP_H
#include <stdint.h>
#include "libavutil/samplefmt.h"
typedef struct FLACDSPContext {
void (*decorrelate[4])(uint8_t **out, int32_t **in, int channels,
int len, int shift);
void (*lpc16)(int32_t *samples, const int coeffs[32], int order,
int qlevel, int len);
void (*lpc32)(int32_t *samples, const int coeffs[32], int order,
int qlevel, int len);
void (*lpc16_encode)(int32_t *res, const int32_t *smp, int len, int order,
const int32_t coefs[32], int shift);
void (*lpc32_encode)(int32_t *res, const int32_t *smp, int len, int order,
const int32_t coefs[32], int shift);
} FLACDSPContext;
void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
#endif /* AVCODEC_FLACDSP_H */

View file

@ -0,0 +1,159 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "libavutil/avutil.h"
#include "mathops.h"
#undef FUNC
#undef sum_type
#undef MUL
#undef CLIP
#undef FSUF
#define FUNC(n) AV_JOIN(n ## _, SAMPLE_SIZE)
#if SAMPLE_SIZE == 32
# define sum_type int64_t
# define MUL(a, b) MUL64(a, b)
# define CLIP(x) av_clipl_int32(x)
#else
# define sum_type int32_t
# define MUL(a, b) ((a) * (b))
# define CLIP(x) (x)
#endif
#define LPC1(x) { \
int c = coefs[(x)-1]; \
p0 += MUL(c, s); \
s = smp[i-(x)+1]; \
p1 += MUL(c, s); \
}
static av_always_inline void FUNC(lpc_encode_unrolled)(int32_t *res,
const int32_t *smp, int len, int order,
const int32_t *coefs, int shift, int big)
{
int i;
for (i = order; i < len; i += 2) {
int s = smp[i-order];
sum_type p0 = 0, p1 = 0;
if (big) {
switch (order) {
case 32: LPC1(32)
case 31: LPC1(31)
case 30: LPC1(30)
case 29: LPC1(29)
case 28: LPC1(28)
case 27: LPC1(27)
case 26: LPC1(26)
case 25: LPC1(25)
case 24: LPC1(24)
case 23: LPC1(23)
case 22: LPC1(22)
case 21: LPC1(21)
case 20: LPC1(20)
case 19: LPC1(19)
case 18: LPC1(18)
case 17: LPC1(17)
case 16: LPC1(16)
case 15: LPC1(15)
case 14: LPC1(14)
case 13: LPC1(13)
case 12: LPC1(12)
case 11: LPC1(11)
case 10: LPC1(10)
case 9: LPC1( 9)
LPC1( 8)
LPC1( 7)
LPC1( 6)
LPC1( 5)
LPC1( 4)
LPC1( 3)
LPC1( 2)
LPC1( 1)
}
} else {
switch (order) {
case 8: LPC1( 8)
case 7: LPC1( 7)
case 6: LPC1( 6)
case 5: LPC1( 5)
case 4: LPC1( 4)
case 3: LPC1( 3)
case 2: LPC1( 2)
case 1: LPC1( 1)
}
}
res[i ] = smp[i ] - CLIP(p0 >> shift);
res[i+1] = smp[i+1] - CLIP(p1 >> shift);
}
}
static void FUNC(flac_lpc_encode_c)(int32_t *res, const int32_t *smp, int len,
int order, const int32_t *coefs, int shift)
{
int i;
for (i = 0; i < order; i++)
res[i] = smp[i];
#if CONFIG_SMALL
for (i = order; i < len; i += 2) {
int j;
int s = smp[i];
sum_type p0 = 0, p1 = 0;
for (j = 0; j < order; j++) {
int c = coefs[j];
p1 += MUL(c, s);
s = smp[i-j-1];
p0 += MUL(c, s);
}
res[i ] = smp[i ] - CLIP(p0 >> shift);
res[i+1] = smp[i+1] - CLIP(p1 >> shift);
}
#else
switch (order) {
case 1: FUNC(lpc_encode_unrolled)(res, smp, len, 1, coefs, shift, 0); break;
case 2: FUNC(lpc_encode_unrolled)(res, smp, len, 2, coefs, shift, 0); break;
case 3: FUNC(lpc_encode_unrolled)(res, smp, len, 3, coefs, shift, 0); break;
case 4: FUNC(lpc_encode_unrolled)(res, smp, len, 4, coefs, shift, 0); break;
case 5: FUNC(lpc_encode_unrolled)(res, smp, len, 5, coefs, shift, 0); break;
case 6: FUNC(lpc_encode_unrolled)(res, smp, len, 6, coefs, shift, 0); break;
case 7: FUNC(lpc_encode_unrolled)(res, smp, len, 7, coefs, shift, 0); break;
case 8: FUNC(lpc_encode_unrolled)(res, smp, len, 8, coefs, shift, 0); break;
default: FUNC(lpc_encode_unrolled)(res, smp, len, order, coefs, shift, 1); break;
}
#endif
}
/* Comment for clarity/de-obfuscation.
*
* for (int i = order; i < len; i++) {
* int32_t p = 0;
* for (int j = 0; j < order; j++) {
* int c = coefs[j];
* int s = smp[(i-1)-j];
* p += c*s;
* }
* res[i] = smp[i] - (p >> shift);
* }
*
* The CONFIG_SMALL code above simplifies to this, in the case of SAMPLE_SIZE
* not being equal to 32 (at the present time that means for 16-bit audio). The
* code above does 2 samples per iteration. Commit bfdd5bc (made all the way
* back in 2007) says that way is faster.
*/

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "libavutil/avutil.h"
#undef FUNC
#undef FSUF
#undef sample
#undef sample_type
#undef OUT
#undef S
#if SAMPLE_SIZE == 32
# define sample_type int32_t
#else
# define sample_type int16_t
#endif
#if PLANAR
# define FSUF AV_JOIN(SAMPLE_SIZE, p)
# define sample sample_type *
# define OUT(n) n
# define S(s, c, i) (s[c][i])
#else
# define FSUF SAMPLE_SIZE
# define sample sample_type
# define OUT(n) n[0]
# define S(s, c, i) (*s++)
#endif
#define FUNC(n) AV_JOIN(n ## _, FSUF)
static void FUNC(flac_decorrelate_indep_c)(uint8_t **out, int32_t **in,
int channels, int len, int shift)
{
sample *samples = (sample *) OUT(out);
int i, j;
for (j = 0; j < len; j++)
for (i = 0; i < channels; i++)
S(samples, i, j) = in[i][j] << shift;
}
static void FUNC(flac_decorrelate_ls_c)(uint8_t **out, int32_t **in,
int channels, int len, int shift)
{
sample *samples = (sample *) OUT(out);
int i;
for (i = 0; i < len; i++) {
int a = in[0][i];
int b = in[1][i];
S(samples, 0, i) = a << shift;
S(samples, 1, i) = (a - b) << shift;
}
}
static void FUNC(flac_decorrelate_rs_c)(uint8_t **out, int32_t **in,
int channels, int len, int shift)
{
sample *samples = (sample *) OUT(out);
int i;
for (i = 0; i < len; i++) {
int a = in[0][i];
int b = in[1][i];
S(samples, 0, i) = (a + b) << shift;
S(samples, 1, i) = b << shift;
}
}
static void FUNC(flac_decorrelate_ms_c)(uint8_t **out, int32_t **in,
int channels, int len, int shift)
{
sample *samples = (sample *) OUT(out);
int i;
for (i = 0; i < len; i++) {
int a = in[0][i];
int b = in[1][i];
a -= b >> 1;
S(samples, 0, i) = (a + b) << shift;
S(samples, 1, i) = a << shift;
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2012 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_FRAME_THREAD_ENCODER_H
#define AVCODEC_FRAME_THREAD_ENCODER_H
#include "avcodec.h"
int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options);
void ff_frame_thread_encoder_free(AVCodecContext *avctx);
int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr);
#endif /* AVCODEC_FRAME_THREAD_ENCODER_H */

View file

@ -0,0 +1,587 @@
/*
* copyright (c) 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
*/
/**
* @file
* bitstream reader API header.
*/
#ifndef AVCODEC_GET_BITS_H
#define AVCODEC_GET_BITS_H
#include <stdint.h>
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/avassert.h"
#include "mathops.h"
#include "vlc.h"
/*
* Safe bitstream reading:
* optionally, the get_bits API can check to ensure that we
* don't read past input buffer boundaries. This is protected
* with CONFIG_SAFE_BITSTREAM_READER at the global level, and
* then below that with UNCHECKED_BITSTREAM_READER at the per-
* decoder level. This means that decoders that check internally
* can "#define UNCHECKED_BITSTREAM_READER 1" to disable
* overread checks.
* Boundary checking causes a minor performance penalty so for
* applications that won't want/need this, it can be disabled
* globally using "#define CONFIG_SAFE_BITSTREAM_READER 0".
*/
#ifndef UNCHECKED_BITSTREAM_READER
#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER
#endif
typedef struct GetBitContext {
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits;
int size_in_bits_plus8;
} GetBitContext;
/* Bitstream reader API docs:
* name
* arbitrary name which is used as prefix for the internal variables
*
* gb
* getbitcontext
*
* OPEN_READER(name, gb)
* load gb into local variables
*
* CLOSE_READER(name, gb)
* store local vars in gb
*
* UPDATE_CACHE(name, gb)
* Refill the internal cache from the bitstream.
* After this call at least MIN_CACHE_BITS will be available.
*
* GET_CACHE(name, gb)
* Will output the contents of the internal cache,
* next bit is MSB of 32 or 64 bits (FIXME 64 bits).
*
* SHOW_UBITS(name, gb, num)
* Will return the next num bits.
*
* SHOW_SBITS(name, gb, num)
* Will return the next num bits and do sign extension.
*
* SKIP_BITS(name, gb, num)
* Will skip over the next num bits.
* Note, this is equivalent to SKIP_CACHE; SKIP_COUNTER.
*
* SKIP_CACHE(name, gb, num)
* Will remove the next num bits from the cache (note SKIP_COUNTER
* MUST be called before UPDATE_CACHE / CLOSE_READER).
*
* SKIP_COUNTER(name, gb, num)
* Will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS).
*
* LAST_SKIP_BITS(name, gb, num)
* Like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER.
*
* BITS_LEFT(name, gb)
* Return the number of bits left
*
* For examples see get_bits, show_bits, skip_bits, get_vlc.
*/
#ifdef LONG_BITSTREAM_READER
# define MIN_CACHE_BITS 32
#else
# define MIN_CACHE_BITS 25
#endif
#define OPEN_READER_NOSIZE(name, gb) \
unsigned int name ## _index = (gb)->index; \
unsigned int av_unused name ## _cache
#if UNCHECKED_BITSTREAM_READER
#define OPEN_READER(name, gb) OPEN_READER_NOSIZE(name, gb)
#define BITS_AVAILABLE(name, gb) 1
#else
#define OPEN_READER(name, gb) \
OPEN_READER_NOSIZE(name, gb); \
unsigned int name ## _size_plus8 = (gb)->size_in_bits_plus8
#define BITS_AVAILABLE(name, gb) name ## _index < name ## _size_plus8
#endif
#define CLOSE_READER(name, gb) (gb)->index = name ## _index
# ifdef LONG_BITSTREAM_READER
# define UPDATE_CACHE_LE(name, gb) name ## _cache = \
AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
# define UPDATE_CACHE_BE(name, gb) name ## _cache = \
AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7))
#else
# define UPDATE_CACHE_LE(name, gb) name ## _cache = \
AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
# define UPDATE_CACHE_BE(name, gb) name ## _cache = \
AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7)
#endif
#ifdef BITSTREAM_READER_LE
# define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb)
# define SKIP_CACHE(name, gb, num) name ## _cache >>= (num)
#else
# define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb)
# define SKIP_CACHE(name, gb, num) name ## _cache <<= (num)
#endif
#if UNCHECKED_BITSTREAM_READER
# define SKIP_COUNTER(name, gb, num) name ## _index += (num)
#else
# define SKIP_COUNTER(name, gb, num) \
name ## _index = FFMIN(name ## _size_plus8, name ## _index + (num))
#endif
#define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name ## _index))
#define SKIP_BITS(name, gb, num) \
do { \
SKIP_CACHE(name, gb, num); \
SKIP_COUNTER(name, gb, num); \
} while (0)
#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
#define SHOW_UBITS_LE(name, gb, num) zero_extend(name ## _cache, num)
#define SHOW_SBITS_LE(name, gb, num) sign_extend(name ## _cache, num)
#define SHOW_UBITS_BE(name, gb, num) NEG_USR32(name ## _cache, num)
#define SHOW_SBITS_BE(name, gb, num) NEG_SSR32(name ## _cache, num)
#ifdef BITSTREAM_READER_LE
# define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num)
# define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num)
#else
# define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num)
# define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num)
#endif
#define GET_CACHE(name, gb) ((uint32_t) name ## _cache)
static inline int get_bits_count(const GetBitContext *s)
{
return s->index;
}
static inline void skip_bits_long(GetBitContext *s, int n)
{
#if UNCHECKED_BITSTREAM_READER
s->index += n;
#else
s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index);
#endif
}
/**
* Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB).
* if MSB not set it is negative
* @param n length in bits
*/
static inline int get_xbits(GetBitContext *s, int n)
{
register int sign;
register int32_t cache;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
cache = GET_CACHE(re, s);
sign = ~cache >> 31;
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
}
static inline int get_sbits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_SBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
/**
* Read 1-25 bits.
*/
static inline unsigned int get_bits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_UBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
/**
* Read 0-25 bits.
*/
static av_always_inline int get_bitsz(GetBitContext *s, int n)
{
return n ? get_bits(s, n) : 0;
}
static inline unsigned int get_bits_le(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE_LE(re, s);
tmp = SHOW_UBITS_LE(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
/**
* Show 1-25 bits.
*/
static inline unsigned int show_bits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER_NOSIZE(re, s);
av_assert2(n>0 && n<=25);
UPDATE_CACHE(re, s);
tmp = SHOW_UBITS(re, s, n);
return tmp;
}
static inline void skip_bits(GetBitContext *s, int n)
{
OPEN_READER(re, s);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
}
static inline unsigned int get_bits1(GetBitContext *s)
{
unsigned int index = s->index;
uint8_t result = s->buffer[index >> 3];
#ifdef BITSTREAM_READER_LE
result >>= index & 7;
result &= 1;
#else
result <<= index & 7;
result >>= 8 - 1;
#endif
#if !UNCHECKED_BITSTREAM_READER
if (s->index < s->size_in_bits_plus8)
#endif
index++;
s->index = index;
return result;
}
static inline unsigned int show_bits1(GetBitContext *s)
{
return show_bits(s, 1);
}
static inline void skip_bits1(GetBitContext *s)
{
skip_bits(s, 1);
}
/**
* Read 0-32 bits.
*/
static inline unsigned int get_bits_long(GetBitContext *s, int n)
{
if (!n) {
return 0;
} else if (n <= MIN_CACHE_BITS) {
return get_bits(s, n);
} else {
#ifdef BITSTREAM_READER_LE
unsigned ret = get_bits(s, 16);
return ret | (get_bits(s, n - 16) << 16);
#else
unsigned ret = get_bits(s, 16) << (n - 16);
return ret | get_bits(s, n - 16);
#endif
}
}
/**
* Read 0-64 bits.
*/
static inline uint64_t get_bits64(GetBitContext *s, int n)
{
if (n <= 32) {
return get_bits_long(s, n);
} else {
#ifdef BITSTREAM_READER_LE
uint64_t ret = get_bits_long(s, 32);
return ret | (uint64_t) get_bits_long(s, n - 32) << 32;
#else
uint64_t ret = (uint64_t) get_bits_long(s, n - 32) << 32;
return ret | get_bits_long(s, 32);
#endif
}
}
/**
* Read 0-32 bits as a signed integer.
*/
static inline int get_sbits_long(GetBitContext *s, int n)
{
return sign_extend(get_bits_long(s, n), n);
}
/**
* Show 0-32 bits.
*/
static inline unsigned int show_bits_long(GetBitContext *s, int n)
{
if (n <= MIN_CACHE_BITS) {
return show_bits(s, n);
} else {
GetBitContext gb = *s;
return get_bits_long(&gb, n);
}
}
static inline int check_marker(void *logctx, GetBitContext *s, const char *msg)
{
int bit = get_bits1(s);
if (!bit)
av_log(logctx, AV_LOG_INFO, "Marker bit missing at %d of %d %s\n",
get_bits_count(s) - 1, s->size_in_bits, msg);
return bit;
}
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
* @param bit_size the size of the buffer in bits
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
int bit_size)
{
int buffer_size;
int ret = 0;
if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer) {
bit_size = 0;
buffer = NULL;
ret = AVERROR_INVALIDDATA;
}
buffer_size = (bit_size + 7) >> 3;
s->buffer = buffer;
s->size_in_bits = bit_size;
s->size_in_bits_plus8 = bit_size + 8;
s->buffer_end = buffer + buffer_size;
s->index = 0;
return ret;
}
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
* @param byte_size the size of the buffer in bytes
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer,
int byte_size)
{
if (byte_size > INT_MAX / 8 || byte_size < 0)
byte_size = -1;
return init_get_bits(s, buffer, byte_size * 8);
}
static inline const uint8_t *align_get_bits(GetBitContext *s)
{
int n = -get_bits_count(s) & 7;
if (n)
skip_bits(s, n);
return s->buffer + (s->index >> 3);
}
/**
* If the vlc code is invalid and max_depth=1, then no bits will be removed.
* If the vlc code is invalid and max_depth>1, then the number of bits removed
* is undefined.
*/
#define GET_VLC(code, name, gb, table, bits, max_depth) \
do { \
int n, nb_bits; \
unsigned int index; \
\
index = SHOW_UBITS(name, gb, bits); \
code = table[index][0]; \
n = table[index][1]; \
\
if (max_depth > 1 && n < 0) { \
LAST_SKIP_BITS(name, gb, bits); \
UPDATE_CACHE(name, gb); \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + code; \
code = table[index][0]; \
n = table[index][1]; \
if (max_depth > 2 && n < 0) { \
LAST_SKIP_BITS(name, gb, nb_bits); \
UPDATE_CACHE(name, gb); \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + code; \
code = table[index][0]; \
n = table[index][1]; \
} \
} \
SKIP_BITS(name, gb, n); \
} while (0)
#define GET_RL_VLC(level, run, name, gb, table, bits, \
max_depth, need_update) \
do { \
int n, nb_bits; \
unsigned int index; \
\
index = SHOW_UBITS(name, gb, bits); \
level = table[index].level; \
n = table[index].len; \
\
if (max_depth > 1 && n < 0) { \
SKIP_BITS(name, gb, bits); \
if (need_update) { \
UPDATE_CACHE(name, gb); \
} \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + level; \
level = table[index].level; \
n = table[index].len; \
if (max_depth > 2 && n < 0) { \
LAST_SKIP_BITS(name, gb, nb_bits); \
if (need_update) { \
UPDATE_CACHE(name, gb); \
} \
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + level; \
level = table[index].level; \
n = table[index].len; \
} \
} \
run = table[index].run; \
SKIP_BITS(name, gb, n); \
} while (0)
/**
* Parse a vlc code.
* @param bits is the number of bits which will be read at once, must be
* identical to nb_bits in init_vlc()
* @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
*/
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2],
int bits, int max_depth)
{
int code;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
GET_VLC(code, re, s, table, bits, max_depth);
CLOSE_READER(re, s);
return code;
}
static inline int decode012(GetBitContext *gb)
{
int n;
n = get_bits1(gb);
if (n == 0)
return 0;
else
return get_bits1(gb) + 1;
}
static inline int decode210(GetBitContext *gb)
{
if (get_bits1(gb))
return 0;
else
return 2 - get_bits1(gb);
}
static inline int get_bits_left(GetBitContext *gb)
{
return gb->size_in_bits - get_bits_count(gb);
}
static inline int skip_1stop_8data_bits(GetBitContext *gb)
{
if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA;
while (get_bits1(gb)) {
skip_bits(gb, 8);
if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA;
}
return 0;
}
#endif /* AVCODEC_GET_BITS_H */

View file

@ -0,0 +1,173 @@
/*
* exp golomb vlc stuff
* 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
* @brief
* exp golomb vlc stuff
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include "libavutil/common.h"
const uint8_t ff_golomb_vlc_len[512]={
19,17,15,15,13,13,13,13,11,11,11,11,11,11,11,11,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};
const uint8_t ff_ue_golomb_vlc_code[512]={
32,32,32,32,32,32,32,32,31,32,32,32,32,32,32,32,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
const int8_t ff_se_golomb_vlc_code[512]={
17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15,
4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const uint8_t ff_ue_golomb_len[256]={
1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,
};
const uint8_t ff_interleaved_golomb_vlc_len[256]={
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
};
const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={
15,16,7, 7, 17,18,8, 8, 3, 3, 3, 3, 3, 3, 3, 3,
19,20,9, 9, 21,22,10,10,4, 4, 4, 4, 4, 4, 4, 4,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
23,24,11,11,25,26,12,12,5, 5, 5, 5, 5, 5, 5, 5,
27,28,13,13,29,30,14,14,6, 6, 6, 6, 6, 6, 6, 6,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const int8_t ff_interleaved_se_golomb_vlc_code[256]={
8, -8, 4, 4, 9, -9, -4, -4, 2, 2, 2, 2, 2, 2, 2, 2,
10,-10, 5, 5, 11,-11, -5, -5, -2, -2, -2, -2, -2, -2, -2, -2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
12,-12, 6, 6, 13,-13, -6, -6, 3, 3, 3, 3, 3, 3, 3, 3,
14,-14, 7, 7, 15,-15, -7, -7, -3, -3, -3, -3, -3, -3, -3, -3,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]={
0, 1, 0, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
4, 5, 2, 2, 6, 7, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 9, 4, 4, 10,11,5, 5, 2, 2, 2, 2, 2, 2, 2, 2,
12,13,6, 6, 14,15,7, 7, 3, 3, 3, 3, 3, 3, 3, 3,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};

View file

@ -0,0 +1,579 @@
/*
* exp golomb vlc stuff
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2004 Alex Beregszaszi
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* @brief
* exp golomb vlc stuff
* @author Michael Niedermayer <michaelni@gmx.at> and Alex Beregszaszi
*/
#ifndef AVCODEC_GOLOMB_H
#define AVCODEC_GOLOMB_H
#include <stdint.h>
#include "get_bits.h"
#include "put_bits.h"
#define INVALID_VLC 0x80000000
extern const uint8_t ff_golomb_vlc_len[512];
extern const uint8_t ff_ue_golomb_vlc_code[512];
extern const int8_t ff_se_golomb_vlc_code[512];
extern const uint8_t ff_ue_golomb_len[256];
extern const uint8_t ff_interleaved_golomb_vlc_len[256];
extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256];
extern const int8_t ff_interleaved_se_golomb_vlc_code[256];
extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256];
/**
* Read an unsigned Exp-Golomb code in the range 0 to 8190.
*/
static inline int get_ue_golomb(GetBitContext *gb)
{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf >= (1 << 27)) {
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_ue_golomb_vlc_code[buf];
} else {
int log = 2 * av_log2(buf) - 31;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
if (log < 7) {
av_log(NULL, AV_LOG_ERROR, "Invalid UE golomb code\n");
return AVERROR_INVALIDDATA;
}
buf >>= log;
buf--;
return buf;
}
}
/**
* Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1.
*/
static inline unsigned get_ue_golomb_long(GetBitContext *gb)
{
unsigned buf, log;
buf = show_bits_long(gb, 32);
log = 31 - av_log2(buf);
skip_bits_long(gb, log);
return get_bits_long(gb, log + 1) - 1;
}
/**
* read unsigned exp golomb code, constraint to a max of 31.
* the return value is undefined if the stored value exceeds 31.
*/
static inline int get_ue_golomb_31(GetBitContext *gb)
{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_ue_golomb_vlc_code[buf];
}
static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb)
{
uint32_t buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf & 0xAA800000) {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_interleaved_ue_golomb_vlc_code[buf];
} else {
unsigned ret = 1;
do {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb,
FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));
if (ff_interleaved_golomb_vlc_len[buf] != 9) {
ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1;
ret |= ff_interleaved_dirac_golomb_vlc_code[buf];
break;
}
ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
} while (ret<0x8000000U && BITS_AVAILABLE(re, gb));
CLOSE_READER(re, gb);
return ret - 1;
}
}
/**
* read unsigned truncated exp golomb code.
*/
static inline int get_te0_golomb(GetBitContext *gb, int range)
{
av_assert2(range >= 1);
if (range == 1)
return 0;
else if (range == 2)
return get_bits1(gb) ^ 1;
else
return get_ue_golomb(gb);
}
/**
* read unsigned truncated exp golomb code.
*/
static inline int get_te_golomb(GetBitContext *gb, int range)
{
av_assert2(range >= 1);
if (range == 2)
return get_bits1(gb) ^ 1;
else
return get_ue_golomb(gb);
}
/**
* read signed exp golomb code.
*/
static inline int get_se_golomb(GetBitContext *gb)
{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf >= (1 << 27)) {
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_se_golomb_vlc_code[buf];
} else {
int log = av_log2(buf), sign;
LAST_SKIP_BITS(re, gb, 31 - log);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
buf >>= log;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
sign = -(buf & 1);
buf = ((buf >> 1) ^ sign) - sign;
return buf;
}
}
static inline int get_se_golomb_long(GetBitContext *gb)
{
unsigned int buf = get_ue_golomb_long(gb);
int sign = (buf & 1) - 1;
return ((buf >> 1) ^ sign) + 1;
}
static inline int get_interleaved_se_golomb(GetBitContext *gb)
{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
if (buf & 0xAA800000) {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_interleaved_se_golomb_vlc_code[buf];
} else {
int log;
LAST_SKIP_BITS(re, gb, 8);
UPDATE_CACHE(re, gb);
buf |= 1 | (GET_CACHE(re, gb) >> 8);
if ((buf & 0xAAAAAAAA) == 0)
return INVALID_VLC;
for (log = 31; (buf & 0x80000000) == 0; log--)
buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30);
LAST_SKIP_BITS(re, gb, 63 - 2 * log - 8);
CLOSE_READER(re, gb);
return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1;
}
}
static inline int dirac_get_se_golomb(GetBitContext *gb)
{
uint32_t ret = get_interleaved_ue_golomb(gb);
if (ret) {
int sign = -get_bits1(gb);
ret = (ret ^ sign) - sign;
}
return ret;
}
/**
* read unsigned golomb rice code (ffv1).
*/
static inline int get_ur_golomb(GetBitContext *gb, int k, int limit,
int esc_len)
{
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
log = av_log2(buf);
if (log > 31 - limit) {
buf >>= log - k;
buf += (30U - log) << k;
LAST_SKIP_BITS(re, gb, 32 + k - log);
CLOSE_READER(re, gb);
return buf;
} else {
LAST_SKIP_BITS(re, gb, limit);
UPDATE_CACHE(re, gb);
buf = SHOW_UBITS(re, gb, esc_len);
LAST_SKIP_BITS(re, gb, esc_len);
CLOSE_READER(re, gb);
return buf + limit - 1;
}
}
/**
* read unsigned golomb rice code (jpegls).
*/
static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit,
int esc_len)
{
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
log = av_log2(buf);
if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) &&
32 - log < limit) {
buf >>= log - k;
buf += (30U - log) << k;
LAST_SKIP_BITS(re, gb, 32 + k - log);
CLOSE_READER(re, gb);
return buf;
} else {
int i;
for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) {
if (gb->size_in_bits <= re_index)
return -1;
LAST_SKIP_BITS(re, gb, 1);
UPDATE_CACHE(re, gb);
}
SKIP_BITS(re, gb, 1);
if (i < limit - 1) {
if (k) {
if (k > MIN_CACHE_BITS - 1) {
buf = SHOW_UBITS(re, gb, 16) << (k-16);
LAST_SKIP_BITS(re, gb, 16);
UPDATE_CACHE(re, gb);
buf |= SHOW_UBITS(re, gb, k-16);
LAST_SKIP_BITS(re, gb, k-16);
} else {
buf = SHOW_UBITS(re, gb, k);
LAST_SKIP_BITS(re, gb, k);
}
} else {
buf = 0;
}
CLOSE_READER(re, gb);
return buf + (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;
}
}
/**
* read signed golomb rice code (ffv1).
*/
static inline int get_sr_golomb(GetBitContext *gb, int k, int limit,
int esc_len)
{
unsigned v = get_ur_golomb(gb, k, limit, esc_len);
return (v >> 1) ^ -(v & 1);
}
/**
* read signed golomb rice code (flac).
*/
static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit,
int esc_len)
{
unsigned v = get_ur_golomb_jpegls(gb, k, limit, esc_len);
return (v >> 1) ^ -(v & 1);
}
/**
* read unsigned golomb rice code (shorten).
*/
static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k)
{
return get_ur_golomb_jpegls(gb, k, INT_MAX, 0);
}
/**
* read signed golomb rice code (shorten).
*/
static inline int get_sr_golomb_shorten(GetBitContext *gb, int k)
{
int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0);
return (uvar >> 1) ^ -(uvar & 1);
}
#ifdef TRACE
static inline int get_ue(GetBitContext *s, const char *file, const char *func,
int line)
{
int show = show_bits(s, 24);
int pos = get_bits_count(s);
int i = get_ue_golomb(s);
int len = get_bits_count(s) - pos;
int bits = show >> (24 - len);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n",
bits, len, i, pos, file, func, line);
return i;
}
static inline int get_se(GetBitContext *s, const char *file, const char *func,
int line)
{
int show = show_bits(s, 24);
int pos = get_bits_count(s);
int i = get_se_golomb(s);
int len = get_bits_count(s) - pos;
int bits = show >> (24 - len);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n",
bits, len, i, pos, file, func, line);
return i;
}
static inline int get_te(GetBitContext *s, int r, char *file, const char *func,
int line)
{
int show = show_bits(s, 24);
int pos = get_bits_count(s);
int i = get_te0_golomb(s, r);
int len = get_bits_count(s) - pos;
int bits = show >> (24 - len);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n",
bits, len, i, pos, file, func, line);
return i;
}
#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#endif /* TRACE */
/**
* write unsigned exp golomb code.
*/
static inline void set_ue_golomb(PutBitContext *pb, int i)
{
av_assert2(i >= 0);
if (i < 256)
put_bits(pb, ff_ue_golomb_len[i], i + 1);
else {
int e = av_log2(i + 1);
put_bits(pb, 2 * e + 1, i + 1);
}
}
/**
* write truncated unsigned exp golomb code.
*/
static inline void set_te_golomb(PutBitContext *pb, int i, int range)
{
av_assert2(range >= 1);
av_assert2(i <= range);
if (range == 2)
put_bits(pb, 1, i ^ 1);
else
set_ue_golomb(pb, i);
}
/**
* write signed exp golomb code. 16 bits at most.
*/
static inline void set_se_golomb(PutBitContext *pb, int i)
{
#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);
}
/**
* write unsigned golomb rice code (ffv1).
*/
static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit,
int esc_len)
{
int e;
av_assert2(i >= 0);
e = i >> k;
if (e < limit)
put_bits(pb, e + k + 1, (1 << k) + av_mod_uintp2(i, k));
else
put_bits(pb, limit + esc_len, i - limit + 1);
}
/**
* write unsigned golomb rice code (jpegls).
*/
static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k,
int limit, int esc_len)
{
int e;
av_assert2(i >= 0);
e = (i >> k) + 1;
if (e < limit) {
while (e > 31) {
put_bits(pb, 31, 0);
e -= 31;
}
put_bits(pb, e, 1);
if (k)
put_sbits(pb, k, i);
} else {
while (limit > 31) {
put_bits(pb, 31, 0);
limit -= 31;
}
put_bits(pb, limit, 1);
put_bits(pb, esc_len, i - 1);
}
}
/**
* write signed golomb rice code (ffv1).
*/
static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit,
int esc_len)
{
int v;
v = -2 * i - 1;
v ^= (v >> 31);
set_ur_golomb(pb, v, k, limit, esc_len);
}
/**
* write signed golomb rice code (flac).
*/
static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k,
int limit, int esc_len)
{
int v;
v = -2 * i - 1;
v ^= (v >> 31);
set_ur_golomb_jpegls(pb, v, k, limit, esc_len);
}
#endif /* AVCODEC_GOLOMB_H */

View file

@ -0,0 +1,35 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_H263DSP_H
#define AVCODEC_H263DSP_H
#include <stdint.h>
extern const uint8_t ff_h263_loop_filter_strength[32];
typedef struct H263DSPContext {
void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale);
void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale);
} H263DSPContext;
void ff_h263dsp_init(H263DSPContext *ctx);
void ff_h263dsp_init_x86(H263DSPContext *ctx);
void ff_h263dsp_init_mips(H263DSPContext *ctx);
#endif /* AVCODEC_H263DSP_H */

View file

@ -0,0 +1,39 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_H264CHROMA_H
#define AVCODEC_H264CHROMA_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 struct H264ChromaContext {
h264_chroma_mc_func put_h264_chroma_pixels_tab[4];
h264_chroma_mc_func avg_h264_chroma_pixels_tab[4];
} H264ChromaContext;
void ff_h264chroma_init(H264ChromaContext *c, int bit_depth);
void ff_h264chroma_init_aarch64(H264ChromaContext *c, int bit_depth);
void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth);
void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth);
void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth);
void ff_h264chroma_init_mips(H264ChromaContext *c, int bit_depth);
#endif /* AVCODEC_H264CHROMA_H */

View file

@ -0,0 +1,132 @@
/*
* Copyright (c) 2003-2010 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 DSP functions.
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#ifndef AVCODEC_H264DSP_H
#define AVCODEC_H264DSP_H
#include <stdint.h>
typedef void (*h264_weight_func)(uint8_t *block, int stride, int height,
int log2_denom, int weight, int offset);
typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
int stride, int height, int log2_denom,
int weightd, int weights, int offset);
/**
* Context for storing H.264 DSP functions
*/
typedef struct H264DSPContext {
/* weighted MC */
h264_weight_func weight_h264_pixels_tab[4];
h264_biweight_func biweight_h264_pixels_tab[4];
/* loop filter */
void (*h264_v_loop_filter_luma)(uint8_t *pix /*align 16*/, int stride,
int alpha, int beta, int8_t *tc0);
void (*h264_h_loop_filter_luma)(uint8_t *pix /*align 4 */, int stride,
int alpha, int beta, int8_t *tc0);
void (*h264_h_loop_filter_luma_mbaff)(uint8_t *pix /*align 16*/, int stride,
int alpha, int beta, int8_t *tc0);
/* v/h_loop_filter_luma_intra: align 16 */
void (*h264_v_loop_filter_luma_intra)(uint8_t *pix, int stride,
int alpha, int beta);
void (*h264_h_loop_filter_luma_intra)(uint8_t *pix, int stride,
int alpha, int beta);
void (*h264_h_loop_filter_luma_mbaff_intra)(uint8_t *pix /*align 16*/,
int stride, int alpha, int beta);
void (*h264_v_loop_filter_chroma)(uint8_t *pix /*align 8*/, int stride,
int alpha, int beta, int8_t *tc0);
void (*h264_h_loop_filter_chroma)(uint8_t *pix /*align 4*/, int stride,
int alpha, int beta, int8_t *tc0);
void (*h264_h_loop_filter_chroma_mbaff)(uint8_t *pix /*align 8*/,
int stride, int alpha, int beta,
int8_t *tc0);
void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix /*align 8*/,
int stride, int alpha, int beta);
void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix /*align 8*/,
int stride, int alpha, int beta);
void (*h264_h_loop_filter_chroma_mbaff_intra)(uint8_t *pix /*align 8*/,
int stride, int alpha, int beta);
// h264_loop_filter_strength: simd only. the C version is inlined in h264_loopfilter.c
void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40],
int8_t ref[2][40], int16_t mv[2][40][2],
int bidir, int edges, int step,
int mask_mv0, int mask_mv1, int field);
/* IDCT */
void (*h264_idct_add)(uint8_t *dst /*align 4*/,
int16_t *block /*align 16*/, int stride);
void (*h264_idct8_add)(uint8_t *dst /*align 8*/,
int16_t *block /*align 16*/, int stride);
void (*h264_idct_dc_add)(uint8_t *dst /*align 4*/,
int16_t *block /*align 16*/, int stride);
void (*h264_idct8_dc_add)(uint8_t *dst /*align 8*/,
int16_t *block /*align 16*/, int stride);
void (*h264_idct_add16)(uint8_t *dst /*align 16*/, const int *blockoffset,
int16_t *block /*align 16*/, int stride,
const uint8_t nnzc[15 * 8]);
void (*h264_idct8_add4)(uint8_t *dst /*align 16*/, const int *blockoffset,
int16_t *block /*align 16*/, int stride,
const uint8_t nnzc[15 * 8]);
void (*h264_idct_add8)(uint8_t **dst /*align 16*/, const int *blockoffset,
int16_t *block /*align 16*/, int stride,
const uint8_t nnzc[15 * 8]);
void (*h264_idct_add16intra)(uint8_t *dst /*align 16*/, const int *blockoffset,
int16_t *block /*align 16*/,
int stride, const uint8_t nnzc[15 * 8]);
void (*h264_luma_dc_dequant_idct)(int16_t *output,
int16_t *input /*align 16*/, int qmul);
void (*h264_chroma_dc_dequant_idct)(int16_t *block, int qmul);
/* bypass-transform */
void (*h264_add_pixels8_clear)(uint8_t *dst, int16_t *block, int stride);
void (*h264_add_pixels4_clear)(uint8_t *dst, int16_t *block, int stride);
/**
* Search buf from the start for up to size bytes. Return the index
* of a zero byte, or >= size if not found. Ideally, use lookahead
* to filter out any zero bytes that are known to not be followed by
* one or more further zero bytes and a one byte. Better still, filter
* out any bytes that form the trailing_zero_8bits syntax element too.
*/
int (*startcode_find_candidate)(const uint8_t *buf, int size);
} H264DSPContext;
void ff_h264dsp_init(H264DSPContext *c, const int bit_depth,
const int chroma_format_idc);
void ff_h264dsp_init_aarch64(H264DSPContext *c, const int bit_depth,
const int chroma_format_idc);
void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth,
const int chroma_format_idc);
void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth,
const int chroma_format_idc);
void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
const int chroma_format_idc);
void ff_h264dsp_init_mips(H264DSPContext *c, const int bit_depth,
const int chroma_format_idc);
#endif /* AVCODEC_H264DSP_H */

View file

@ -0,0 +1,603 @@
/*
* 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 prediction functions.
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "h264pred.h"
#define BIT_DEPTH 8
#include "h264pred_template.c"
#undef BIT_DEPTH
#define BIT_DEPTH 9
#include "h264pred_template.c"
#undef BIT_DEPTH
#define BIT_DEPTH 10
#include "h264pred_template.c"
#undef BIT_DEPTH
#define BIT_DEPTH 12
#include "h264pred_template.c"
#undef BIT_DEPTH
#define BIT_DEPTH 14
#include "h264pred_template.c"
#undef BIT_DEPTH
static void pred4x4_vertical_vp8_c(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
const unsigned lt = src[-1-1*stride];
LOAD_TOP_EDGE
LOAD_TOP_RIGHT_EDGE
uint32_t v = PACK_4U8((lt + 2*t0 + t1 + 2) >> 2,
(t0 + 2*t1 + t2 + 2) >> 2,
(t1 + 2*t2 + t3 + 2) >> 2,
(t2 + 2*t3 + t4 + 2) >> 2);
AV_WN32A(src+0*stride, v);
AV_WN32A(src+1*stride, v);
AV_WN32A(src+2*stride, v);
AV_WN32A(src+3*stride, v);
}
static void pred4x4_horizontal_vp8_c(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
const unsigned lt = src[-1-1*stride];
LOAD_LEFT_EDGE
AV_WN32A(src+0*stride, ((lt + 2*l0 + l1 + 2) >> 2)*0x01010101);
AV_WN32A(src+1*stride, ((l0 + 2*l1 + l2 + 2) >> 2)*0x01010101);
AV_WN32A(src+2*stride, ((l1 + 2*l2 + l3 + 2) >> 2)*0x01010101);
AV_WN32A(src+3*stride, ((l2 + 2*l3 + l3 + 2) >> 2)*0x01010101);
}
static void pred4x4_down_left_svq3_c(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
LOAD_TOP_EDGE
LOAD_LEFT_EDGE
src[0+0*stride]=(l1 + t1)>>1;
src[1+0*stride]=
src[0+1*stride]=(l2 + t2)>>1;
src[2+0*stride]=
src[1+1*stride]=
src[0+2*stride]=
src[3+0*stride]=
src[2+1*stride]=
src[1+2*stride]=
src[0+3*stride]=
src[3+1*stride]=
src[2+2*stride]=
src[1+3*stride]=
src[3+2*stride]=
src[2+3*stride]=
src[3+3*stride]=(l3 + t3)>>1;
}
static void pred4x4_down_left_rv40_c(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
LOAD_TOP_EDGE
LOAD_TOP_RIGHT_EDGE
LOAD_LEFT_EDGE
LOAD_DOWN_LEFT_EDGE
src[0+0*stride]=(t0 + t2 + 2*t1 + 2 + l0 + l2 + 2*l1 + 2)>>3;
src[1+0*stride]=
src[0+1*stride]=(t1 + t3 + 2*t2 + 2 + l1 + l3 + 2*l2 + 2)>>3;
src[2+0*stride]=
src[1+1*stride]=
src[0+2*stride]=(t2 + t4 + 2*t3 + 2 + l2 + l4 + 2*l3 + 2)>>3;
src[3+0*stride]=
src[2+1*stride]=
src[1+2*stride]=
src[0+3*stride]=(t3 + t5 + 2*t4 + 2 + l3 + l5 + 2*l4 + 2)>>3;
src[3+1*stride]=
src[2+2*stride]=
src[1+3*stride]=(t4 + t6 + 2*t5 + 2 + l4 + l6 + 2*l5 + 2)>>3;
src[3+2*stride]=
src[2+3*stride]=(t5 + t7 + 2*t6 + 2 + l5 + l7 + 2*l6 + 2)>>3;
src[3+3*stride]=(t6 + t7 + 1 + l6 + l7 + 1)>>2;
}
static void pred4x4_down_left_rv40_nodown_c(uint8_t *src,
const uint8_t *topright,
ptrdiff_t stride)
{
LOAD_TOP_EDGE
LOAD_TOP_RIGHT_EDGE
LOAD_LEFT_EDGE
src[0+0*stride]=(t0 + t2 + 2*t1 + 2 + l0 + l2 + 2*l1 + 2)>>3;
src[1+0*stride]=
src[0+1*stride]=(t1 + t3 + 2*t2 + 2 + l1 + l3 + 2*l2 + 2)>>3;
src[2+0*stride]=
src[1+1*stride]=
src[0+2*stride]=(t2 + t4 + 2*t3 + 2 + l2 + 3*l3 + 2)>>3;
src[3+0*stride]=
src[2+1*stride]=
src[1+2*stride]=
src[0+3*stride]=(t3 + t5 + 2*t4 + 2 + l3*4 + 2)>>3;
src[3+1*stride]=
src[2+2*stride]=
src[1+3*stride]=(t4 + t6 + 2*t5 + 2 + l3*4 + 2)>>3;
src[3+2*stride]=
src[2+3*stride]=(t5 + t7 + 2*t6 + 2 + l3*4 + 2)>>3;
src[3+3*stride]=(t6 + t7 + 1 + 2*l3 + 1)>>2;
}
static void pred4x4_vertical_left_rv40(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride,
const int l0, const int l1, const int l2,
const int l3, const int l4)
{
LOAD_TOP_EDGE
LOAD_TOP_RIGHT_EDGE
src[0+0*stride]=(2*t0 + 2*t1 + l1 + 2*l2 + l3 + 4)>>3;
src[1+0*stride]=
src[0+2*stride]=(t1 + t2 + 1)>>1;
src[2+0*stride]=
src[1+2*stride]=(t2 + t3 + 1)>>1;
src[3+0*stride]=
src[2+2*stride]=(t3 + t4+ 1)>>1;
src[3+2*stride]=(t4 + t5+ 1)>>1;
src[0+1*stride]=(t0 + 2*t1 + t2 + l2 + 2*l3 + l4 + 4)>>3;
src[1+1*stride]=
src[0+3*stride]=(t1 + 2*t2 + t3 + 2)>>2;
src[2+1*stride]=
src[1+3*stride]=(t2 + 2*t3 + t4 + 2)>>2;
src[3+1*stride]=
src[2+3*stride]=(t3 + 2*t4 + t5 + 2)>>2;
src[3+3*stride]=(t4 + 2*t5 + t6 + 2)>>2;
}
static void pred4x4_vertical_left_rv40_c(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
LOAD_LEFT_EDGE
LOAD_DOWN_LEFT_EDGE
pred4x4_vertical_left_rv40(src, topright, stride, l0, l1, l2, l3, l4);
}
static void pred4x4_vertical_left_rv40_nodown_c(uint8_t *src,
const uint8_t *topright,
ptrdiff_t stride)
{
LOAD_LEFT_EDGE
pred4x4_vertical_left_rv40(src, topright, stride, l0, l1, l2, l3, l3);
}
static void pred4x4_vertical_left_vp8_c(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
LOAD_TOP_EDGE
LOAD_TOP_RIGHT_EDGE
src[0+0*stride]=(t0 + t1 + 1)>>1;
src[1+0*stride]=
src[0+2*stride]=(t1 + t2 + 1)>>1;
src[2+0*stride]=
src[1+2*stride]=(t2 + t3 + 1)>>1;
src[3+0*stride]=
src[2+2*stride]=(t3 + t4 + 1)>>1;
src[0+1*stride]=(t0 + 2*t1 + t2 + 2)>>2;
src[1+1*stride]=
src[0+3*stride]=(t1 + 2*t2 + t3 + 2)>>2;
src[2+1*stride]=
src[1+3*stride]=(t2 + 2*t3 + t4 + 2)>>2;
src[3+1*stride]=
src[2+3*stride]=(t3 + 2*t4 + t5 + 2)>>2;
src[3+2*stride]=(t4 + 2*t5 + t6 + 2)>>2;
src[3+3*stride]=(t5 + 2*t6 + t7 + 2)>>2;
}
static void pred4x4_horizontal_up_rv40_c(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
LOAD_LEFT_EDGE
LOAD_DOWN_LEFT_EDGE
LOAD_TOP_EDGE
LOAD_TOP_RIGHT_EDGE
src[0+0*stride]=(t1 + 2*t2 + t3 + 2*l0 + 2*l1 + 4)>>3;
src[1+0*stride]=(t2 + 2*t3 + t4 + l0 + 2*l1 + l2 + 4)>>3;
src[2+0*stride]=
src[0+1*stride]=(t3 + 2*t4 + t5 + 2*l1 + 2*l2 + 4)>>3;
src[3+0*stride]=
src[1+1*stride]=(t4 + 2*t5 + t6 + l1 + 2*l2 + l3 + 4)>>3;
src[2+1*stride]=
src[0+2*stride]=(t5 + 2*t6 + t7 + 2*l2 + 2*l3 + 4)>>3;
src[3+1*stride]=
src[1+2*stride]=(t6 + 3*t7 + l2 + 3*l3 + 4)>>3;
src[3+2*stride]=
src[1+3*stride]=(l3 + 2*l4 + l5 + 2)>>2;
src[0+3*stride]=
src[2+2*stride]=(t6 + t7 + l3 + l4 + 2)>>2;
src[2+3*stride]=(l4 + l5 + 1)>>1;
src[3+3*stride]=(l4 + 2*l5 + l6 + 2)>>2;
}
static void pred4x4_horizontal_up_rv40_nodown_c(uint8_t *src,
const uint8_t *topright,
ptrdiff_t stride)
{
LOAD_LEFT_EDGE
LOAD_TOP_EDGE
LOAD_TOP_RIGHT_EDGE
src[0+0*stride]=(t1 + 2*t2 + t3 + 2*l0 + 2*l1 + 4)>>3;
src[1+0*stride]=(t2 + 2*t3 + t4 + l0 + 2*l1 + l2 + 4)>>3;
src[2+0*stride]=
src[0+1*stride]=(t3 + 2*t4 + t5 + 2*l1 + 2*l2 + 4)>>3;
src[3+0*stride]=
src[1+1*stride]=(t4 + 2*t5 + t6 + l1 + 2*l2 + l3 + 4)>>3;
src[2+1*stride]=
src[0+2*stride]=(t5 + 2*t6 + t7 + 2*l2 + 2*l3 + 4)>>3;
src[3+1*stride]=
src[1+2*stride]=(t6 + 3*t7 + l2 + 3*l3 + 4)>>3;
src[3+2*stride]=
src[1+3*stride]=l3;
src[0+3*stride]=
src[2+2*stride]=(t6 + t7 + 2*l3 + 2)>>2;
src[2+3*stride]=
src[3+3*stride]=l3;
}
static void pred4x4_tm_vp8_c(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP - src[-1-stride];
uint8_t *top = src-stride;
int y;
for (y = 0; y < 4; y++) {
const uint8_t *cm_in = cm + src[-1];
src[0] = cm_in[top[0]];
src[1] = cm_in[top[1]];
src[2] = cm_in[top[2]];
src[3] = cm_in[top[3]];
src += stride;
}
}
static void pred16x16_plane_svq3_c(uint8_t *src, ptrdiff_t stride)
{
pred16x16_plane_compat_8_c(src, stride, 1, 0);
}
static void pred16x16_plane_rv40_c(uint8_t *src, ptrdiff_t stride)
{
pred16x16_plane_compat_8_c(src, stride, 0, 1);
}
static void pred16x16_tm_vp8_c(uint8_t *src, ptrdiff_t stride)
{
const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP - src[-1-stride];
uint8_t *top = src-stride;
int y;
for (y = 0; y < 16; y++) {
const uint8_t *cm_in = cm + src[-1];
src[0] = cm_in[top[0]];
src[1] = cm_in[top[1]];
src[2] = cm_in[top[2]];
src[3] = cm_in[top[3]];
src[4] = cm_in[top[4]];
src[5] = cm_in[top[5]];
src[6] = cm_in[top[6]];
src[7] = cm_in[top[7]];
src[8] = cm_in[top[8]];
src[9] = cm_in[top[9]];
src[10] = cm_in[top[10]];
src[11] = cm_in[top[11]];
src[12] = cm_in[top[12]];
src[13] = cm_in[top[13]];
src[14] = cm_in[top[14]];
src[15] = cm_in[top[15]];
src += stride;
}
}
static void pred8x8_left_dc_rv40_c(uint8_t *src, ptrdiff_t stride)
{
int i;
unsigned dc0;
dc0=0;
for(i=0;i<8; i++)
dc0+= src[-1+i*stride];
dc0= 0x01010101*((dc0 + 4)>>3);
for(i=0; i<8; i++){
((uint32_t*)(src+i*stride))[0]=
((uint32_t*)(src+i*stride))[1]= dc0;
}
}
static void pred8x8_top_dc_rv40_c(uint8_t *src, ptrdiff_t stride)
{
int i;
unsigned dc0;
dc0=0;
for(i=0;i<8; i++)
dc0+= src[i-stride];
dc0= 0x01010101*((dc0 + 4)>>3);
for(i=0; i<8; i++){
((uint32_t*)(src+i*stride))[0]=
((uint32_t*)(src+i*stride))[1]= dc0;
}
}
static void pred8x8_dc_rv40_c(uint8_t *src, ptrdiff_t stride)
{
int i;
unsigned dc0 = 0;
for(i=0;i<4; i++){
dc0+= src[-1+i*stride] + src[i-stride];
dc0+= src[4+i-stride];
dc0+= src[-1+(i+4)*stride];
}
dc0= 0x01010101*((dc0 + 8)>>4);
for(i=0; i<4; i++){
((uint32_t*)(src+i*stride))[0]= dc0;
((uint32_t*)(src+i*stride))[1]= dc0;
}
for(i=4; i<8; i++){
((uint32_t*)(src+i*stride))[0]= dc0;
((uint32_t*)(src+i*stride))[1]= dc0;
}
}
static void pred8x8_tm_vp8_c(uint8_t *src, ptrdiff_t stride)
{
const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP - src[-1-stride];
uint8_t *top = src-stride;
int y;
for (y = 0; y < 8; y++) {
const uint8_t *cm_in = cm + src[-1];
src[0] = cm_in[top[0]];
src[1] = cm_in[top[1]];
src[2] = cm_in[top[2]];
src[3] = cm_in[top[3]];
src[4] = cm_in[top[4]];
src[5] = cm_in[top[5]];
src[6] = cm_in[top[6]];
src[7] = cm_in[top[7]];
src += stride;
}
}
/**
* Set the intra prediction function pointers.
*/
av_cold void ff_h264_pred_init(H264PredContext *h, int codec_id,
const int bit_depth,
int chroma_format_idc)
{
#undef FUNC
#undef FUNCC
#define FUNC(a, depth) a ## _ ## depth
#define FUNCC(a, depth) a ## _ ## depth ## _c
#define FUNCD(a) a ## _c
#define H264_PRED(depth) \
if(codec_id != AV_CODEC_ID_RV40){\
if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) {\
h->pred4x4[VERT_PRED ]= FUNCD(pred4x4_vertical_vp8);\
h->pred4x4[HOR_PRED ]= FUNCD(pred4x4_horizontal_vp8);\
} else {\
h->pred4x4[VERT_PRED ]= FUNCC(pred4x4_vertical , depth);\
h->pred4x4[HOR_PRED ]= FUNCC(pred4x4_horizontal , depth);\
}\
h->pred4x4[DC_PRED ]= FUNCC(pred4x4_dc , depth);\
if(codec_id == AV_CODEC_ID_SVQ3)\
h->pred4x4[DIAG_DOWN_LEFT_PRED ]= FUNCD(pred4x4_down_left_svq3);\
else\
h->pred4x4[DIAG_DOWN_LEFT_PRED ]= FUNCC(pred4x4_down_left , depth);\
h->pred4x4[DIAG_DOWN_RIGHT_PRED]= FUNCC(pred4x4_down_right , depth);\
h->pred4x4[VERT_RIGHT_PRED ]= FUNCC(pred4x4_vertical_right , depth);\
h->pred4x4[HOR_DOWN_PRED ]= FUNCC(pred4x4_horizontal_down , depth);\
if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) {\
h->pred4x4[VERT_LEFT_PRED ]= FUNCD(pred4x4_vertical_left_vp8);\
} else\
h->pred4x4[VERT_LEFT_PRED ]= FUNCC(pred4x4_vertical_left , depth);\
h->pred4x4[HOR_UP_PRED ]= FUNCC(pred4x4_horizontal_up , depth);\
if (codec_id != AV_CODEC_ID_VP7 && codec_id != AV_CODEC_ID_VP8) {\
h->pred4x4[LEFT_DC_PRED ]= FUNCC(pred4x4_left_dc , depth);\
h->pred4x4[TOP_DC_PRED ]= FUNCC(pred4x4_top_dc , depth);\
} else {\
h->pred4x4[TM_VP8_PRED ]= FUNCD(pred4x4_tm_vp8);\
h->pred4x4[DC_127_PRED ]= FUNCC(pred4x4_127_dc , depth);\
h->pred4x4[DC_129_PRED ]= FUNCC(pred4x4_129_dc , depth);\
h->pred4x4[VERT_VP8_PRED ]= FUNCC(pred4x4_vertical , depth);\
h->pred4x4[HOR_VP8_PRED ]= FUNCC(pred4x4_horizontal , depth);\
}\
if (codec_id != AV_CODEC_ID_VP8)\
h->pred4x4[DC_128_PRED ]= FUNCC(pred4x4_128_dc , depth);\
}else{\
h->pred4x4[VERT_PRED ]= FUNCC(pred4x4_vertical , depth);\
h->pred4x4[HOR_PRED ]= FUNCC(pred4x4_horizontal , depth);\
h->pred4x4[DC_PRED ]= FUNCC(pred4x4_dc , depth);\
h->pred4x4[DIAG_DOWN_LEFT_PRED ]= FUNCD(pred4x4_down_left_rv40);\
h->pred4x4[DIAG_DOWN_RIGHT_PRED]= FUNCC(pred4x4_down_right , depth);\
h->pred4x4[VERT_RIGHT_PRED ]= FUNCC(pred4x4_vertical_right , depth);\
h->pred4x4[HOR_DOWN_PRED ]= FUNCC(pred4x4_horizontal_down , depth);\
h->pred4x4[VERT_LEFT_PRED ]= FUNCD(pred4x4_vertical_left_rv40);\
h->pred4x4[HOR_UP_PRED ]= FUNCD(pred4x4_horizontal_up_rv40);\
h->pred4x4[LEFT_DC_PRED ]= FUNCC(pred4x4_left_dc , depth);\
h->pred4x4[TOP_DC_PRED ]= FUNCC(pred4x4_top_dc , depth);\
h->pred4x4[DC_128_PRED ]= FUNCC(pred4x4_128_dc , depth);\
h->pred4x4[DIAG_DOWN_LEFT_PRED_RV40_NODOWN]= FUNCD(pred4x4_down_left_rv40_nodown);\
h->pred4x4[HOR_UP_PRED_RV40_NODOWN]= FUNCD(pred4x4_horizontal_up_rv40_nodown);\
h->pred4x4[VERT_LEFT_PRED_RV40_NODOWN]= FUNCD(pred4x4_vertical_left_rv40_nodown);\
}\
\
h->pred8x8l[VERT_PRED ]= FUNCC(pred8x8l_vertical , depth);\
h->pred8x8l[HOR_PRED ]= FUNCC(pred8x8l_horizontal , depth);\
h->pred8x8l[DC_PRED ]= FUNCC(pred8x8l_dc , depth);\
h->pred8x8l[DIAG_DOWN_LEFT_PRED ]= FUNCC(pred8x8l_down_left , depth);\
h->pred8x8l[DIAG_DOWN_RIGHT_PRED]= FUNCC(pred8x8l_down_right , depth);\
h->pred8x8l[VERT_RIGHT_PRED ]= FUNCC(pred8x8l_vertical_right , depth);\
h->pred8x8l[HOR_DOWN_PRED ]= FUNCC(pred8x8l_horizontal_down , depth);\
h->pred8x8l[VERT_LEFT_PRED ]= FUNCC(pred8x8l_vertical_left , depth);\
h->pred8x8l[HOR_UP_PRED ]= FUNCC(pred8x8l_horizontal_up , depth);\
h->pred8x8l[LEFT_DC_PRED ]= FUNCC(pred8x8l_left_dc , depth);\
h->pred8x8l[TOP_DC_PRED ]= FUNCC(pred8x8l_top_dc , depth);\
h->pred8x8l[DC_128_PRED ]= FUNCC(pred8x8l_128_dc , depth);\
\
if (chroma_format_idc <= 1) {\
h->pred8x8[VERT_PRED8x8 ]= FUNCC(pred8x8_vertical , depth);\
h->pred8x8[HOR_PRED8x8 ]= FUNCC(pred8x8_horizontal , depth);\
} else {\
h->pred8x8[VERT_PRED8x8 ]= FUNCC(pred8x16_vertical , depth);\
h->pred8x8[HOR_PRED8x8 ]= FUNCC(pred8x16_horizontal , depth);\
}\
if (codec_id != AV_CODEC_ID_VP7 && codec_id != AV_CODEC_ID_VP8) {\
if (chroma_format_idc <= 1) {\
h->pred8x8[PLANE_PRED8x8]= FUNCC(pred8x8_plane , depth);\
} else {\
h->pred8x8[PLANE_PRED8x8]= FUNCC(pred8x16_plane , depth);\
}\
} else\
h->pred8x8[PLANE_PRED8x8]= FUNCD(pred8x8_tm_vp8);\
if (codec_id != AV_CODEC_ID_RV40 && codec_id != AV_CODEC_ID_VP7 && \
codec_id != AV_CODEC_ID_VP8) {\
if (chroma_format_idc <= 1) {\
h->pred8x8[DC_PRED8x8 ]= FUNCC(pred8x8_dc , depth);\
h->pred8x8[LEFT_DC_PRED8x8]= FUNCC(pred8x8_left_dc , depth);\
h->pred8x8[TOP_DC_PRED8x8 ]= FUNCC(pred8x8_top_dc , depth);\
h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_l0t, depth);\
h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_0lt, depth);\
h->pred8x8[ALZHEIMER_DC_L00_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_l00, depth);\
h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_0l0, depth);\
} else {\
h->pred8x8[DC_PRED8x8 ]= FUNCC(pred8x16_dc , depth);\
h->pred8x8[LEFT_DC_PRED8x8]= FUNCC(pred8x16_left_dc , depth);\
h->pred8x8[TOP_DC_PRED8x8 ]= FUNCC(pred8x16_top_dc , depth);\
h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8 ]= FUNC(pred8x16_mad_cow_dc_l0t, depth);\
h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8 ]= FUNC(pred8x16_mad_cow_dc_0lt, depth);\
h->pred8x8[ALZHEIMER_DC_L00_PRED8x8 ]= FUNC(pred8x16_mad_cow_dc_l00, depth);\
h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8 ]= FUNC(pred8x16_mad_cow_dc_0l0, depth);\
}\
}else{\
h->pred8x8[DC_PRED8x8 ]= FUNCD(pred8x8_dc_rv40);\
h->pred8x8[LEFT_DC_PRED8x8]= FUNCD(pred8x8_left_dc_rv40);\
h->pred8x8[TOP_DC_PRED8x8 ]= FUNCD(pred8x8_top_dc_rv40);\
if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) {\
h->pred8x8[DC_127_PRED8x8]= FUNCC(pred8x8_127_dc , depth);\
h->pred8x8[DC_129_PRED8x8]= FUNCC(pred8x8_129_dc , depth);\
}\
}\
if (chroma_format_idc <= 1) {\
h->pred8x8[DC_128_PRED8x8 ]= FUNCC(pred8x8_128_dc , depth);\
} else {\
h->pred8x8[DC_128_PRED8x8 ]= FUNCC(pred8x16_128_dc , depth);\
}\
\
h->pred16x16[DC_PRED8x8 ]= FUNCC(pred16x16_dc , depth);\
h->pred16x16[VERT_PRED8x8 ]= FUNCC(pred16x16_vertical , depth);\
h->pred16x16[HOR_PRED8x8 ]= FUNCC(pred16x16_horizontal , depth);\
switch(codec_id){\
case AV_CODEC_ID_SVQ3:\
h->pred16x16[PLANE_PRED8x8 ]= FUNCD(pred16x16_plane_svq3);\
break;\
case AV_CODEC_ID_RV40:\
h->pred16x16[PLANE_PRED8x8 ]= FUNCD(pred16x16_plane_rv40);\
break;\
case AV_CODEC_ID_VP7:\
case AV_CODEC_ID_VP8:\
h->pred16x16[PLANE_PRED8x8 ]= FUNCD(pred16x16_tm_vp8);\
h->pred16x16[DC_127_PRED8x8]= FUNCC(pred16x16_127_dc , depth);\
h->pred16x16[DC_129_PRED8x8]= FUNCC(pred16x16_129_dc , depth);\
break;\
default:\
h->pred16x16[PLANE_PRED8x8 ]= FUNCC(pred16x16_plane , depth);\
break;\
}\
h->pred16x16[LEFT_DC_PRED8x8]= FUNCC(pred16x16_left_dc , depth);\
h->pred16x16[TOP_DC_PRED8x8 ]= FUNCC(pred16x16_top_dc , depth);\
h->pred16x16[DC_128_PRED8x8 ]= FUNCC(pred16x16_128_dc , depth);\
\
/* special lossless h/v prediction for H.264 */ \
h->pred4x4_add [VERT_PRED ]= FUNCC(pred4x4_vertical_add , depth);\
h->pred4x4_add [ HOR_PRED ]= FUNCC(pred4x4_horizontal_add , depth);\
h->pred8x8l_add [VERT_PRED ]= FUNCC(pred8x8l_vertical_add , depth);\
h->pred8x8l_add [ HOR_PRED ]= FUNCC(pred8x8l_horizontal_add , depth);\
h->pred8x8l_filter_add [VERT_PRED ]= FUNCC(pred8x8l_vertical_filter_add , depth);\
h->pred8x8l_filter_add [ HOR_PRED ]= FUNCC(pred8x8l_horizontal_filter_add , depth);\
if (chroma_format_idc <= 1) {\
h->pred8x8_add [VERT_PRED8x8]= FUNCC(pred8x8_vertical_add , depth);\
h->pred8x8_add [ HOR_PRED8x8]= FUNCC(pred8x8_horizontal_add , depth);\
} else {\
h->pred8x8_add [VERT_PRED8x8]= FUNCC(pred8x16_vertical_add , depth);\
h->pred8x8_add [ HOR_PRED8x8]= FUNCC(pred8x16_horizontal_add , depth);\
}\
h->pred16x16_add[VERT_PRED8x8]= FUNCC(pred16x16_vertical_add , depth);\
h->pred16x16_add[ HOR_PRED8x8]= FUNCC(pred16x16_horizontal_add , depth);\
switch (bit_depth) {
case 9:
H264_PRED(9)
break;
case 10:
H264_PRED(10)
break;
case 12:
H264_PRED(12)
break;
case 14:
H264_PRED(14)
break;
default:
av_assert0(bit_depth<=8);
H264_PRED(8)
break;
}
if (ARCH_AARCH64)
ff_h264_pred_init_aarch64(h, codec_id, bit_depth, chroma_format_idc);
if (ARCH_ARM)
ff_h264_pred_init_arm(h, codec_id, bit_depth, chroma_format_idc);
if (ARCH_X86)
ff_h264_pred_init_x86(h, codec_id, bit_depth, chroma_format_idc);
if (ARCH_MIPS)
ff_h264_pred_init_mips(h, codec_id, bit_depth, chroma_format_idc);
}

View file

@ -0,0 +1,126 @@
/*
* 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 prediction functions.
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#ifndef AVCODEC_H264PRED_H
#define AVCODEC_H264PRED_H
#include <stddef.h>
#include <stdint.h>
/**
* Prediction types
*/
//@{
#define VERT_PRED 0
#define HOR_PRED 1
#define DC_PRED 2
#define DIAG_DOWN_LEFT_PRED 3
#define DIAG_DOWN_RIGHT_PRED 4
#define VERT_RIGHT_PRED 5
#define HOR_DOWN_PRED 6
#define VERT_LEFT_PRED 7
#define HOR_UP_PRED 8
// DC edge (not for VP8)
#define LEFT_DC_PRED 9
#define TOP_DC_PRED 10
#define DC_128_PRED 11
// RV40 specific
#define DIAG_DOWN_LEFT_PRED_RV40_NODOWN 12
#define HOR_UP_PRED_RV40_NODOWN 13
#define VERT_LEFT_PRED_RV40_NODOWN 14
// VP8 specific
#define TM_VP8_PRED 9 ///< "True Motion", used instead of plane
#define VERT_VP8_PRED 10 ///< for VP8, #VERT_PRED is the average of
///< (left col+cur col x2+right col) / 4;
///< this is the "unaveraged" one
#define HOR_VP8_PRED 14 ///< unaveraged version of #HOR_PRED, see
///< #VERT_VP8_PRED for details
#define DC_127_PRED 12
#define DC_129_PRED 13
#define DC_PRED8x8 0
#define HOR_PRED8x8 1
#define VERT_PRED8x8 2
#define PLANE_PRED8x8 3
// DC edge
#define LEFT_DC_PRED8x8 4
#define TOP_DC_PRED8x8 5
#define DC_128_PRED8x8 6
// H.264/SVQ3 (8x8) specific
#define ALZHEIMER_DC_L0T_PRED8x8 7
#define ALZHEIMER_DC_0LT_PRED8x8 8
#define ALZHEIMER_DC_L00_PRED8x8 9
#define ALZHEIMER_DC_0L0_PRED8x8 10
// VP8 specific
#define DC_127_PRED8x8 7
#define DC_129_PRED8x8 8
//@}
/**
* Context for storing H.264 prediction functions
*/
typedef struct H264PredContext {
void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride);
void(*pred8x8l[9 + 3])(uint8_t *src, int topleft, int topright,
ptrdiff_t stride);
void(*pred8x8[4 + 3 + 4])(uint8_t *src, ptrdiff_t stride);
void(*pred16x16[4 + 3 + 2])(uint8_t *src, ptrdiff_t stride);
void(*pred4x4_add[2])(uint8_t *pix /*align 4*/,
int16_t *block /*align 16*/, ptrdiff_t stride);
void(*pred8x8l_add[2])(uint8_t *pix /*align 8*/,
int16_t *block /*align 16*/, ptrdiff_t stride);
void(*pred8x8l_filter_add[2])(uint8_t *pix /*align 8*/,
int16_t *block /*align 16*/, int topleft, int topright, ptrdiff_t stride);
void(*pred8x8_add[3])(uint8_t *pix /*align 8*/,
const int *block_offset,
int16_t *block /*align 16*/, ptrdiff_t stride);
void(*pred16x16_add[3])(uint8_t *pix /*align 16*/,
const int *block_offset,
int16_t *block /*align 16*/, ptrdiff_t stride);
} H264PredContext;
void ff_h264_pred_init(H264PredContext *h, int codec_id,
const int bit_depth, const int chroma_format_idc);
void ff_h264_pred_init_aarch64(H264PredContext *h, int codec_id,
const int bit_depth,
const int chroma_format_idc);
void ff_h264_pred_init_arm(H264PredContext *h, int codec_id,
const int bit_depth, const int chroma_format_idc);
void ff_h264_pred_init_x86(H264PredContext *h, int codec_id,
const int bit_depth, const int chroma_format_idc);
void ff_h264_pred_init_mips(H264PredContext *h, int codec_id,
const int bit_depth, const int chroma_format_idc);
#endif /* AVCODEC_H264PRED_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,104 @@
/*
* Half-pel DSP functions.
* Copyright (c) 2000, 2001, 2002 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
*/
/**
* @file
* Half-pel DSP functions.
*/
#ifndef AVCODEC_HPELDSP_H
#define AVCODEC_HPELDSP_H
#include <stdint.h>
#include <stddef.h>
/* add and put pixel (decoding) */
// blocksizes for hpel_pixels_func are 8x4,8x8 16x8 16x16
// h for hpel_pixels_func is limited to {width/2, width} but never larger
// than 16 and never smaller than 4
typedef void (*op_pixels_func)(uint8_t *block /*align width (8 or 16)*/,
const uint8_t *pixels /*align 1*/,
ptrdiff_t line_size, int h);
/**
* Half-pel DSP context.
*/
typedef struct HpelDSPContext {
/**
* Halfpel motion compensation with rounding (a+b+1)>>1.
* this is an array[4][4] of motion compensation functions for 4
* horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination where the result is stored
* @param pixels source
* @param line_size number of bytes in a horizontal line of block
* @param h height
*/
op_pixels_func put_pixels_tab[4][4];
/**
* Halfpel motion compensation with rounding (a+b+1)>>1.
* This is an array[4][4] of motion compensation functions for 4
* horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination into which the result is averaged (a+b+1)>>1
* @param pixels source
* @param line_size number of bytes in a horizontal line of block
* @param h height
*/
op_pixels_func avg_pixels_tab[4][4];
/**
* Halfpel motion compensation with no rounding (a+b)>>1.
* this is an array[4][4] of motion compensation functions for 2
* horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination where the result is stored
* @param pixels source
* @param line_size number of bytes in a horizontal line of block
* @param h height
*/
op_pixels_func put_no_rnd_pixels_tab[4][4];
/**
* Halfpel motion compensation with no rounding (a+b)>>1.
* this is an array[4] of motion compensation functions for 1
* horizontal blocksize (16) and the 4 halfpel positions<br>
* *pixels_tab[0][ xhalfpel + 2*yhalfpel ]
* @param block destination into which the result is averaged (a+b)>>1
* @param pixels source
* @param line_size number of bytes in a horizontal line of block
* @param h height
*/
op_pixels_func avg_no_rnd_pixels_tab[4];
} HpelDSPContext;
void ff_hpeldsp_init(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_aarch64(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_alpha(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags);
void ff_hpeldsp_init_mips(HpelDSPContext *c, int flags);
#endif /* AVCODEC_HPELDSP_H */

View file

@ -0,0 +1,114 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_IDCTDSP_H
#define AVCODEC_IDCTDSP_H
#include <stdint.h>
#include "avcodec.h"
/**
* Scantable.
*/
typedef struct ScanTable {
const uint8_t *scantable;
uint8_t permutated[64];
uint8_t raster_end[64];
} ScanTable;
enum idct_permutation_type {
FF_IDCT_PERM_NONE,
FF_IDCT_PERM_LIBMPEG2,
FF_IDCT_PERM_SIMPLE,
FF_IDCT_PERM_TRANSPOSE,
FF_IDCT_PERM_PARTTRANS,
FF_IDCT_PERM_SSE2,
};
void ff_init_scantable(uint8_t *permutation, ScanTable *st,
const uint8_t *src_scantable);
void ff_init_scantable_permutation(uint8_t *idct_permutation,
enum idct_permutation_type perm_type);
int ff_init_scantable_permutation_x86(uint8_t *idct_permutation,
enum idct_permutation_type perm_type);
typedef struct IDCTDSPContext {
/* pixel ops : interface with DCT */
void (*put_pixels_clamped)(const int16_t *block /* align 16 */,
uint8_t *pixels /* align 8 */,
ptrdiff_t line_size);
void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */,
uint8_t *pixels /* align 8 */,
ptrdiff_t line_size);
void (*add_pixels_clamped)(const int16_t *block /* align 16 */,
uint8_t *pixels /* align 8 */,
ptrdiff_t line_size);
void (*idct)(int16_t *block /* align 16 */);
/**
* block -> idct -> clip to unsigned 8 bit -> dest.
* (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...)
* @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 */);
/**
* 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 */);
/**
* 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];
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_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx);
void ff_idctdsp_init_alpha(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_idctdsp_init_arm(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_idctdsp_init_ppc(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_idctdsp_init_mips(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
#endif /* AVCODEC_IDCTDSP_H */

View file

@ -0,0 +1,235 @@
/*
* Misc image conversion routines
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* misc image conversion routines
*/
#include "avcodec.h"
#include "internal.h"
#include "mathops.h"
#include "libavutil/avassert.h"
#include "libavutil/colorspace.h"
#include "libavutil/common.h"
#include "libavutil/pixdesc.h"
#include "libavutil/internal.h"
#include "libavutil/imgutils.h"
#if FF_API_GETCHROMA
void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
av_assert0(desc);
*h_shift = desc->log2_chroma_w;
*v_shift = desc->log2_chroma_h;
}
#endif
int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
enum AVPixelFormat src_pix_fmt,
int has_alpha)
{
return av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
}
enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
{
return av_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr);
}
#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
enum AVPixelFormat avcodec_find_best_pix_fmt2(const enum AVPixelFormat *pix_fmt_list,
enum AVPixelFormat src_pix_fmt,
int has_alpha, int *loss_ptr){
return avcodec_find_best_pix_fmt_of_list(pix_fmt_list, src_pix_fmt, has_alpha, loss_ptr);
}
#else
enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
{
return avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr);
}
#endif
enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list,
enum AVPixelFormat src_pix_fmt,
int has_alpha, int *loss_ptr){
int i;
enum AVPixelFormat best = AV_PIX_FMT_NONE;
for(i=0; pix_fmt_list[i] != AV_PIX_FMT_NONE; i++)
best = avcodec_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, loss_ptr);
return best;
}
#if FF_API_AVPICTURE
FF_DISABLE_DEPRECATION_WARNINGS
/* return true if yuv planar */
static inline int is_yuv_planar(const AVPixFmtDescriptor *desc)
{
int i;
int planes[4] = { 0 };
if ( desc->flags & AV_PIX_FMT_FLAG_RGB
|| !(desc->flags & AV_PIX_FMT_FLAG_PLANAR))
return 0;
/* set the used planes */
for (i = 0; i < desc->nb_components; i++)
planes[desc->comp[i].plane] = 1;
/* if there is an unused plane, the format is not planar */
for (i = 0; i < desc->nb_components; i++)
if (!planes[i])
return 0;
return 1;
}
int av_picture_crop(AVPicture *dst, const AVPicture *src,
enum AVPixelFormat pix_fmt, int top_band, int left_band)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
int y_shift;
int x_shift;
int max_step[4];
if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
return -1;
y_shift = desc->log2_chroma_h;
x_shift = desc->log2_chroma_w;
av_image_fill_max_pixsteps(max_step, NULL, desc);
if (is_yuv_planar(desc)) {
dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
} else{
if(top_band % (1<<y_shift) || left_band % (1<<x_shift))
return -1;
dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + (left_band * max_step[0]);
}
dst->linesize[0] = src->linesize[0];
dst->linesize[1] = src->linesize[1];
dst->linesize[2] = src->linesize[2];
return 0;
}
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
int *color)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
uint8_t *optr;
int y_shift;
int x_shift;
int yheight;
int i, y;
int max_step[4];
if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
return -1;
if (!is_yuv_planar(desc)) {
if (src)
return -1; //TODO: Not yet implemented
av_image_fill_max_pixsteps(max_step, NULL, desc);
if (padtop || padleft) {
memset(dst->data[0], color[0],
dst->linesize[0] * padtop + (padleft * max_step[0]));
}
if (padleft || padright) {
optr = dst->data[0] + dst->linesize[0] * padtop +
(dst->linesize[0] - (padright * max_step[0]));
yheight = height - 1 - (padtop + padbottom);
for (y = 0; y < yheight; y++) {
memset(optr, color[0], (padleft + padright) * max_step[0]);
optr += dst->linesize[0];
}
}
if (padbottom || padright) {
optr = dst->data[0] + dst->linesize[0] * (height - padbottom) -
(padright * max_step[0]);
memset(optr, color[0], dst->linesize[0] * padbottom +
(padright * max_step[0]));
}
return 0;
}
for (i = 0; i < 3; i++) {
x_shift = i ? desc->log2_chroma_w : 0;
y_shift = i ? desc->log2_chroma_h : 0;
if (padtop || padleft) {
memset(dst->data[i], color[i],
dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
}
if (padleft || padright) {
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(dst->linesize[i] - (padright >> x_shift));
yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
for (y = 0; y < yheight; y++) {
memset(optr, color[i], (padleft + padright) >> x_shift);
optr += dst->linesize[i];
}
}
if (src) { /* first line */
uint8_t *iptr = src->data[i];
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(padleft >> x_shift);
memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
iptr += src->linesize[i];
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(dst->linesize[i] - (padright >> x_shift));
yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
for (y = 0; y < yheight; y++) {
memset(optr, color[i], (padleft + padright) >> x_shift);
memcpy(optr + ((padleft + padright) >> x_shift), iptr,
(width - padleft - padright) >> x_shift);
iptr += src->linesize[i];
optr += dst->linesize[i];
}
}
if (padbottom || padright) {
optr = dst->data[i] + dst->linesize[i] *
((height - padbottom) >> y_shift) - (padright >> x_shift);
memset(optr, color[i],dst->linesize[i] *
(padbottom >> y_shift) + (padright >> x_shift));
}
}
return 0;
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif /* FF_API_AVPICTURE */

View file

@ -0,0 +1,363 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* common internal api header.
*/
#ifndef AVCODEC_INTERNAL_H
#define AVCODEC_INTERNAL_H
#include <stdint.h>
#include "libavutil/buffer.h"
#include "libavutil/channel_layout.h"
#include "libavutil/mathematics.h"
#include "libavutil/pixfmt.h"
#include "avcodec.h"
#include "config.h"
/**
* The codec does not modify any global variables in the init function,
* allowing to call the init function without locking any global mutexes.
*/
#define FF_CODEC_CAP_INIT_THREADSAFE (1 << 0)
/**
* The codec allows calling the close function for deallocation even if
* the init function returned a failure. Without this capability flag, a
* codec does such cleanup internally when returning failures from the
* init function and does not expect the close function to be called at
* all.
*/
#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
* from the input AVPacket.
*/
#define FF_CODEC_CAP_SETS_PKT_DTS (1 << 2)
/**
* The decoder extracts and fills its parameters even if the frame is
* skipped due to the skip_frame setting.
*/
#define FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM (1 << 3)
#ifdef TRACE
# define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__)
#else
# define ff_tlog(ctx, ...) do { } while(0)
#endif
#if !FF_API_QUANT_BIAS
#define FF_DEFAULT_QUANT_BIAS 999999
#endif
#define FF_SANE_NB_CHANNELS 64U
#define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1)
#if HAVE_AVX
# define STRIDE_ALIGN 32
#elif HAVE_SIMD_ALIGN_16
# define STRIDE_ALIGN 16
#else
# define STRIDE_ALIGN 8
#endif
typedef struct FramePool {
/**
* Pools for each data plane. For audio all the planes have the same size,
* so only pools[0] is used.
*/
AVBufferPool *pools[4];
/*
* Pool parameters
*/
int format;
int width, height;
int stride_align[AV_NUM_DATA_POINTERS];
int linesize[4];
int planes;
int channels;
int samples;
} FramePool;
typedef struct AVCodecInternal {
/**
* Whether the parent AVCodecContext is a copy of the context which had
* init() called on it.
* This is used by multithreading - shared tables and picture pointers
* should be freed from the original context only.
*/
int is_copy;
/**
* Whether to allocate progress for frame threading.
*
* The codec must set it to 1 if it uses ff_thread_await/report_progress(),
* then progress will be allocated in ff_thread_get_buffer(). The frames
* then MUST be freed with ff_thread_release_buffer().
*
* If the codec does not need to call the progress functions (there are no
* dependencies between the frames), it should leave this at 0. Then it can
* decode straight to the user-provided frames (which the user will then
* free with av_frame_unref()), there is no need to call
* ff_thread_release_buffer().
*/
int allocate_progress;
/**
* An audio frame with less than required samples has been submitted and
* padded with silence. Reject all subsequent frames.
*/
int last_audio_frame;
AVFrame *to_free;
FramePool *pool;
void *thread_ctx;
/**
* Current packet as passed into the decoder, to avoid having to pass the
* packet into every function.
*/
AVPacket *pkt;
/**
* temporary buffer used for encoders to store their bitstream
*/
uint8_t *byte_buffer;
unsigned int byte_buffer_size;
void *frame_thread_encoder;
/**
* Number of audio samples to skip at the start of the next decoded frame
*/
int skip_samples;
/**
* hwaccel-specific private data
*/
void *hwaccel_priv_data;
/**
* checks API usage: after codec draining, flush is required to resume operation
*/
int draining;
/**
* buffers for using new encode/decode API through legacy API
*/
AVPacket *buffer_pkt;
int buffer_pkt_valid; // encoding: packet without data can be valid
AVFrame *buffer_frame;
int draining_done;
} AVCodecInternal;
struct AVCodecDefault {
const uint8_t *key;
const uint8_t *value;
};
extern const uint8_t ff_log2_run[41];
/**
* Return the index into tab at which {a,b} match elements {[0],[1]} of tab.
* If there is no such matching pair then size is returned.
*/
int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b);
unsigned int avpriv_toupper4(unsigned int x);
/**
* does needed setup of pkt_pts/pos and such for (re)get_buffer();
*/
int ff_init_buffer_info(AVCodecContext *s, AVFrame *frame);
void ff_color_frame(AVFrame *frame, const int color[4]);
extern volatile int ff_avcodec_locked;
int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec);
int ff_unlock_avcodec(const AVCodec *codec);
int avpriv_lock_avformat(void);
int avpriv_unlock_avformat(void);
/**
* Maximum size in bytes of extradata.
* This value was chosen such that every bit of the buffer is
* addressable by a 32-bit signed integer as used by get_bits.
*/
#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE)
/**
* Check AVPacket size and/or allocate data.
*
* Encoders supporting AVCodec.encode2() can use this as a convenience to
* ensure the output packet data is large enough, whether provided by the user
* or allocated in this function.
*
* @param avctx the AVCodecContext of the encoder
* @param avpkt the AVPacket
* If avpkt->data is already set, avpkt->size is checked
* to ensure it is large enough.
* If avpkt->data is NULL, a new buffer is allocated.
* avpkt->size is set to the specified size.
* All other AVPacket fields will be reset with av_init_packet().
* @param size the minimum required packet size
* @param min_size This is a hint to the allocation algorithm, which indicates
* to what minimal size the caller might later shrink the packet
* to. Encoders often allocate packets which are larger than the
* amount of data that is written into them as the exact amount is
* not known at the time of allocation. min_size represents the
* size a packet might be shrunk to by the caller. Can be set to
* 0. setting this roughly correctly allows the allocation code
* to choose between several allocation strategies to improve
* speed slightly.
* @return non negative on success, negative error code on failure
*/
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size);
attribute_deprecated int ff_alloc_packet(AVPacket *avpkt, int size);
/**
* Rescale from sample rate to AVCodecContext.time_base.
*/
static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx,
int64_t samples)
{
if(samples == AV_NOPTS_VALUE)
return AV_NOPTS_VALUE;
return av_rescale_q(samples, (AVRational){ 1, avctx->sample_rate },
avctx->time_base);
}
/**
* 2^(x) for integer x
* @return correctly rounded float
*/
static av_always_inline float ff_exp2fi(int x) {
/* Normal range */
if (-126 <= x && x <= 128)
return av_int2float(x+127 << 23);
/* Too large */
else if (x > 128)
return INFINITY;
/* Subnormal numbers */
else if (x > -150)
return av_int2float(1 << (x+149));
/* Negligibly small */
else
return 0;
}
/**
* Get a buffer for a frame. This is a wrapper around
* AVCodecContext.get_buffer() and should be used instead calling get_buffer()
* directly.
*/
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags);
/**
* Identical in function to av_frame_make_writable(), except it uses
* ff_get_buffer() to allocate the buffer when needed.
*/
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame);
int ff_thread_can_start_frame(AVCodecContext *avctx);
int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx);
/**
* Call avcodec_open2 recursively by decrementing counter, unlocking mutex,
* calling the function and then restoring again. Assumes the mutex is
* already locked
*/
int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
/**
* Finalize buf into extradata and set its size appropriately.
*/
int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf);
const uint8_t *avpriv_find_start_code(const uint8_t *p,
const uint8_t *end,
uint32_t *state);
int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec);
/**
* Check that the provided frame dimensions are valid and set them on the codec
* context.
*/
int ff_set_dimensions(AVCodecContext *s, int width, int height);
/**
* Check that the provided sample aspect ratio is valid and set it on the codec
* context.
*/
int ff_set_sar(AVCodecContext *avctx, AVRational sar);
/**
* Add or update AV_FRAME_DATA_MATRIXENCODING side data.
*/
int ff_side_data_update_matrix_encoding(AVFrame *frame,
enum AVMatrixEncoding matrix_encoding);
/**
* Select the (possibly hardware accelerated) pixel format.
* This is a wrapper around AVCodecContext.get_format() and should be used
* instead of calling get_format() directly.
*/
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt);
/**
* Set various frame properties from the codec context / packet data.
*/
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame);
/**
* Add a CPB properties side data to an encoding context.
*/
AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx);
int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type);
/**
* Check AVFrame for A53 side data and allocate and fill SEI message with A53 info
*
* @param frame Raw frame to get A53 side data from
* @param prefix_len Number of bytes to allocate before SEI message
* @param data Pointer to a variable to store allocated memory
* Upon return the variable will hold NULL on error or if frame has no A53 info.
* Otherwise it will point to prefix_len uninitialized bytes followed by
* *sei_size SEI message
* @param sei_size Pointer to a variable to store generated SEI message length
* @return Zero on success, negative error code on failure
*/
int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len,
void **data, size_t *sei_size);
#endif /* AVCODEC_INTERNAL_H */

View file

@ -0,0 +1 @@
#include "libavutil/log2_tab.c"

View file

@ -0,0 +1,252 @@
/*
* simple math operations
* Copyright (c) 2001, 2002 Fabrice Bellard
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_MATHOPS_H
#define AVCODEC_MATHOPS_H
#include <stdint.h>
#include "libavutil/common.h"
#include "config.h"
#define MAX_NEG_CROP 1024
extern const uint32_t ff_inverse[257];
extern const uint8_t ff_sqrt_tab[256];
extern const uint8_t ff_crop_tab[256 + 2 * MAX_NEG_CROP];
extern const uint8_t ff_zigzag_direct[64];
extern const uint8_t ff_zigzag_scan[16+1];
#if ARCH_ARM
# include "arm/mathops.h"
#elif ARCH_AVR32
# include "avr32/mathops.h"
#elif ARCH_MIPS
# include "mips/mathops.h"
#elif ARCH_PPC
# include "ppc/mathops.h"
#elif ARCH_X86
# include "x86/mathops.h"
#endif
/* generic implementation */
#ifndef MUL64
# define MUL64(a,b) ((int64_t)(a) * (int64_t)(b))
#endif
#ifndef MULL
# define MULL(a,b,s) (MUL64(a, b) >> (s))
#endif
#ifndef MULH
static av_always_inline int MULH(int a, int b){
return MUL64(a, b) >> 32;
}
#endif
#ifndef UMULH
static av_always_inline unsigned UMULH(unsigned a, unsigned b){
return ((uint64_t)(a) * (uint64_t)(b))>>32;
}
#endif
#ifndef MAC64
# define MAC64(d, a, b) ((d) += MUL64(a, b))
#endif
#ifndef MLS64
# define MLS64(d, a, b) ((d) -= MUL64(a, b))
#endif
/* signed 16x16 -> 32 multiply add accumulate */
#ifndef MAC16
# define MAC16(rt, ra, rb) rt += (ra) * (rb)
#endif
/* signed 16x16 -> 32 multiply */
#ifndef MUL16
# define MUL16(ra, rb) ((ra) * (rb))
#endif
#ifndef MLS16
# define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb))
#endif
/* median of 3 */
#ifndef mid_pred
#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;
else b=c;
}
}else{
if(b>c){
if(c>a) b=c;
else b=a;
}
}
return b;
#endif
}
#endif
#ifndef median4
#define median4 median4
static inline av_const int median4(int a, int b, int c, int d)
{
if (a < b) {
if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
} else {
if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
}
}
#endif
#ifndef sign_extend
static inline av_const int sign_extend(int val, unsigned bits)
{
unsigned shift = 8 * sizeof(int) - bits;
union { unsigned u; int s; } v = { (unsigned) val << shift };
return v.s >> shift;
}
#endif
#ifndef zero_extend
static inline av_const unsigned zero_extend(unsigned val, unsigned bits)
{
return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits);
}
#endif
#ifndef COPY3_IF_LT
#define COPY3_IF_LT(x, y, a, b, c, d)\
if ((y) < (x)) {\
(x) = (y);\
(a) = (b);\
(c) = (d);\
}
#endif
#ifndef MASK_ABS
#define MASK_ABS(mask, level) do { \
mask = level >> 31; \
level = (level ^ mask) - mask; \
} while (0)
#endif
#ifndef NEG_SSR32
# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
#endif
#ifndef NEG_USR32
# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
#endif
#if HAVE_BIGENDIAN
# ifndef PACK_2U8
# define PACK_2U8(a,b) (((a) << 8) | (b))
# endif
# ifndef PACK_4U8
# define PACK_4U8(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
# endif
# ifndef PACK_2U16
# define PACK_2U16(a,b) (((a) << 16) | (b))
# endif
#else
# ifndef PACK_2U8
# define PACK_2U8(a,b) (((b) << 8) | (a))
# endif
# ifndef PACK_4U2
# define PACK_4U8(a,b,c,d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a))
# endif
# ifndef PACK_2U16
# define PACK_2U16(a,b) (((b) << 16) | (a))
# endif
#endif
#ifndef PACK_2S8
# define PACK_2S8(a,b) PACK_2U8((a)&255, (b)&255)
#endif
#ifndef PACK_4S8
# define PACK_4S8(a,b,c,d) PACK_4U8((a)&255, (b)&255, (c)&255, (d)&255)
#endif
#ifndef PACK_2S16
# define PACK_2S16(a,b) PACK_2U16((a)&0xffff, (b)&0xffff)
#endif
#ifndef FASTDIV
# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32))
#endif /* FASTDIV */
#ifndef ff_sqrt
#define ff_sqrt ff_sqrt
static inline av_const unsigned int ff_sqrt(unsigned int a)
{
unsigned int b;
if (a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4;
else if (a < (1 << 12)) b = ff_sqrt_tab[a >> 4] >> 2;
#if !CONFIG_SMALL
else if (a < (1 << 14)) b = ff_sqrt_tab[a >> 6] >> 1;
else if (a < (1 << 16)) b = ff_sqrt_tab[a >> 8] ;
#endif
else {
int s = av_log2_16bit(a >> 16) >> 1;
unsigned int c = a >> (s + 2);
b = ff_sqrt_tab[c >> (s + 8)];
b = FASTDIV(c,b) + (b << s);
}
return b - (a < b * b);
}
#endif
static inline av_const float ff_sqrf(float a)
{
return a*a;
}
static inline int8_t ff_u8_to_s8(uint8_t a)
{
union {
uint8_t u8;
int8_t s8;
} b;
b.u8 = a;
return b.s8;
}
#endif /* AVCODEC_MATHOPS_H */

View file

@ -0,0 +1,114 @@
/*
* 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
*/
#include <stdint.h>
#include "mathops.h"
/* a*inverse[b]>>32 == a/b for all 0<=a<=16909558 && 2<=b<=256
* for a>16909558, is an overestimate by less than 1 part in 1<<24 */
const uint32_t ff_inverse[257]={
0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757,
536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154,
268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709,
178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333,
134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367,
107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283,
89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315,
76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085,
67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498,
59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675,
53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441,
48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183,
44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712,
41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400,
38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163,
35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641,
33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573,
31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737,
29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493,
28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373,
26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368,
25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671,
24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767,
23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740,
22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751,
21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635,
20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593,
19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944,
19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933,
18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575,
17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532,
17318417, 17248865, 17179870, 17111424, 17043522, 16976156, 16909321, 16843010,
16777216
};
const uint8_t ff_sqrt_tab[256]={
0, 16, 23, 28, 32, 36, 40, 43, 46, 48, 51, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 77, 79, 80, 82, 84, 85, 87, 88, 90,
91, 92, 94, 95, 96, 98, 99,100,102,103,104,105,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,144,145,146,147,148,149,150,151,151,152,153,154,155,156,156,
157,158,159,160,160,161,162,163,164,164,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,176,177,178,179,179,180,181,
182,182,183,184,184,185,186,186,187,188,188,189,190,190,191,192,192,193,194,194,195,196,196,197,198,198,199,200,200,201,202,202,
203,204,204,205,205,206,207,207,208,208,209,210,210,211,212,212,213,213,214,215,215,216,216,217,218,218,219,219,220,220,221,222,
222,223,223,224,224,225,226,226,227,227,228,228,229,230,230,231,231,232,232,233,233,234,235,235,236,236,237,237,238,238,239,239,
240,240,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255,255
};
#define times4(x) x, x, x, x
#define times256(x) times4(times4(times4(times4(times4(x)))))
const uint8_t ff_crop_tab[256 + 2 * MAX_NEG_CROP] = {
times256(0x00),
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
times256(0xFF)
};
const uint8_t ff_zigzag_direct[64] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
};
const uint8_t ff_zigzag_scan[16+1] = {
0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4,
1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4,
1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4,
3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,
};

View file

@ -0,0 +1,96 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_ME_CMP_H
#define AVCODEC_ME_CMP_H
#include <stdint.h>
#include "avcodec.h"
extern uint32_t ff_square_tab[512];
/* minimum alignment rules ;)
* If you notice errors in the align stuff, need more alignment for some ASM code
* for some CPU or need to use a function with less aligned data then send a mail
* to the ffmpeg-devel mailing list, ...
*
* !warning These alignments might not match reality, (missing attribute((align))
* stuff somewhere possible).
* I (Michael) did not check them, these are just the alignments which I think
* could be reached easily ...
*
* !future video codecs might need functions with less strict alignment
*/
struct MpegEncContext;
/* Motion estimation:
* h is limited to { width / 2, width, 2 * width },
* but never larger than 16 and never smaller than 2.
* Although currently h < 4 is not used as functions with
* width < 8 are neither used nor implemented. */
typedef int (*me_cmp_func)(struct MpegEncContext *c,
uint8_t *blk1 /* align width (8 or 16) */,
uint8_t *blk2 /* align 1 */, ptrdiff_t stride,
int h);
typedef struct MECmpContext {
int (*sum_abs_dctelem)(int16_t *block /* align 16 */);
me_cmp_func sad[6]; /* identical to pix_absAxA except additional void * */
me_cmp_func sse[6];
me_cmp_func hadamard8_diff[6];
me_cmp_func dct_sad[6];
me_cmp_func quant_psnr[6];
me_cmp_func bit[6];
me_cmp_func rd[6];
me_cmp_func vsad[6];
me_cmp_func vsse[6];
me_cmp_func nsse[6];
me_cmp_func w53[6];
me_cmp_func w97[6];
me_cmp_func dct_max[6];
me_cmp_func dct264_sad[6];
me_cmp_func me_pre_cmp[6];
me_cmp_func me_cmp[6];
me_cmp_func me_sub_cmp[6];
me_cmp_func mb_cmp[6];
me_cmp_func ildct_cmp[6]; // only width 16 used
me_cmp_func frame_skip_cmp[6]; // only width 8 used
me_cmp_func pix_abs[2][4];
} MECmpContext;
void ff_me_cmp_init_static(void);
int ff_check_alignment(void);
void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx);
void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx);
void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx);
void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx);
void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx);
void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx);
void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type);
void ff_dsputil_init_dwt(MECmpContext *c);
#endif /* AVCODEC_ME_CMP_H */

View file

@ -0,0 +1,135 @@
/*
* Motion estimation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_MOTION_EST_H
#define AVCODEC_MOTION_EST_H
#include <stdint.h>
#include "avcodec.h"
#include "hpeldsp.h"
#include "qpeldsp.h"
struct MpegEncContext;
#if ARCH_IA64 // Limit static arrays to avoid gcc failing "short data segment overflowed"
#define MAX_MV 1024
#else
#define MAX_MV 4096
#endif
#define MAX_DMV (2*MAX_MV)
#define ME_MAP_SIZE 64
#define FF_ME_ZERO 0
#define FF_ME_EPZS 1
#define FF_ME_XONE 2
/**
* Motion estimation context.
*/
typedef struct MotionEstContext {
AVCodecContext *avctx;
int skip; ///< set if ME is skipped for the current MB
int co_located_mv[4][2]; ///< mv from last P-frame for direct mode ME
int direct_basis_mv[4][2];
uint8_t *scratchpad; /**< data area for the ME algo, so that
* the ME does not need to malloc/free. */
uint8_t *best_mb;
uint8_t *temp_mb[2];
uint8_t *temp;
int best_bits;
uint32_t *map; ///< map to avoid duplicate evaluations
uint32_t *score_map; ///< map to store the scores
unsigned map_generation;
int pre_penalty_factor;
int penalty_factor; /**< an estimate of the bits required to
* code a given mv value, e.g. (1,0) takes
* more bits than (0,0). We have to
* estimate whether any reduction in
* residual is worth the extra bits. */
int sub_penalty_factor;
int mb_penalty_factor;
int flags;
int sub_flags;
int mb_flags;
int pre_pass; ///< = 1 for the pre pass
int dia_size;
int xmin;
int xmax;
int ymin;
int ymax;
int pred_x;
int pred_y;
uint8_t *src[4][4];
uint8_t *ref[4][4];
int stride;
int uvstride;
/* temp variables for picture complexity calculation */
int64_t mc_mb_var_sum_temp;
int64_t mb_var_sum_temp;
int scene_change_score;
op_pixels_func(*hpel_put)[4];
op_pixels_func(*hpel_avg)[4];
qpel_mc_func(*qpel_put)[16];
qpel_mc_func(*qpel_avg)[16];
uint8_t (*mv_penalty)[MAX_DMV * 2 + 1]; ///< bit amount needed to encode a MV
uint8_t *current_mv_penalty;
int (*sub_motion_search)(struct MpegEncContext *s,
int *mx_ptr, int *my_ptr, int dmin,
int src_index, int ref_index,
int size, int h);
} MotionEstContext;
static inline int ff_h263_round_chroma(int x)
{
//FIXME static or not?
static const uint8_t h263_chroma_roundtab[16] = {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
};
return h263_chroma_roundtab[x & 0xf] + (x >> 3);
}
int ff_init_me(struct MpegEncContext *s);
void ff_estimate_p_frame_motion(struct MpegEncContext *s, int mb_x, int mb_y);
void ff_estimate_b_frame_motion(struct MpegEncContext *s, int mb_x, int mb_y);
int ff_pre_estimate_p_frame_motion(struct MpegEncContext *s,
int mb_x, int mb_y);
int ff_epzs_motion_search(struct MpegEncContext *s, int *mx_ptr, int *my_ptr,
int P[10][2], int src_index, int ref_index,
int16_t (*last_mv)[2], int ref_mv_scale, int size,
int h);
int ff_get_mb_score(struct MpegEncContext *s, int mx, int my, int src_index,
int ref_index, int size, int h, int add_rate);
int ff_get_best_fcode(struct MpegEncContext *s,
int16_t (*mv_table)[2], int type);
void ff_fix_long_p_mvs(struct MpegEncContext *s);
void ff_fix_long_mvs(struct MpegEncContext *s, uint8_t *field_select_table,
int field_select, int16_t (*mv_table)[2], int f_code,
int type, int truncate);
#endif /* AVCODEC_MOTION_EST_H */

View file

@ -0,0 +1,65 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Due to duplicate file names, we compile libavutil/x86 in its own
# moz.build file.
if CONFIG['FFVPX_ASFLAGS']:
DIRS += ['x86']
SharedLibrary('mozavcodec')
SOURCES += [
'allcodecs.c',
'audioconvert.c',
'avpacket.c',
'avpicture.c',
'bitstream.c',
'codec_desc.c',
'dummy_funcs.c',
'flac.c',
'flac_parser.c',
'flacdata.c',
'flacdec.c',
'flacdsp.c',
'golomb.c',
'h264pred.c',
'imgconvert.c',
'log2_tab.c',
'mathtables.c',
'options.c',
'parser.c',
'profiles.c',
'pthread.c',
'pthread_frame.c',
'pthread_slice.c',
'qsv_api.c',
'raw.c',
'resample.c',
'resample2.c',
'reverse.c',
'utils.c',
'videodsp.c',
'vorbis_parser.c',
'vp56rac.c',
'vp8.c',
'vp8_parser.c',
'vp8dsp.c',
'vp9.c',
'vp9_parser.c',
'vp9dsp.c',
'vp9dsp_10bpp.c',
'vp9dsp_12bpp.c',
'vp9dsp_8bpp.c',
'xiph.c'
]
SYMBOLS_FILE = 'avcodec.symbols'
NO_VISIBILITY_FLAGS = True
USE_LIBS += [
'mozavutil'
]
include("../ffvpxcommon.mozbuild")

View file

@ -0,0 +1,57 @@
/*
* MPEG-1/2 tables
* copyright (c) 2000,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
*/
/**
* @file
* MPEG-1/2 tables.
*/
#ifndef AVCODEC_MPEG12DATA_H
#define AVCODEC_MPEG12DATA_H
#include <stdint.h>
#include "libavutil/rational.h"
#include "rl.h"
extern const uint16_t ff_mpeg1_default_intra_matrix[];
extern const uint16_t ff_mpeg1_default_non_intra_matrix[64];
extern const uint16_t ff_mpeg12_vlc_dc_lum_code[12];
extern const unsigned char ff_mpeg12_vlc_dc_lum_bits[12];
extern const uint16_t ff_mpeg12_vlc_dc_chroma_code[12];
extern const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12];
extern RLTable ff_rl_mpeg1;
extern RLTable ff_rl_mpeg2;
extern const uint8_t ff_mpeg12_mbAddrIncrTable[36][2];
extern const uint8_t ff_mpeg12_mbPatTable[64][2];
extern const uint8_t ff_mpeg12_mbMotionVectorTable[17][2];
extern const AVRational ff_mpeg12_frame_rate_tab[];
extern const AVRational ff_mpeg2_frame_rate_tab[];
extern const float ff_mpeg1_aspect[16];
extern const AVRational ff_mpeg2_aspect[16];
#endif /* AVCODEC_MPEG12DATA_H */

View file

@ -0,0 +1,114 @@
/*
* Mpeg video formats-related defines and utility functions
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_MPEGPICTURE_H
#define AVCODEC_MPEGPICTURE_H
#include <stdint.h>
#include "libavutil/frame.h"
#include "avcodec.h"
#include "motion_est.h"
#include "thread.h"
#define MAX_PICTURE_COUNT 36
#define EDGE_WIDTH 16
typedef struct ScratchpadContext {
uint8_t *edge_emu_buffer; ///< temporary buffer for if MVs point to out-of-frame data
uint8_t *rd_scratchpad; ///< scratchpad for rate distortion mb decision
uint8_t *obmc_scratchpad;
uint8_t *b_scratchpad; ///< scratchpad used for writing into write only buffers
} ScratchpadContext;
/**
* Picture.
*/
typedef struct Picture {
struct AVFrame *f;
ThreadFrame tf;
AVBufferRef *qscale_table_buf;
int8_t *qscale_table;
AVBufferRef *motion_val_buf[2];
int16_t (*motion_val[2])[2];
AVBufferRef *mb_type_buf;
uint32_t *mb_type; ///< types and macros are defined in mpegutils.h
AVBufferRef *mbskip_table_buf;
uint8_t *mbskip_table;
AVBufferRef *ref_index_buf[2];
int8_t *ref_index[2];
AVBufferRef *mb_var_buf;
uint16_t *mb_var; ///< Table for MB variances
AVBufferRef *mc_mb_var_buf;
uint16_t *mc_mb_var; ///< Table for motion compensated MB variances
int alloc_mb_width; ///< mb_width used to allocate tables
int alloc_mb_height; ///< mb_height used to allocate tables
AVBufferRef *mb_mean_buf;
uint8_t *mb_mean; ///< Table for MB luminance
AVBufferRef *hwaccel_priv_buf;
void *hwaccel_picture_private; ///< Hardware accelerator private data
int field_picture; ///< whether or not the picture was encoded in separate fields
int64_t mb_var_sum; ///< sum of MB variance for current frame
int64_t mc_mb_var_sum; ///< motion compensated MB variance for current frame
int b_frame_score;
int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change)
int reference;
int shared;
uint64_t encoding_error[AV_NUM_DATA_POINTERS];
} Picture;
/**
* Allocate a Picture.
* The pixels are allocated/set by calling get_buffer() if shared = 0.
*/
int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
ScratchpadContext *sc, int shared, int encoding,
int chroma_x_shift, int chroma_y_shift, int out_format,
int mb_stride, int mb_width, int mb_height, int b8_stride,
ptrdiff_t *linesize, ptrdiff_t *uvlinesize);
int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
ScratchpadContext *sc, int linesize);
int ff_mpeg_ref_picture(AVCodecContext *avctx, Picture *dst, Picture *src);
void ff_mpeg_unref_picture(AVCodecContext *avctx, Picture *picture);
void ff_free_picture_tables(Picture *pic);
int ff_update_picture_tables(Picture *dst, Picture *src);
int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared);
#endif /* AVCODEC_MPEGPICTURE_H */

View file

@ -0,0 +1,142 @@
/*
* Mpeg video formats-related defines and utility functions
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_MPEGUTILS_H
#define AVCODEC_MPEGUTILS_H
#include <stdint.h>
#include "libavutil/frame.h"
#include "avcodec.h"
#include "version.h"
/**
* Return value for header parsers if frame is not coded.
* */
#define FRAME_SKIPPED 100
/* picture type */
#define PICT_TOP_FIELD 1
#define PICT_BOTTOM_FIELD 2
#define PICT_FRAME 3
/**
* Value of Picture.reference when Picture is not a reference picture, but
* is held for delayed output.
*/
#define DELAYED_PIC_REF 4
#define MAX_MB_BYTES (30 * 16 * 16 * 3 / 8 + 120)
#define MAX_FCODE 7
/* MB types */
#if !FF_API_MB_TYPE
#define MB_TYPE_INTRA4x4 (1 << 0)
#define MB_TYPE_INTRA16x16 (1 << 1) // FIXME H.264-specific
#define MB_TYPE_INTRA_PCM (1 << 2) // FIXME H.264-specific
#define MB_TYPE_16x16 (1 << 3)
#define MB_TYPE_16x8 (1 << 4)
#define MB_TYPE_8x16 (1 << 5)
#define MB_TYPE_8x8 (1 << 6)
#define MB_TYPE_INTERLACED (1 << 7)
#define MB_TYPE_DIRECT2 (1 << 8) // FIXME
#define MB_TYPE_ACPRED (1 << 9)
#define MB_TYPE_GMC (1 << 10)
#define MB_TYPE_SKIP (1 << 11)
#define MB_TYPE_P0L0 (1 << 12)
#define MB_TYPE_P1L0 (1 << 13)
#define MB_TYPE_P0L1 (1 << 14)
#define MB_TYPE_P1L1 (1 << 15)
#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0)
#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
#define MB_TYPE_QUANT (1 << 16)
#define MB_TYPE_CBP (1 << 17)
#endif
#define MB_TYPE_INTRA MB_TYPE_INTRA4x4 // default mb_type if there is just one type
#define IS_INTRA4x4(a) ((a) & MB_TYPE_INTRA4x4)
#define IS_INTRA16x16(a) ((a) & MB_TYPE_INTRA16x16)
#define IS_PCM(a) ((a) & MB_TYPE_INTRA_PCM)
#define IS_INTRA(a) ((a) & 7)
#define IS_INTER(a) ((a) & (MB_TYPE_16x16 | MB_TYPE_16x8 | \
MB_TYPE_8x16 | MB_TYPE_8x8))
#define IS_SKIP(a) ((a) & MB_TYPE_SKIP)
#define IS_INTRA_PCM(a) ((a) & MB_TYPE_INTRA_PCM)
#define IS_INTERLACED(a) ((a) & MB_TYPE_INTERLACED)
#define IS_DIRECT(a) ((a) & MB_TYPE_DIRECT2)
#define IS_GMC(a) ((a) & MB_TYPE_GMC)
#define IS_16X16(a) ((a) & MB_TYPE_16x16)
#define IS_16X8(a) ((a) & MB_TYPE_16x8)
#define IS_8X16(a) ((a) & MB_TYPE_8x16)
#define IS_8X8(a) ((a) & MB_TYPE_8x8)
#define IS_SUB_8X8(a) ((a) & MB_TYPE_16x16) // note reused
#define IS_SUB_8X4(a) ((a) & MB_TYPE_16x8) // note reused
#define IS_SUB_4X8(a) ((a) & MB_TYPE_8x16) // note reused
#define IS_SUB_4X4(a) ((a) & MB_TYPE_8x8) // note reused
#define IS_ACPRED(a) ((a) & MB_TYPE_ACPRED)
#define IS_QUANT(a) ((a) & MB_TYPE_QUANT)
#define IS_DIR(a, part, list) ((a) & (MB_TYPE_P0L0 << ((part) + 2 * (list))))
// does this mb use listX, note does not work if subMBs
#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0 | MB_TYPE_P1L0) << (2 * (list))))
#define HAS_CBP(a) ((a) & MB_TYPE_CBP)
/* MB types for encoding */
#define CANDIDATE_MB_TYPE_INTRA (1 << 0)
#define CANDIDATE_MB_TYPE_INTER (1 << 1)
#define CANDIDATE_MB_TYPE_INTER4V (1 << 2)
#define CANDIDATE_MB_TYPE_SKIPPED (1 << 3)
#define CANDIDATE_MB_TYPE_DIRECT (1 << 4)
#define CANDIDATE_MB_TYPE_FORWARD (1 << 5)
#define CANDIDATE_MB_TYPE_BACKWARD (1 << 6)
#define CANDIDATE_MB_TYPE_BIDIR (1 << 7)
#define CANDIDATE_MB_TYPE_INTER_I (1 << 8)
#define CANDIDATE_MB_TYPE_FORWARD_I (1 << 9)
#define CANDIDATE_MB_TYPE_BACKWARD_I (1 << 10)
#define CANDIDATE_MB_TYPE_BIDIR_I (1 << 11)
#define CANDIDATE_MB_TYPE_DIRECT0 (1 << 12)
#define INPLACE_OFFSET 16
enum OutputFormat {
FMT_MPEG1,
FMT_H261,
FMT_H263,
FMT_MJPEG,
};
/**
* Draw a horizontal band if supported.
*
* @param h is the normal height, this will be reduced automatically if needed
*/
void ff_draw_horiz_band(AVCodecContext *avctx, AVFrame *cur, AVFrame *last,
int y, int h, int picture_structure, int first_field,
int low_delay);
#endif /* AVCODEC_MPEGUTILS_H */

View file

@ -0,0 +1,752 @@
/*
* Generic DCT based hybrid video encoder
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* mpegvideo header.
*/
#ifndef AVCODEC_MPEGVIDEO_H
#define AVCODEC_MPEGVIDEO_H
#include <float.h>
#include "avcodec.h"
#include "blockdsp.h"
#include "error_resilience.h"
#include "fdctdsp.h"
#include "get_bits.h"
#include "h264chroma.h"
#include "h263dsp.h"
#include "hpeldsp.h"
#include "idctdsp.h"
#include "internal.h"
#include "me_cmp.h"
#include "motion_est.h"
#include "mpegpicture.h"
#include "mpegvideodsp.h"
#include "mpegvideoencdsp.h"
#include "pixblockdsp.h"
#include "put_bits.h"
#include "ratecontrol.h"
#include "parser.h"
#include "mpegutils.h"
#include "mpeg12data.h"
#include "qpeldsp.h"
#include "thread.h"
#include "videodsp.h"
#include "libavutil/opt.h"
#include "libavutil/timecode.h"
#define MAX_THREADS 32
#define MAX_B_FRAMES 16
/* Start codes. */
#define SEQ_END_CODE 0x000001b7
#define SEQ_START_CODE 0x000001b3
#define GOP_START_CODE 0x000001b8
#define PICTURE_START_CODE 0x00000100
#define SLICE_MIN_START_CODE 0x00000101
#define SLICE_MAX_START_CODE 0x000001af
#define EXT_START_CODE 0x000001b5
#define USER_START_CODE 0x000001b2
/**
* MpegEncContext.
*/
typedef struct MpegEncContext {
AVClass *class;
int y_dc_scale, c_dc_scale;
int ac_pred;
int block_last_index[12]; ///< last non zero coefficient in block
int h263_aic; ///< Advanced INTRA Coding (AIC)
/* scantables */
ScanTable inter_scantable; ///< if inter == intra then intra should be used to reduce the cache usage
ScanTable intra_scantable;
ScanTable intra_h_scantable;
ScanTable intra_v_scantable;
/* WARNING: changes above this line require updates to hardcoded
* offsets used in ASM. */
struct AVCodecContext *avctx;
/* the following parameters must be initialized before encoding */
int width, height;///< picture size. must be a multiple of 16
int gop_size;
int intra_only; ///< if true, only intra pictures are generated
int64_t bit_rate; ///< wanted bit rate
enum OutputFormat out_format; ///< output format
int h263_pred; ///< use MPEG-4/H.263 ac/dc predictions
int pb_frame; ///< PB-frame mode (0 = none, 1 = base, 2 = improved)
/* the following codec id fields are deprecated in favor of codec_id */
int h263_plus; ///< H.263+ headers
int h263_flv; ///< use flv H.263 header
enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
int fixed_qscale; ///< fixed qscale if non zero
int encoding; ///< true if we are encoding (vs decoding)
int max_b_frames; ///< max number of B-frames for encoding
int luma_elim_threshold;
int chroma_elim_threshold;
int strict_std_compliance; ///< strictly follow the std (MPEG-4, ...)
int workaround_bugs; ///< workaround bugs in encoders which cannot be detected automatically
int codec_tag; ///< internal codec_tag upper case converted from avctx codec_tag
/* the following fields are managed internally by the encoder */
/* sequence parameters */
int context_initialized;
int input_picture_number; ///< used to set pic->display_picture_number, should not be used for/by anything else
int coded_picture_number; ///< used to set pic->coded_picture_number, should not be used for/by anything else
int picture_number; //FIXME remove, unclear definition
int picture_in_gop_number; ///< 0-> first pic in gop, ...
int mb_width, mb_height; ///< number of MBs horizontally & vertically
int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11
int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressing
int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replication)
int mb_num; ///< number of MBs of a picture
ptrdiff_t linesize; ///< line size, in bytes, may be different from width
ptrdiff_t uvlinesize; ///< line size, for chroma in bytes, may be different from width
Picture *picture; ///< main picture buffer
Picture **input_picture; ///< next pictures on display order for encoding
Picture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding
int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_encode_video2()
/**
* pts difference between the first and second input frame, used for
* calculating dts of the first frame when there's a delay */
int64_t dts_delta;
/**
* reordered pts to be used as dts for the next output frame when there's
* a delay */
int64_t reordered_pts;
/** bit output */
PutBitContext pb;
int start_mb_y; ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
int end_mb_y; ///< end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
struct MpegEncContext *thread_context[MAX_THREADS];
int slice_context_count; ///< number of used thread_contexts
/**
* copy of the previous picture structure.
* note, linesize & data, might not match the previous picture (for field pictures)
*/
Picture last_picture;
/**
* copy of the next picture structure.
* note, linesize & data, might not match the next picture (for field pictures)
*/
Picture next_picture;
/**
* copy of the source picture structure for encoding.
* note, linesize & data, might not match the source picture (for field pictures)
*/
Picture new_picture;
/**
* copy of the current picture structure.
* note, linesize & data, might not match the current picture (for field pictures)
*/
Picture current_picture; ///< buffer to store the decompressed current picture
Picture *last_picture_ptr; ///< pointer to the previous picture.
Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred)
Picture *current_picture_ptr; ///< pointer to the current picture
int last_dc[3]; ///< last DC values for MPEG-1
int16_t *dc_val_base;
int16_t *dc_val[3]; ///< used for MPEG-4 DC prediction, all 3 arrays must be continuous
const uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table
const uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table
const uint8_t *chroma_qscale_table; ///< qscale -> chroma_qscale (H.263)
uint8_t *coded_block_base;
uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1)
int16_t (*ac_val_base)[16];
int16_t (*ac_val[3])[16]; ///< used for MPEG-4 AC prediction, all 3 arrays must be continuous
int mb_skipped; ///< MUST BE SET only during DECODING
uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example)
and used for B-frame encoding & decoding (contains skip table of next P-frame) */
uint8_t *mbintra_table; ///< used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding
uint8_t *cbp_table; ///< used to store cbp, ac_pred for partitioned decoding
uint8_t *pred_dir_table; ///< used to store pred_dir for partitioned decoding
ScratchpadContext sc;
int qscale; ///< QP
int chroma_qscale; ///< chroma QP
unsigned int lambda; ///< Lagrange multiplier used in rate distortion
unsigned int lambda2; ///< (lambda*lambda) >> FF_LAMBDA_SHIFT
int *lambda_table;
int adaptive_quant; ///< use adaptive quantization
int dquant; ///< qscale difference to prev qscale
int closed_gop; ///< MPEG1/2 GOP is closed
int pict_type; ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
int vbv_delay;
int last_pict_type; //FIXME removes
int last_non_b_pict_type; ///< used for MPEG-4 gmc B-frames & ratecontrol
int droppable;
int frame_rate_index;
AVRational mpeg2_frame_rate_ext;
int last_lambda_for[5]; ///< last lambda for a specific pict type
int skipdct; ///< skip dct and code zero residual
/* motion compensation */
int unrestricted_mv; ///< mv can point outside of the coded picture
int h263_long_vectors; ///< use horrible H.263v1 long vector mode
BlockDSPContext bdsp;
FDCTDSPContext fdsp;
H264ChromaContext h264chroma;
HpelDSPContext hdsp;
IDCTDSPContext idsp;
MECmpContext mecc;
MpegVideoDSPContext mdsp;
MpegvideoEncDSPContext mpvencdsp;
PixblockDSPContext pdsp;
QpelDSPContext qdsp;
VideoDSPContext vdsp;
H263DSPContext h263dsp;
int f_code; ///< forward MV resolution
int b_code; ///< backward MV resolution for B-frames (MPEG-4)
int16_t (*p_mv_table_base)[2];
int16_t (*b_forw_mv_table_base)[2];
int16_t (*b_back_mv_table_base)[2];
int16_t (*b_bidir_forw_mv_table_base)[2];
int16_t (*b_bidir_back_mv_table_base)[2];
int16_t (*b_direct_mv_table_base)[2];
int16_t (*p_field_mv_table_base[2][2])[2];
int16_t (*b_field_mv_table_base[2][2][2])[2];
int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) P-frame encoding
int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode B-frame encoding
int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode B-frame encoding
int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode B-frame encoding
int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode B-frame encoding
int16_t (*b_direct_mv_table)[2]; ///< MV table (1MV per MB) direct mode B-frame encoding
int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced P-frame encoding
int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced B-frame encoding
uint8_t (*p_field_select_table[2]);
uint8_t (*b_field_select_table[2][2]);
#if FF_API_MOTION_EST
int me_method; ///< ME algorithm
#endif
int motion_est; ///< ME algorithm
int me_penalty_compensation;
int me_pre; ///< prepass for motion estimation
int mv_dir;
#define MV_DIR_FORWARD 1
#define MV_DIR_BACKWARD 2
#define MV_DIRECT 4 ///< bidirectional mode where the difference equals the MV of the last P/S/I-Frame (MPEG-4)
int mv_type;
#define MV_TYPE_16X16 0 ///< 1 vector for the whole mb
#define MV_TYPE_8X8 1 ///< 4 vectors (H.263, MPEG-4 4MV)
#define MV_TYPE_16X8 2 ///< 2 vectors, one per 16x8 block
#define MV_TYPE_FIELD 3 ///< 2 vectors, one per field
#define MV_TYPE_DMV 4 ///< 2 vectors, special mpeg2 Dual Prime Vectors
/**motion vectors for a macroblock
first coordinate : 0 = forward 1 = backward
second " : depend on type
third " : 0 = x, 1 = y
*/
int mv[2][4][2];
int field_select[2][2];
int last_mv[2][2][2]; ///< last MV, used for MV prediction in MPEG-1 & B-frame MPEG-4
uint8_t *fcode_tab; ///< smallest fcode needed for each MV
int16_t direct_scale_mv[2][64]; ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv
MotionEstContext me;
int no_rounding; /**< apply no rounding to motion compensation (MPEG-4, msmpeg4, ...)
for B-frames rounding mode is always 0 */
/* macroblock layer */
int mb_x, mb_y;
int mb_skip_run;
int mb_intra;
uint16_t *mb_type; ///< Table for candidate MB types for encoding (defines in mpegutils.h)
int block_index[6]; ///< index to current MB in block based arrays with edges
int block_wrap[6];
uint8_t *dest[3];
int *mb_index2xy; ///< mb_index -> mb_x + mb_y*mb_stride
/** matrix transmitted in the bitstream */
uint16_t intra_matrix[64];
uint16_t chroma_intra_matrix[64];
uint16_t inter_matrix[64];
uint16_t chroma_inter_matrix[64];
int force_duplicated_matrix; ///< Force duplication of mjpeg matrices, useful for rtp streaming
int intra_quant_bias; ///< bias for the quantizer
int inter_quant_bias; ///< bias for the quantizer
int min_qcoeff; ///< minimum encodable coefficient
int max_qcoeff; ///< maximum encodable coefficient
int ac_esc_length; ///< num of bits needed to encode the longest esc
uint8_t *intra_ac_vlc_length;
uint8_t *intra_ac_vlc_last_length;
uint8_t *intra_chroma_ac_vlc_length;
uint8_t *intra_chroma_ac_vlc_last_length;
uint8_t *inter_ac_vlc_length;
uint8_t *inter_ac_vlc_last_length;
uint8_t *luma_dc_vlc_length;
#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
int coded_score[12];
/** precomputed matrix (combine qscale and DCT renorm) */
int (*q_intra_matrix)[64];
int (*q_chroma_intra_matrix)[64];
int (*q_inter_matrix)[64];
/** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/
uint16_t (*q_intra_matrix16)[2][64];
uint16_t (*q_chroma_intra_matrix16)[2][64];
uint16_t (*q_inter_matrix16)[2][64];
/* noise reduction */
int (*dct_error_sum)[64];
int dct_count[2];
uint16_t (*dct_offset)[64];
/* bit rate control */
int64_t total_bits;
int frame_bits; ///< bits used for the current frame
int stuffing_bits; ///< bits used for stuffing
int next_lambda; ///< next lambda used for retrying to encode a frame
RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
/* statistics, used for 2-pass encoding */
int mv_bits;
int header_bits;
int i_tex_bits;
int p_tex_bits;
int i_count;
int f_count;
int b_count;
int skip_count;
int misc_bits; ///< cbp, mb_type
int last_bits; ///< temp var used for calculating the above vars
/* error concealment / resync */
int resync_mb_x; ///< x position of last resync marker
int resync_mb_y; ///< y position of last resync marker
GetBitContext last_resync_gb; ///< used to search for the next resync marker
int mb_num_left; ///< number of MBs left in this video packet (for partitioned Slices only)
int next_p_frame_damaged; ///< set if the next p frame is damaged, to avoid showing trashed B-frames
ParseContext parse_context;
/* H.263 specific */
int gob_index;
int obmc; ///< overlapped block motion compensation
int mb_info; ///< interval for outputting info about mb offsets as side data
int prev_mb_info, last_mb_info;
uint8_t *mb_info_ptr;
int mb_info_size;
int ehc_mode;
int rc_strategy;
/* H.263+ specific */
int umvplus; ///< == H.263+ && unrestricted_mv
int h263_aic_dir; ///< AIC direction: 0 = left, 1 = top
int h263_slice_structured;
int alt_inter_vlc; ///< alternative inter vlc
int modified_quant;
int loop_filter;
int custom_pcf;
/* MPEG-4 specific */
///< number of bits to represent the fractional part of time (encoder only)
int time_increment_bits;
int last_time_base;
int time_base; ///< time in seconds of last I,P,S Frame
int64_t time; ///< time of current frame
int64_t last_non_b_time;
uint16_t pp_time; ///< time distance between the last 2 p,s,i frames
uint16_t pb_time; ///< time distance between the last b and p,s,i frame
uint16_t pp_field_time;
uint16_t pb_field_time; ///< like above, just for interlaced
int real_sprite_warping_points;
int sprite_offset[2][2]; ///< sprite offset[isChroma][isMVY]
int sprite_delta[2][2]; ///< sprite_delta [isY][isMVY]
int mcsel;
int quant_precision;
int quarter_sample; ///< 1->qpel, 0->half pel ME/MC
int aspect_ratio_info; //FIXME remove
int sprite_warping_accuracy;
int data_partitioning; ///< data partitioning flag from header
int partitioned_frame; ///< is current frame partitioned
int low_delay; ///< no reordering needed / has no B-frames
int vo_type;
PutBitContext tex_pb; ///< used for data partitioned VOPs
PutBitContext pb2; ///< used for data partitioned VOPs
int mpeg_quant;
int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG-4
/* divx specific, used to workaround (many) bugs in divx5 */
int divx_packed;
uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them
int bitstream_buffer_size;
unsigned int allocated_bitstream_buffer_size;
/* RV10 specific */
int rv10_version; ///< RV10 version: 0 or 3
int rv10_first_dc_coded[3];
/* MJPEG specific */
struct MJpegContext *mjpeg_ctx;
int esc_pos;
int pred;
/* MSMPEG4 specific */
int mv_table_index;
int rl_table_index;
int rl_chroma_table_index;
int dc_table_index;
int use_skip_mb_code;
int slice_height; ///< in macroblocks
int first_slice_line; ///< used in MPEG-4 too to handle resync markers
int flipflop_rounding;
int msmpeg4_version; ///< 0=not msmpeg4, 1=mp41, 2=mp42, 3=mp43/divx3 4=wmv1/7 5=wmv2/8
int per_mb_rl_table;
int esc3_level_length;
int esc3_run_length;
/** [mb_intra][isChroma][level][run][last] */
int (*ac_stats)[2][MAX_LEVEL+1][MAX_RUN+1][2];
int inter_intra_pred;
int mspel;
/* decompression specific */
GetBitContext gb;
/* MPEG-1 specific */
int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & MPEG-1 specific
int last_mv_dir; ///< last mv_dir, used for B-frame encoding
uint8_t *vbv_delay_ptr; ///< pointer to vbv_delay in the bitstream
/* MPEG-2-specific - I wished not to have to support this mess. */
int progressive_sequence;
int mpeg_f_code[2][2];
// picture structure defines are loaded from mpegutils.h
int picture_structure;
int64_t timecode_frame_start; ///< GOP timecode frame start number, in non drop frame format
int intra_dc_precision;
int frame_pred_frame_dct;
int top_field_first;
int concealment_motion_vectors;
int q_scale_type;
int brd_scale;
int intra_vlc_format;
int alternate_scan;
int seq_disp_ext;
int repeat_first_field;
int chroma_420_type;
int chroma_format;
#define CHROMA_420 1
#define CHROMA_422 2
#define CHROMA_444 3
int chroma_x_shift;//depend on pix_format, that depend on chroma_format
int chroma_y_shift;
int progressive_frame;
int full_pel[2];
int interlaced_dct;
int first_field; ///< is 1 for the first field of a field picture 0 otherwise
int drop_frame_timecode; ///< timecode is in drop frame format.
int scan_offset; ///< reserve space for SVCD scan offset user data.
/* RTP specific */
int rtp_mode;
int rtp_payload_size;
char *tc_opt_str; ///< timecode option string
AVTimecode tc; ///< timecode context
uint8_t *ptr_lastgob;
int swap_uv; //vcr2 codec is an MPEG-2 variant with U and V swapped
int pack_pblocks; //xvmc needs to keep blocks without gaps.
int16_t (*pblocks[12])[64];
int16_t (*block)[64]; ///< points to one of the following blocks
int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
int (*decode_mb)(struct MpegEncContext *s, int16_t block[6][64]); // used by some codecs to avoid a switch()
#define SLICE_OK 0
#define SLICE_ERROR -1
#define SLICE_END -2 ///<end marker found
#define SLICE_NOEND -3 ///<no end marker or error found but mb count exceeded
void (*dct_unquantize_mpeg1_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg1_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg2_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_mpeg2_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_intra)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_intra)(struct MpegEncContext *s, // unquantizer to use (MPEG-4 can use both)
int16_t *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_inter)(struct MpegEncContext *s, // unquantizer to use (MPEG-4 can use both)
int16_t *block/*align 16*/, int n, int qscale);
int (*dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
int (*fast_dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
void (*denoise_dct)(struct MpegEncContext *s, int16_t *block);
int mpv_flags; ///< flags set by private options
int quantizer_noise_shaping;
/**
* ratecontrol qmin qmax limiting method
* 0-> clipping, 1-> use a nice continuous function to limit qscale within qmin/qmax.
*/
float rc_qsquish;
float rc_qmod_amp;
int rc_qmod_freq;
float rc_initial_cplx;
float rc_buffer_aggressivity;
float border_masking;
int lmin, lmax;
int vbv_ignore_qmax;
char *rc_eq;
/* temp buffers for rate control */
float *cplx_tab, *bits_tab;
/* flag to indicate a reinitialization is required, e.g. after
* a frame size change */
int context_reinit;
ERContext er;
int error_rate;
/* temporary frames used by b_frame_strategy = 2 */
AVFrame *tmp_frames[MAX_B_FRAMES + 2];
int b_frame_strategy;
int b_sensitivity;
/* frame skip options for encoding */
int frame_skip_threshold;
int frame_skip_factor;
int frame_skip_exp;
int frame_skip_cmp;
int scenechange_threshold;
int noise_reduction;
} MpegEncContext;
/* mpegvideo_enc common options */
#define FF_MPV_FLAG_SKIP_RD 0x0001
#define FF_MPV_FLAG_STRICT_GOP 0x0002
#define FF_MPV_FLAG_QP_RD 0x0004
#define FF_MPV_FLAG_CBP_RD 0x0008
#define FF_MPV_FLAG_NAQ 0x0010
#define FF_MPV_FLAG_MV0 0x0020
enum rc_strategy {
MPV_RC_STRATEGY_FFMPEG,
MPV_RC_STRATEGY_XVID,
NB_MPV_RC_STRATEGY
};
#define FF_MPV_OPT_CMP_FUNC \
{ "sad", "Sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "sse", "Sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "satd", "Sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "dct", "Sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "psnr", "Sum of squared quantization errors, low quality", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "bit", "Number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "rd", "Rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "zero", "Zero", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "vsad", "Sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "vsse", "Sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "nsse", "Noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "dct264", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT264 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }
#ifndef FF_MPV_OFFSET
#define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
#endif
#define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
#define FF_MPV_COMMON_OPTS \
FF_MPV_OPT_CMP_FUNC, \
{ "mpv_flags", "Flags common for all mpegvideo-based encoders.", FF_MPV_OFFSET(mpv_flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "skip_rd", "RD optimal MB level residual skipping", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_SKIP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "strict_gop", "Strictly enforce gop size", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_STRICT_GOP }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "qp_rd", "Use rate distortion optimization for qp selection", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_QP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "cbp_rd", "use rate distortion optimization for CBP", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_CBP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "naq", "normalize adaptive quantization", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_NAQ }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "mv0", "always try a mb with mv=<0,0>", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_MV0 }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
{ "luma_elim_threshold", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)",\
FF_MPV_OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
{ "chroma_elim_threshold", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)",\
FF_MPV_OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
{ "quantizer_noise_shaping", NULL, FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },\
{ "error_rate", "Simulate errors in the bitstream to test error concealment.", \
FF_MPV_OFFSET(error_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },\
{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", \
FF_MPV_OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, 99, FF_MPV_OPT_FLAGS}, \
{"rc_qmod_amp", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
{"rc_qmod_freq", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS}, \
{"rc_eq", "Set rate control equation. When computing the expression, besides the standard functions " \
"defined in the section 'Expression Evaluation', the following functions are available: " \
"bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv " \
"fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.", \
FF_MPV_OFFSET(rc_eq), AV_OPT_TYPE_STRING, .flags = FF_MPV_OPT_FLAGS }, \
{"rc_init_cplx", "initial complexity for 1-pass encoding", FF_MPV_OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
{"rc_buf_aggressivity", "currently useless", FF_MPV_OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
{"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
{"lmin", "minimum Lagrange factor (VBR)", FF_MPV_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"lmax", "maximum Lagrange factor (VBR)", FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"ibias", "intra quant bias", FF_MPV_OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"pbias", "inter quant bias", FF_MPV_OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"rc_strategy", "ratecontrol method", FF_MPV_OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = MPV_RC_STRATEGY_FFMPEG }, 0, NB_MPV_RC_STRATEGY-1, FF_MPV_OPT_FLAGS, "rc_strategy" }, \
{ "ffmpeg", "default native rate control", 0, AV_OPT_TYPE_CONST, { .i64 = MPV_RC_STRATEGY_FFMPEG }, 0, 0, FF_MPV_OPT_FLAGS, "rc_strategy" }, \
{ "xvid", "libxvid (2 pass only)", 0, AV_OPT_TYPE_CONST, { .i64 = MPV_RC_STRATEGY_XVID }, 0, 0, FF_MPV_OPT_FLAGS, "rc_strategy" }, \
{"motion_est", "motion estimation algorithm", FF_MPV_OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, "motion_est" }, \
{ "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \
{ "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \
{ "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \
{ "force_duplicated_matrix", "Always write luma and chroma matrix for mjpeg, useful for rtp streaming.", FF_MPV_OFFSET(force_duplicated_matrix), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS }, \
{"b_strategy", "Strategy to choose between I/P/B-frames", FF_MPV_OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, FF_MPV_OPT_FLAGS }, \
{"b_sensitivity", "Adjust sensitivity of b_frame_strategy 1", FF_MPV_OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"brd_scale", "Downscale frames for dynamic B-frame decision", FF_MPV_OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 3, FF_MPV_OPT_FLAGS }, \
{"skip_threshold", "Frame skip threshold", FF_MPV_OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"skip_factor", "Frame skip factor", FF_MPV_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"skip_exp", "Frame skip exponent", FF_MPV_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"skip_cmp", "Frame skip compare function", FF_MPV_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{"sc_threshold", "Scene change threshold", FF_MPV_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"noise_reduction", "Noise reduction", FF_MPV_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"mpeg_quant", "Use MPEG quantizers instead of H.263", FF_MPV_OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS }, \
{"ps", "RTP payload size in bytes", FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"mepc", "Motion estimation bitrate penalty compensation (1.0 = 256)", FF_MPV_OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
{"mepre", "pre motion estimation", FF_MPV_OFFSET(me_pre), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
extern const AVOption ff_mpv_generic_options[];
/**
* Set the given MpegEncContext to common defaults (same for encoding
* and decoding). The changed fields will not depend upon the prior
* state of the MpegEncContext.
*/
void ff_mpv_common_defaults(MpegEncContext *s);
void ff_dct_encode_init_x86(MpegEncContext *s);
int ff_mpv_common_init(MpegEncContext *s);
void ff_mpv_common_init_arm(MpegEncContext *s);
void ff_mpv_common_init_axp(MpegEncContext *s);
void ff_mpv_common_init_neon(MpegEncContext *s);
void ff_mpv_common_init_ppc(MpegEncContext *s);
void ff_mpv_common_init_x86(MpegEncContext *s);
void ff_mpv_common_init_mips(MpegEncContext *s);
int ff_mpv_common_frame_size_change(MpegEncContext *s);
void ff_mpv_common_end(MpegEncContext *s);
void ff_mpv_decode_defaults(MpegEncContext *s);
void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx);
void ff_mpv_decode_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);
void ff_mpv_frame_end(MpegEncContext *s);
int ff_mpv_encode_init(AVCodecContext *avctx);
void ff_mpv_encode_init_x86(MpegEncContext *s);
int ff_mpv_encode_end(AVCodecContext *avctx);
int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *frame, int *got_packet);
int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t size_increase);
void ff_clean_intra_table_entries(MpegEncContext *s);
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h);
void ff_mpeg_flush(AVCodecContext *avctx);
void ff_print_debug_info(MpegEncContext *s, Picture *p, AVFrame *pict);
void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_table,
uint32_t *mbtype_table, int8_t *qscale_table, int16_t (*motion_val[2])[2],
int *low_delay,
int mb_width, int mb_height, int mb_stride, int quarter_sample);
int ff_mpv_export_qp_table(MpegEncContext *s, AVFrame *f, Picture *p, int qp_type);
void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix);
int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src);
void ff_set_qscale(MpegEncContext * s, int qscale);
void ff_mpv_idct_init(MpegEncContext *s);
int ff_dct_encode_init(MpegEncContext *s);
void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64], uint16_t (*qmat16)[2][64],
const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra);
int ff_dct_quantize_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
void ff_block_permute(int16_t *block, uint8_t *permutation,
const uint8_t *scantable, int last);
void ff_init_block_index(MpegEncContext *s);
void ff_mpv_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb,
uint8_t *dest_cr, int dir,
uint8_t **ref_picture,
op_pixels_func (*pix_op)[4],
qpel_mc_func (*qpix_op)[16]);
static inline void ff_update_block_index(MpegEncContext *s){
const int block_size= 8 >> s->avctx->lowres;
s->block_index[0]+=2;
s->block_index[1]+=2;
s->block_index[2]+=2;
s->block_index[3]+=2;
s->block_index[4]++;
s->block_index[5]++;
s->dest[0]+= 2*block_size;
s->dest[1]+= block_size;
s->dest[2]+= block_size;
}
static inline int get_bits_diff(MpegEncContext *s){
const int bits= put_bits_count(&s->pb);
const int last= s->last_bits;
s->last_bits = bits;
return bits - last;
}
#endif /* AVCODEC_MPEGVIDEO_H */

View file

@ -0,0 +1,47 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_MPEGVIDEODSP_H
#define AVCODEC_MPEGVIDEODSP_H
#include <stdint.h>
void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy,
int dxx, int dxy, int dyx, int dyy, int shift, int r,
int width, int height);
typedef struct MpegVideoDSPContext {
/**
* translational global motion compensation.
*/
void (*gmc1)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */,
int srcStride, int h, int x16, int y16, int rounder);
/**
* global motion compensation.
*/
void (*gmc)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */,
int stride, int h, int ox, int oy,
int dxx, int dxy, int dyx, int dyy,
int shift, int r, int width, int height);
} MpegVideoDSPContext;
void ff_mpegvideodsp_init(MpegVideoDSPContext *c);
void ff_mpegvideodsp_init_ppc(MpegVideoDSPContext *c);
void ff_mpegvideodsp_init_x86(MpegVideoDSPContext *c);
#endif /* AVCODEC_MPEGVIDEODSP_H */

View file

@ -0,0 +1,58 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_MPEGVIDEOENCDSP_H
#define AVCODEC_MPEGVIDEOENCDSP_H
#include <stdint.h>
#include "avcodec.h"
#define BASIS_SHIFT 16
#define RECON_SHIFT 6
#define EDGE_TOP 1
#define EDGE_BOTTOM 2
typedef struct MpegvideoEncDSPContext {
int (*try_8x8basis)(int16_t rem[64], int16_t weight[64],
int16_t basis[64], int scale);
void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale);
int (*pix_sum)(uint8_t *pix, int line_size);
int (*pix_norm1)(uint8_t *pix, int line_size);
void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src,
int src_wrap, int width, int height);
void (*draw_edges)(uint8_t *buf, int wrap, int width, int height,
int w, int h, int sides);
} MpegvideoEncDSPContext;
void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c,
AVCodecContext *avctx);
void ff_mpegvideoencdsp_init_arm(MpegvideoEncDSPContext *c,
AVCodecContext *avctx);
void ff_mpegvideoencdsp_init_ppc(MpegvideoEncDSPContext *c,
AVCodecContext *avctx);
void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c,
AVCodecContext *avctx);
void ff_mpegvideoencdsp_init_mips(MpegvideoEncDSPContext *c,
AVCodecContext *avctx);
#endif /* AVCODEC_MPEGVIDEOENCDSP_H */

View file

@ -0,0 +1,503 @@
/*
* 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
*/
/**
* @file
* Options definition for AVCodecContext.
*/
#include "avcodec.h"
#include "internal.h"
#include "libavutil/avassert.h"
#include "libavutil/internal.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include <float.h> /* FLT_MIN, FLT_MAX */
#include <string.h>
FF_DISABLE_DEPRECATION_WARNINGS
#include "ff_options_table.h"
FF_ENABLE_DEPRECATION_WARNINGS
static const char* context_to_name(void* ptr) {
AVCodecContext *avc= ptr;
if(avc && avc->codec && avc->codec->name)
return avc->codec->name;
else
return "NULL";
}
static void *codec_child_next(void *obj, void *prev)
{
AVCodecContext *s = obj;
if (!prev && s->codec && s->codec->priv_class && s->priv_data)
return s->priv_data;
return NULL;
}
static const AVClass *codec_child_class_next(const AVClass *prev)
{
AVCodec *c = NULL;
/* find the codec that corresponds to prev */
while (prev && (c = av_codec_next(c)))
if (c->priv_class == prev)
break;
/* find next codec with priv options */
while (c = av_codec_next(c))
if (c->priv_class)
return c->priv_class;
return NULL;
}
static AVClassCategory get_category(void *ptr)
{
AVCodecContext* avctx = ptr;
if(avctx->codec && avctx->codec->decode) return AV_CLASS_CATEGORY_DECODER;
else return AV_CLASS_CATEGORY_ENCODER;
}
static const AVClass av_codec_context_class = {
.class_name = "AVCodecContext",
.item_name = context_to_name,
.option = avcodec_options,
.version = LIBAVUTIL_VERSION_INT,
.log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
.child_next = codec_child_next,
.child_class_next = codec_child_class_next,
.category = AV_CLASS_CATEGORY_ENCODER,
.get_category = get_category,
};
static int init_context_defaults(AVCodecContext *s, const AVCodec *codec)
{
int flags=0;
memset(s, 0, sizeof(AVCodecContext));
s->av_class = &av_codec_context_class;
s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
if (codec) {
s->codec = codec;
s->codec_id = codec->id;
}
if(s->codec_type == AVMEDIA_TYPE_AUDIO)
flags= AV_OPT_FLAG_AUDIO_PARAM;
else if(s->codec_type == AVMEDIA_TYPE_VIDEO)
flags= AV_OPT_FLAG_VIDEO_PARAM;
else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE)
flags= AV_OPT_FLAG_SUBTITLE_PARAM;
av_opt_set_defaults2(s, flags, flags);
s->time_base = (AVRational){0,1};
s->framerate = (AVRational){ 0, 1 };
s->pkt_timebase = (AVRational){ 0, 1 };
s->get_buffer2 = avcodec_default_get_buffer2;
s->get_format = avcodec_default_get_format;
s->execute = avcodec_default_execute;
s->execute2 = avcodec_default_execute2;
s->sample_aspect_ratio = (AVRational){0,1};
s->pix_fmt = AV_PIX_FMT_NONE;
s->sample_fmt = AV_SAMPLE_FMT_NONE;
s->reordered_opaque = AV_NOPTS_VALUE;
if(codec && codec->priv_data_size){
if(!s->priv_data){
s->priv_data= av_mallocz(codec->priv_data_size);
if (!s->priv_data) {
return AVERROR(ENOMEM);
}
}
if(codec->priv_class){
*(const AVClass**)s->priv_data = codec->priv_class;
av_opt_set_defaults(s->priv_data);
}
}
if (codec && codec->defaults) {
int ret;
const AVCodecDefault *d = codec->defaults;
while (d->key) {
ret = av_opt_set(s, d->key, d->value, 0);
av_assert0(ret >= 0);
d++;
}
}
return 0;
}
#if FF_API_GET_CONTEXT_DEFAULTS
int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
{
return init_context_defaults(s, codec);
}
#endif
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
{
AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
if (!avctx)
return NULL;
if (init_context_defaults(avctx, codec) < 0) {
av_free(avctx);
return NULL;
}
return avctx;
}
void avcodec_free_context(AVCodecContext **pavctx)
{
AVCodecContext *avctx = *pavctx;
if (!avctx)
return;
avcodec_close(avctx);
av_freep(&avctx->extradata);
av_freep(&avctx->subtitle_header);
av_freep(&avctx->intra_matrix);
av_freep(&avctx->inter_matrix);
av_freep(&avctx->rc_override);
av_freep(pavctx);
}
#if FF_API_COPY_CONTEXT
int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
{
const AVCodec *orig_codec = dest->codec;
uint8_t *orig_priv_data = dest->priv_data;
if (avcodec_is_open(dest)) { // check that the dest context is uninitialized
av_log(dest, AV_LOG_ERROR,
"Tried to copy AVCodecContext %p into already-initialized %p\n",
src, dest);
return AVERROR(EINVAL);
}
av_opt_free(dest);
av_freep(&dest->rc_override);
av_freep(&dest->intra_matrix);
av_freep(&dest->inter_matrix);
av_freep(&dest->extradata);
av_freep(&dest->subtitle_header);
memcpy(dest, src, sizeof(*dest));
av_opt_copy(dest, src);
dest->priv_data = orig_priv_data;
dest->codec = orig_codec;
if (orig_priv_data && src->codec && src->codec->priv_class &&
dest->codec && dest->codec->priv_class)
av_opt_copy(orig_priv_data, src->priv_data);
/* set values specific to opened codecs back to their default state */
dest->slice_offset = NULL;
dest->hwaccel = NULL;
dest->internal = NULL;
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
dest->coded_frame = NULL;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
/* reallocate values that should be allocated separately */
dest->extradata = NULL;
dest->intra_matrix = NULL;
dest->inter_matrix = NULL;
dest->rc_override = NULL;
dest->subtitle_header = NULL;
dest->hw_frames_ctx = NULL;
#define alloc_and_copy_or_fail(obj, size, pad) \
if (src->obj && size > 0) { \
dest->obj = av_malloc(size + pad); \
if (!dest->obj) \
goto fail; \
memcpy(dest->obj, src->obj, size); \
if (pad) \
memset(((uint8_t *) dest->obj) + size, 0, pad); \
}
alloc_and_copy_or_fail(extradata, src->extradata_size,
AV_INPUT_BUFFER_PADDING_SIZE);
dest->extradata_size = src->extradata_size;
alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0);
alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0);
alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0);
alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1);
av_assert0(dest->subtitle_header_size == src->subtitle_header_size);
#undef alloc_and_copy_or_fail
if (src->hw_frames_ctx) {
dest->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
if (!dest->hw_frames_ctx)
goto fail;
}
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);
return AVERROR(ENOMEM);
}
#endif
const AVClass *avcodec_get_class(void)
{
return &av_codec_context_class;
}
#define FOFFSET(x) offsetof(AVFrame,x)
static const AVOption frame_options[]={
{"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0},
{"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
{"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
{"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
{"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
{"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
{"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0},
{"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0},
{"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
{NULL},
};
static const AVClass av_frame_class = {
.class_name = "AVFrame",
.item_name = NULL,
.option = frame_options,
.version = LIBAVUTIL_VERSION_INT,
};
const AVClass *avcodec_get_frame_class(void)
{
return &av_frame_class;
}
#define SROFFSET(x) offsetof(AVSubtitleRect,x)
static const AVOption subtitle_rect_options[]={
{"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
{"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
{"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
{"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
{"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"},
{"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0},
{NULL},
};
static const AVClass av_subtitle_rect_class = {
.class_name = "AVSubtitleRect",
.item_name = NULL,
.option = subtitle_rect_options,
.version = LIBAVUTIL_VERSION_INT,
};
const AVClass *avcodec_get_subtitle_rect_class(void)
{
return &av_subtitle_rect_class;
}
#ifdef TEST
static int dummy_init(AVCodecContext *ctx)
{
//TODO: this code should set every possible pointer that could be set by codec and is not an option;
ctx->extradata_size = 8;
ctx->extradata = av_malloc(ctx->extradata_size);
return 0;
}
static int dummy_close(AVCodecContext *ctx)
{
av_freep(&ctx->extradata);
ctx->extradata_size = 0;
return 0;
}
static int dummy_encode(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
{
return AVERROR(ENOSYS);
}
typedef struct Dummy12Context {
AVClass *av_class;
int num;
char* str;
} Dummy12Context;
typedef struct Dummy3Context {
void *fake_av_class;
int num;
char* str;
} Dummy3Context;
#define OFFSET(x) offsetof(Dummy12Context, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption dummy_options[] = {
{ "str", "set str", OFFSET(str), AV_OPT_TYPE_STRING, { .str = "i'm src default value" }, 0, 0, VE},
{ "num", "set num", OFFSET(num), AV_OPT_TYPE_INT, { .i64 = 1500100900 }, 0, INT_MAX, VE},
{ NULL },
};
static const AVClass dummy_v1_class = {
.class_name = "dummy_v1_class",
.item_name = av_default_item_name,
.option = dummy_options,
.version = LIBAVUTIL_VERSION_INT,
};
static const AVClass dummy_v2_class = {
.class_name = "dummy_v2_class",
.item_name = av_default_item_name,
.option = dummy_options,
.version = LIBAVUTIL_VERSION_INT,
};
/* codec with options */
static AVCodec dummy_v1_encoder = {
.name = "dummy_v1_codec",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_NONE - 1,
.encode2 = dummy_encode,
.init = dummy_init,
.close = dummy_close,
.priv_class = &dummy_v1_class,
.priv_data_size = sizeof(Dummy12Context),
};
/* codec with options, different class */
static AVCodec dummy_v2_encoder = {
.name = "dummy_v2_codec",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_NONE - 2,
.encode2 = dummy_encode,
.init = dummy_init,
.close = dummy_close,
.priv_class = &dummy_v2_class,
.priv_data_size = sizeof(Dummy12Context),
};
/* codec with priv data, but no class */
static AVCodec dummy_v3_encoder = {
.name = "dummy_v3_codec",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_NONE - 3,
.encode2 = dummy_encode,
.init = dummy_init,
.close = dummy_close,
.priv_data_size = sizeof(Dummy3Context),
};
/* codec without priv data */
static AVCodec dummy_v4_encoder = {
.name = "dummy_v4_codec",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_NONE - 4,
.encode2 = dummy_encode,
.init = dummy_init,
.close = dummy_close,
};
static void test_copy_print_codec(const AVCodecContext *ctx)
{
printf("%-14s: %dx%d prv: %s",
ctx->codec ? ctx->codec->name : "NULL",
ctx->width, ctx->height,
ctx->priv_data ? "set" : "null");
if (ctx->codec && ctx->codec->priv_class && ctx->codec->priv_data_size) {
int64_t i64;
char *str = NULL;
av_opt_get_int(ctx->priv_data, "num", 0, &i64);
av_opt_get(ctx->priv_data, "str", 0, (uint8_t**)&str);
printf(" opts: %"PRId64" %s", i64, str);
av_free(str);
}
printf("\n");
}
static void test_copy(const AVCodec *c1, const AVCodec *c2)
{
AVCodecContext *ctx1, *ctx2;
printf("%s -> %s\nclosed:\n", c1 ? c1->name : "NULL", c2 ? c2->name : "NULL");
ctx1 = avcodec_alloc_context3(c1);
ctx2 = avcodec_alloc_context3(c2);
ctx1->width = ctx1->height = 128;
if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
av_opt_set(ctx2->priv_data, "num", "667", 0);
av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
}
avcodec_copy_context(ctx2, ctx1);
test_copy_print_codec(ctx1);
test_copy_print_codec(ctx2);
if (ctx1->codec) {
printf("opened:\n");
avcodec_open2(ctx1, ctx1->codec, NULL);
if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
av_opt_set(ctx2->priv_data, "num", "667", 0);
av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
}
avcodec_copy_context(ctx2, ctx1);
test_copy_print_codec(ctx1);
test_copy_print_codec(ctx2);
avcodec_close(ctx1);
}
avcodec_free_context(&ctx1);
avcodec_free_context(&ctx2);
}
int main(void)
{
AVCodec *dummy_codec[] = {
&dummy_v1_encoder,
&dummy_v2_encoder,
&dummy_v3_encoder,
&dummy_v4_encoder,
NULL,
};
int i, j;
for (i = 0; dummy_codec[i]; i++)
avcodec_register(dummy_codec[i]);
printf("testing avcodec_copy_context()\n");
for (i = 0; i < FF_ARRAY_ELEMS(dummy_codec); i++)
for (j = 0; j < FF_ARRAY_ELEMS(dummy_codec); j++)
test_copy(dummy_codec[i], dummy_codec[j]);
return 0;
}
#endif

View file

@ -0,0 +1,340 @@
/*
* Audio and Video frame extraction
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2003 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include <string.h>
#include "libavutil/avassert.h"
#include "libavutil/atomic.h"
#include "libavutil/internal.h"
#include "libavutil/mem.h"
#include "internal.h"
#include "parser.h"
static AVCodecParser *av_first_parser = NULL;
AVCodecParser *av_parser_next(const AVCodecParser *p)
{
if (p)
return p->next;
else
return av_first_parser;
}
void av_register_codec_parser(AVCodecParser *parser)
{
do {
parser->next = av_first_parser;
} while (parser->next != avpriv_atomic_ptr_cas((void * volatile *)&av_first_parser, parser->next, parser));
}
AVCodecParserContext *av_parser_init(int codec_id)
{
AVCodecParserContext *s = NULL;
AVCodecParser *parser;
int ret;
if (codec_id == AV_CODEC_ID_NONE)
return NULL;
for (parser = av_first_parser; parser; parser = parser->next) {
if (parser->codec_ids[0] == codec_id ||
parser->codec_ids[1] == codec_id ||
parser->codec_ids[2] == codec_id ||
parser->codec_ids[3] == codec_id ||
parser->codec_ids[4] == codec_id)
goto found;
}
return NULL;
found:
s = av_mallocz(sizeof(AVCodecParserContext));
if (!s)
goto err_out;
s->parser = parser;
s->priv_data = av_mallocz(parser->priv_data_size);
if (!s->priv_data)
goto err_out;
s->fetch_timestamp=1;
s->pict_type = AV_PICTURE_TYPE_I;
if (parser->parser_init) {
ret = parser->parser_init(s);
if (ret != 0)
goto err_out;
}
s->key_frame = -1;
#if FF_API_CONVERGENCE_DURATION
FF_DISABLE_DEPRECATION_WARNINGS
s->convergence_duration = 0;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
s->dts_sync_point = INT_MIN;
s->dts_ref_dts_delta = INT_MIN;
s->pts_dts_delta = INT_MIN;
s->format = -1;
return s;
err_out:
if (s)
av_freep(&s->priv_data);
av_free(s);
return NULL;
}
void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove, int fuzzy)
{
int i;
if (!fuzzy) {
s->dts =
s->pts = AV_NOPTS_VALUE;
s->pos = -1;
s->offset = 0;
}
for (i = 0; i < AV_PARSER_PTS_NB; i++) {
if (s->cur_offset + off >= s->cur_frame_offset[i] &&
(s->frame_offset < s->cur_frame_offset[i] ||
(!s->frame_offset && !s->next_frame_offset)) && // first field/frame
// check disabled since MPEG-TS does not send complete PES packets
/*s->next_frame_offset + off <*/ s->cur_frame_end[i]){
if (!fuzzy || s->cur_frame_dts[i] != AV_NOPTS_VALUE) {
s->dts = s->cur_frame_dts[i];
s->pts = s->cur_frame_pts[i];
s->pos = s->cur_frame_pos[i];
s->offset = s->next_frame_offset - s->cur_frame_offset[i];
}
if (remove)
s->cur_frame_offset[i] = INT64_MAX;
if (s->cur_offset + off < s->cur_frame_end[i])
break;
}
}
}
int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size,
int64_t pts, int64_t dts, int64_t pos)
{
int index, i;
uint8_t dummy_buf[AV_INPUT_BUFFER_PADDING_SIZE];
av_assert1(avctx->codec_id != AV_CODEC_ID_NONE);
/* Parsers only work for the specified codec ids. */
av_assert1(avctx->codec_id == s->parser->codec_ids[0] ||
avctx->codec_id == s->parser->codec_ids[1] ||
avctx->codec_id == s->parser->codec_ids[2] ||
avctx->codec_id == s->parser->codec_ids[3] ||
avctx->codec_id == s->parser->codec_ids[4]);
if (!(s->flags & PARSER_FLAG_FETCHED_OFFSET)) {
s->next_frame_offset =
s->cur_offset = pos;
s->flags |= PARSER_FLAG_FETCHED_OFFSET;
}
if (buf_size == 0) {
/* padding is always necessary even if EOF, so we add it here */
memset(dummy_buf, 0, sizeof(dummy_buf));
buf = dummy_buf;
} else if (s->cur_offset + buf_size != s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */
/* add a new packet descriptor */
i = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
s->cur_frame_start_index = i;
s->cur_frame_offset[i] = s->cur_offset;
s->cur_frame_end[i] = s->cur_offset + buf_size;
s->cur_frame_pts[i] = pts;
s->cur_frame_dts[i] = dts;
s->cur_frame_pos[i] = pos;
}
if (s->fetch_timestamp) {
s->fetch_timestamp = 0;
s->last_pts = s->pts;
s->last_dts = s->dts;
s->last_pos = s->pos;
ff_fetch_timestamp(s, 0, 0, 0);
}
/* WARNING: the returned index can be negative */
index = s->parser->parser_parse(s, avctx, (const uint8_t **) poutbuf,
poutbuf_size, buf, buf_size);
av_assert0(index > -0x20000000); // The API does not allow returning AVERROR codes
/* update the file pointer */
if (*poutbuf_size) {
/* fill the data for the current frame */
s->frame_offset = s->next_frame_offset;
/* offset of the next frame */
s->next_frame_offset = s->cur_offset + index;
s->fetch_timestamp = 1;
}
if (index < 0)
index = 0;
s->cur_offset += index;
return index;
}
int av_parser_change(AVCodecParserContext *s, AVCodecContext *avctx,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size, int keyframe)
{
if (s && s->parser->split) {
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER ||
avctx->flags2 & AV_CODEC_FLAG2_LOCAL_HEADER) {
int i = s->parser->split(avctx, buf, buf_size);
buf += i;
buf_size -= i;
}
}
/* cast to avoid warning about discarding qualifiers */
*poutbuf = (uint8_t *) buf;
*poutbuf_size = buf_size;
if (avctx->extradata) {
if (keyframe && (avctx->flags2 & AV_CODEC_FLAG2_LOCAL_HEADER)) {
int size = buf_size + avctx->extradata_size;
*poutbuf_size = size;
*poutbuf = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!*poutbuf)
return AVERROR(ENOMEM);
memcpy(*poutbuf, avctx->extradata, avctx->extradata_size);
memcpy(*poutbuf + avctx->extradata_size, buf,
buf_size + AV_INPUT_BUFFER_PADDING_SIZE);
return 1;
}
}
return 0;
}
void av_parser_close(AVCodecParserContext *s)
{
if (s) {
if (s->parser->parser_close)
s->parser->parser_close(s);
av_freep(&s->priv_data);
av_free(s);
}
}
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",
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]);
}
/* Copy overread bytes from last frame into buffer. */
for (; pc->overread > 0; pc->overread--)
pc->buffer[pc->index++] = pc->buffer[pc->overread_index++];
/* flush remaining if EOF */
if (!*buf_size && next == END_NOT_FOUND)
next = 0;
pc->last_index = pc->index;
/* copy into buffer end return */
if (next == END_NOT_FOUND) {
void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
*buf_size + pc->index +
AV_INPUT_BUFFER_PADDING_SIZE);
if (!new_buffer) {
av_log(NULL, AV_LOG_ERROR, "Failed to reallocate parser buffer to %d\n", *buf_size + pc->index + AV_INPUT_BUFFER_PADDING_SIZE);
pc->index = 0;
return AVERROR(ENOMEM);
}
pc->buffer = new_buffer;
memcpy(&pc->buffer[pc->index], *buf, *buf_size);
pc->index += *buf_size;
return -1;
}
*buf_size =
pc->overread_index = pc->index + next;
/* append to buffer */
if (pc->index) {
void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
next + pc->index +
AV_INPUT_BUFFER_PADDING_SIZE);
if (!new_buffer) {
av_log(NULL, AV_LOG_ERROR, "Failed to reallocate parser buffer to %d\n", next + pc->index + AV_INPUT_BUFFER_PADDING_SIZE);
pc->overread_index =
pc->index = 0;
return AVERROR(ENOMEM);
}
pc->buffer = new_buffer;
if (next > -AV_INPUT_BUFFER_PADDING_SIZE)
memcpy(&pc->buffer[pc->index], *buf,
next + AV_INPUT_BUFFER_PADDING_SIZE);
pc->index = 0;
*buf = pc->buffer;
}
/* store overread bytes */
for (; next < 0; next++) {
pc->state = pc->state << 8 | pc->buffer[pc->last_index + next];
pc->state64 = pc->state64 << 8 | pc->buffer[pc->last_index + next];
pc->overread++;
}
if (pc->overread) {
ff_dlog(NULL, "overread %d, state:%X 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]);
}
return 0;
}
void ff_parse_close(AVCodecParserContext *s)
{
ParseContext *pc = s->priv_data;
av_freep(&pc->buffer);
}
int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
{
uint32_t state = -1;
const uint8_t *ptr = buf, *end = buf + buf_size;
while (ptr < end) {
ptr = avpriv_find_start_code(ptr, end, &state);
if (state == 0x1B3 || state == 0x1B6)
return ptr - 4 - buf;
}
return 0;
}

View file

@ -0,0 +1,60 @@
/*
* AVCodecParser prototypes and definitions
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2003 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_PARSER_H
#define AVCODEC_PARSER_H
#include "avcodec.h"
typedef struct ParseContext{
uint8_t *buffer;
int index;
int last_index;
unsigned int buffer_size;
uint32_t state; ///< contains the last few bytes in MSB order
int frame_start_found;
int overread; ///< the number of bytes which where irreversibly read from the next frame
int overread_index; ///< the index into ParseContext.buffer of the overread bytes
uint64_t state64; ///< contains the last 8 bytes in MSB order
} ParseContext;
#define END_NOT_FOUND (-100)
/**
* Combine the (truncated) bitstream to a complete frame.
* @return -1 if no complete frame could be created,
* AVERROR(ENOMEM) if there was a memory allocation error
*/
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size);
int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf,
int buf_size);
void ff_parse_close(AVCodecParserContext *s);
/**
* Fetch timestamps for a specific byte within the current access unit.
* @param off byte position within the access unit
* @param remove Found timestamps will be removed if set to 1, kept if set to 0.
* @param fuzzy Only use found value if it is more informative than what we already have
*/
void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove, int fuzzy);
#endif /* AVCODEC_PARSER_H */

View file

@ -0,0 +1,48 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_PIXBLOCKDSP_H
#define AVCODEC_PIXBLOCKDSP_H
#include <stdint.h>
#include "avcodec.h"
typedef struct PixblockDSPContext {
void (*get_pixels)(int16_t *block /* align 16 */,
const uint8_t *pixels /* align 8 */,
ptrdiff_t line_size);
void (*diff_pixels)(int16_t *block /* align 16 */,
const uint8_t *s1 /* align 8 */,
const uint8_t *s2 /* align 8 */,
int stride);
} PixblockDSPContext;
void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx);
void ff_pixblockdsp_init_alpha(PixblockDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_pixblockdsp_init_arm(PixblockDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_pixblockdsp_init_ppc(PixblockDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_pixblockdsp_init_x86(PixblockDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
void ff_pixblockdsp_init_mips(PixblockDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth);
#endif /* AVCODEC_PIXBLOCKDSP_H */

View file

@ -0,0 +1,131 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "avcodec.h"
#include "profiles.h"
#if !CONFIG_SMALL
const AVProfile ff_aac_profiles[] = {
{ FF_PROFILE_AAC_LOW, "LC" },
{ FF_PROFILE_AAC_HE, "HE-AAC" },
{ FF_PROFILE_AAC_HE_V2, "HE-AACv2" },
{ FF_PROFILE_AAC_LD, "LD" },
{ FF_PROFILE_AAC_ELD, "ELD" },
{ FF_PROFILE_AAC_MAIN, "Main" },
{ FF_PROFILE_AAC_LOW, "LC" },
{ FF_PROFILE_AAC_SSR, "SSR" },
{ FF_PROFILE_AAC_LTP, "LTP" },
{ FF_PROFILE_UNKNOWN },
};
const AVProfile ff_dca_profiles[] = {
{ FF_PROFILE_DTS, "DTS" },
{ FF_PROFILE_DTS_ES, "DTS-ES" },
{ FF_PROFILE_DTS_96_24, "DTS 96/24" },
{ FF_PROFILE_DTS_HD_HRA, "DTS-HD HRA" },
{ FF_PROFILE_DTS_HD_MA, "DTS-HD MA" },
{ FF_PROFILE_DTS_EXPRESS, "DTS Express" },
{ FF_PROFILE_UNKNOWN },
};
const AVProfile ff_h264_profiles[] = {
{ FF_PROFILE_H264_BASELINE, "Baseline" },
{ FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline" },
{ FF_PROFILE_H264_MAIN, "Main" },
{ FF_PROFILE_H264_EXTENDED, "Extended" },
{ FF_PROFILE_H264_HIGH, "High" },
{ FF_PROFILE_H264_HIGH_10, "High 10" },
{ FF_PROFILE_H264_HIGH_10_INTRA, "High 10 Intra" },
{ FF_PROFILE_H264_HIGH_422, "High 4:2:2" },
{ FF_PROFILE_H264_HIGH_422_INTRA, "High 4:2:2 Intra" },
{ FF_PROFILE_H264_HIGH_444, "High 4:4:4" },
{ 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_UNKNOWN },
};
const AVProfile ff_hevc_profiles[] = {
{ FF_PROFILE_HEVC_MAIN, "Main" },
{ FF_PROFILE_HEVC_MAIN_10, "Main 10" },
{ FF_PROFILE_HEVC_MAIN_STILL_PICTURE, "Main Still Picture" },
{ FF_PROFILE_HEVC_REXT, "Rext" },
{ FF_PROFILE_UNKNOWN },
};
const AVProfile ff_jpeg2000_profiles[] = {
{ FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0, "JPEG 2000 codestream restriction 0" },
{ FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1, "JPEG 2000 codestream restriction 1" },
{ FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION, "JPEG 2000 no codestream restrictions" },
{ FF_PROFILE_JPEG2000_DCINEMA_2K, "JPEG 2000 digital cinema 2K" },
{ FF_PROFILE_JPEG2000_DCINEMA_4K, "JPEG 2000 digital cinema 4K" },
{ FF_PROFILE_UNKNOWN },
};
const AVProfile ff_mpeg2_video_profiles[] = {
{ FF_PROFILE_MPEG2_422, "4:2:2" },
{ FF_PROFILE_MPEG2_HIGH, "High" },
{ FF_PROFILE_MPEG2_SS, "Spatially Scalable" },
{ FF_PROFILE_MPEG2_SNR_SCALABLE, "SNR Scalable" },
{ FF_PROFILE_MPEG2_MAIN, "Main" },
{ FF_PROFILE_MPEG2_SIMPLE, "Simple" },
{ FF_PROFILE_RESERVED, "Reserved" },
{ FF_PROFILE_RESERVED, "Reserved" },
{ FF_PROFILE_UNKNOWN },
};
const AVProfile ff_mpeg4_video_profiles[] = {
{ FF_PROFILE_MPEG4_SIMPLE, "Simple Profile" },
{ FF_PROFILE_MPEG4_SIMPLE_SCALABLE, "Simple Scalable Profile" },
{ FF_PROFILE_MPEG4_CORE, "Core Profile" },
{ FF_PROFILE_MPEG4_MAIN, "Main Profile" },
{ FF_PROFILE_MPEG4_N_BIT, "N-bit Profile" },
{ FF_PROFILE_MPEG4_SCALABLE_TEXTURE, "Scalable Texture Profile" },
{ FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION, "Simple Face Animation Profile" },
{ FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE, "Basic Animated Texture Profile" },
{ FF_PROFILE_MPEG4_HYBRID, "Hybrid Profile" },
{ FF_PROFILE_MPEG4_ADVANCED_REAL_TIME, "Advanced Real Time Simple Profile" },
{ FF_PROFILE_MPEG4_CORE_SCALABLE, "Code Scalable Profile" },
{ FF_PROFILE_MPEG4_ADVANCED_CODING, "Advanced Coding Profile" },
{ FF_PROFILE_MPEG4_ADVANCED_CORE, "Advanced Core Profile" },
{ FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE, "Advanced Scalable Texture Profile" },
{ FF_PROFILE_MPEG4_SIMPLE_STUDIO, "Simple Studio Profile" },
{ FF_PROFILE_MPEG4_ADVANCED_SIMPLE, "Advanced Simple Profile" },
{ FF_PROFILE_UNKNOWN },
};
const AVProfile ff_vc1_profiles[] = {
{ FF_PROFILE_VC1_SIMPLE, "Simple" },
{ FF_PROFILE_VC1_MAIN, "Main" },
{ FF_PROFILE_VC1_COMPLEX, "Complex" },
{ FF_PROFILE_VC1_ADVANCED, "Advanced" },
{ FF_PROFILE_UNKNOWN },
};
const AVProfile ff_vp9_profiles[] = {
{ FF_PROFILE_VP9_0, "Profile 0" },
{ FF_PROFILE_VP9_1, "Profile 1" },
{ FF_PROFILE_VP9_2, "Profile 2" },
{ FF_PROFILE_VP9_3, "Profile 3" },
{ FF_PROFILE_UNKNOWN },
};
#endif /* !CONFIG_SMALL */

View file

@ -0,0 +1,34 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_PROFILES_H
#define AVCODEC_PROFILES_H
#include "avcodec.h"
extern const AVProfile ff_aac_profiles[];
extern const AVProfile ff_dca_profiles[];
extern const AVProfile ff_h264_profiles[];
extern const AVProfile ff_hevc_profiles[];
extern const AVProfile ff_jpeg2000_profiles[];
extern const AVProfile ff_mpeg2_video_profiles[];
extern const AVProfile ff_mpeg4_video_profiles[];
extern const AVProfile ff_vc1_profiles[];
extern const AVProfile ff_vp9_profiles[];
#endif /* AVCODEC_PROFILES_H */

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2004 Roman Shaposhnik
* Copyright (c) 2008 Alexander Strange (astrange@ithinksw.com)
*
* Many thanks to Steven M. Schultz for providing clever ideas and
* to Michael Niedermayer <michaelni@gmx.at> for writing initial
* implementation.
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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
* Multithreading support functions
* @see doc/multithreading.txt
*/
#include "avcodec.h"
#include "internal.h"
#include "pthread_internal.h"
#include "thread.h"
/**
* Set the threading algorithms used.
*
* Threading requires more than one thread.
* Frame threading requires entire frames to be passed to the codec,
* and introduces extra decoding delay, so is incompatible with low_delay.
*
* @param avctx The context.
*/
static void validate_thread_parameters(AVCodecContext *avctx)
{
int frame_threading_supported = (avctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS)
&& !(avctx->flags & AV_CODEC_FLAG_TRUNCATED)
&& !(avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
&& !(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS);
if (avctx->thread_count == 1) {
avctx->active_thread_type = 0;
} else if (frame_threading_supported && (avctx->thread_type & FF_THREAD_FRAME)) {
avctx->active_thread_type = FF_THREAD_FRAME;
} else if (avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS &&
avctx->thread_type & FF_THREAD_SLICE) {
avctx->active_thread_type = FF_THREAD_SLICE;
} else if (!(avctx->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS)) {
avctx->thread_count = 1;
avctx->active_thread_type = 0;
}
if (avctx->thread_count > MAX_AUTO_THREADS)
av_log(avctx, AV_LOG_WARNING,
"Application has requested %d threads. Using a thread count greater than %d is not recommended.\n",
avctx->thread_count, MAX_AUTO_THREADS);
}
int ff_thread_init(AVCodecContext *avctx)
{
validate_thread_parameters(avctx);
if (avctx->active_thread_type&FF_THREAD_SLICE)
return ff_slice_thread_init(avctx);
else if (avctx->active_thread_type&FF_THREAD_FRAME)
return ff_frame_thread_init(avctx);
return 0;
}
void ff_thread_free(AVCodecContext *avctx)
{
if (avctx->active_thread_type&FF_THREAD_FRAME)
ff_frame_thread_free(avctx, avctx->thread_count);
else
ff_slice_thread_free(avctx);
}

View file

@ -0,0 +1,900 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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
* Frame multithreading support functions
* @see doc/multithreading.txt
*/
#include "config.h"
#include <stdint.h>
#include "avcodec.h"
#include "internal.h"
#include "pthread_internal.h"
#include "thread.h"
#include "version.h"
#include "libavutil/avassert.h"
#include "libavutil/buffer.h"
#include "libavutil/common.h"
#include "libavutil/cpu.h"
#include "libavutil/frame.h"
#include "libavutil/internal.h"
#include "libavutil/log.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/thread.h"
#if defined(MOZ_TSAN)
typedef _Atomic(int) atomic_int;
#else
typedef volatile int atomic_int;
#endif
/**
* 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;
pthread_t thread;
int thread_init;
pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread.
pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change.
pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish.
pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext.
pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
AVCodecContext *avctx; ///< Context used to decode packets passed to this thread.
AVPacket avpkt; ///< Input packet (for decoding) or output (for encoding).
AVFrame *frame; ///< Output frame (for decoding) or input (for encoding).
int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
int result; ///< The result of the last codec decode/encode() call.
atomic_int state;
/**
* Array of frames passed to ff_thread_release_buffer().
* Frames are released after all threads referencing them are finished.
*/
AVFrame *released_buffers;
int num_released_buffers;
int released_buffers_allocated;
AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
int requested_flags; ///< flags passed to get_buffer() for requested_frame
const enum AVPixelFormat *available_formats; ///< Format array for get_format()
enum AVPixelFormat result_format; ///< get_format() result
int die; ///< Set when the thread should exit.
} PerThreadContext;
/**
* Context stored in the client AVCodecInternal thread_ctx.
*/
typedef struct FrameThreadContext {
PerThreadContext *threads; ///< The contexts for each thread.
PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
int next_decoding; ///< The next context to submit a packet to.
int next_finished; ///< The next context to return output from.
int delaying; /**<
* Set for the first N packets, where N is the number of threads.
* While it is set, ff_thread_en/decode_frame won't return any results.
*/
} FrameThreadContext;
#define THREAD_SAFE_CALLBACKS(avctx) \
((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2)
/**
* Codec worker thread.
*
* Automatically calls ff_thread_finish_setup() if the codec does
* not provide an update_thread_context method, or if the codec returns
* before calling it.
*/
static attribute_align_arg void *frame_worker_thread(void *arg)
{
PerThreadContext *p = arg;
AVCodecContext *avctx = p->avctx;
const AVCodec *codec = avctx->codec;
pthread_mutex_lock(&p->mutex);
while (1) {
while (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);
av_frame_unref(p->frame);
p->got_frame = 0;
p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt);
if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) {
if (avctx->internal->allocate_progress)
av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not "
"free the frame on failure. This is a bug, please report it.\n");
av_frame_unref(p->frame);
}
if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
pthread_mutex_lock(&p->progress_mutex);
#if 0 //BUFREF-FIXME
for (i = 0; i < MAX_BUFFERS; i++)
if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) {
p->progress[i][0] = INT_MAX;
p->progress[i][1] = INT_MAX;
}
#endif
p->state = STATE_INPUT_READY;
pthread_cond_broadcast(&p->progress_cond);
pthread_cond_signal(&p->output_cond);
pthread_mutex_unlock(&p->progress_mutex);
}
pthread_mutex_unlock(&p->mutex);
return NULL;
}
/**
* Update the next thread's AVCodecContext with values from the reference thread's context.
*
* @param dst The destination context.
* @param src The source context.
* @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
* @return 0 on success, negative error code on failure
*/
static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user)
{
int err = 0;
if (dst != src) {
dst->time_base = src->time_base;
dst->framerate = src->framerate;
dst->width = src->width;
dst->height = src->height;
dst->pix_fmt = src->pix_fmt;
dst->coded_width = src->coded_width;
dst->coded_height = src->coded_height;
dst->has_b_frames = src->has_b_frames;
dst->idct_algo = src->idct_algo;
dst->bits_per_coded_sample = src->bits_per_coded_sample;
dst->sample_aspect_ratio = src->sample_aspect_ratio;
#if FF_API_AFD
FF_DISABLE_DEPRECATION_WARNINGS
dst->dtg_active_format = src->dtg_active_format;
FF_ENABLE_DEPRECATION_WARNINGS
#endif /* FF_API_AFD */
dst->profile = src->profile;
dst->level = src->level;
dst->bits_per_raw_sample = src->bits_per_raw_sample;
dst->ticks_per_frame = src->ticks_per_frame;
dst->color_primaries = src->color_primaries;
dst->color_trc = src->color_trc;
dst->colorspace = src->colorspace;
dst->color_range = src->color_range;
dst->chroma_sample_location = src->chroma_sample_location;
dst->hwaccel = src->hwaccel;
dst->hwaccel_context = src->hwaccel_context;
dst->channels = src->channels;
dst->sample_rate = src->sample_rate;
dst->sample_fmt = src->sample_fmt;
dst->channel_layout = src->channel_layout;
dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
}
if (for_user) {
dst->delay = src->thread_count - 1;
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
dst->coded_frame = src->coded_frame;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
} else {
if (dst->codec->update_thread_context)
err = dst->codec->update_thread_context(dst, src);
}
return err;
}
/**
* Update the next thread's AVCodecContext with values set by the user.
*
* @param dst The destination context.
* @param src The source context.
* @return 0 on success, negative error code on failure
*/
static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
{
#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s);
dst->flags = src->flags;
dst->draw_horiz_band= src->draw_horiz_band;
dst->get_buffer2 = src->get_buffer2;
dst->opaque = src->opaque;
dst->debug = src->debug;
dst->debug_mv = src->debug_mv;
dst->slice_flags = src->slice_flags;
dst->flags2 = src->flags2;
copy_fields(skip_loop_filter, subtitle_header);
dst->frame_number = src->frame_number;
dst->reordered_opaque = src->reordered_opaque;
dst->thread_safe_callbacks = src->thread_safe_callbacks;
if (src->slice_count && src->slice_offset) {
if (dst->slice_count < src->slice_count) {
int err = av_reallocp_array(&dst->slice_offset, src->slice_count,
sizeof(*dst->slice_offset));
if (err < 0)
return err;
}
memcpy(dst->slice_offset, src->slice_offset,
src->slice_count * sizeof(*dst->slice_offset));
}
dst->slice_count = src->slice_count;
return 0;
#undef copy_fields
}
/// Releases the buffers that this decoding thread was the last user of.
static void release_delayed_buffers(PerThreadContext *p)
{
FrameThreadContext *fctx = p->parent;
while (p->num_released_buffers > 0) {
AVFrame *f;
pthread_mutex_lock(&fctx->buffer_mutex);
// fix extended data in case the caller screwed it up
av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
p->avctx->codec_type == AVMEDIA_TYPE_AUDIO);
f = &p->released_buffers[--p->num_released_buffers];
f->extended_data = f->data;
av_frame_unref(f);
pthread_mutex_unlock(&fctx->buffer_mutex);
}
}
static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
{
FrameThreadContext *fctx = p->parent;
PerThreadContext *prev_thread = fctx->prev_thread;
const AVCodec *codec = p->avctx->codec;
if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY))
return 0;
pthread_mutex_lock(&p->mutex);
release_delayed_buffers(p);
if (prev_thread) {
int err;
if (prev_thread->state == STATE_SETTING_UP) {
pthread_mutex_lock(&prev_thread->progress_mutex);
while (prev_thread->state == STATE_SETTING_UP)
pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
pthread_mutex_unlock(&prev_thread->progress_mutex);
}
err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
if (err) {
pthread_mutex_unlock(&p->mutex);
return err;
}
}
av_packet_unref(&p->avpkt);
av_packet_ref(&p->avpkt, avpkt);
p->state = STATE_SETTING_UP;
pthread_cond_signal(&p->input_cond);
pthread_mutex_unlock(&p->mutex);
/*
* If the client doesn't have a thread-safe get_buffer(),
* then decoding threads call back to the main thread,
* and it calls back to the client here.
*/
if (!p->avctx->thread_safe_callbacks && (
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) {
int call_done = 1;
pthread_mutex_lock(&p->progress_mutex);
while (p->state == STATE_SETTING_UP)
pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
State p_state = (State)p->state;
switch (p_state) {
case STATE_GET_BUFFER:
p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags);
break;
case STATE_GET_FORMAT:
p->result_format = ff_get_format(p->avctx, p->available_formats);
break;
default:
call_done = 0;
break;
}
if (call_done) {
p->state = STATE_SETTING_UP;
pthread_cond_signal(&p->progress_cond);
}
pthread_mutex_unlock(&p->progress_mutex);
}
}
fctx->prev_thread = p;
fctx->next_decoding++;
return 0;
}
int ff_thread_decode_frame(AVCodecContext *avctx,
AVFrame *picture, int *got_picture_ptr,
AVPacket *avpkt)
{
FrameThreadContext *fctx = avctx->internal->thread_ctx;
int finished = fctx->next_finished;
PerThreadContext *p;
int err;
/*
* Submit a packet to the next decoding thread.
*/
p = &fctx->threads[fctx->next_decoding];
err = update_context_from_user(p->avctx, avctx);
if (err) return err;
err = submit_packet(p, avpkt);
if (err) return err;
/*
* If we're still receiving the initial packets, don't return a frame.
*/
if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
fctx->delaying = 0;
if (fctx->delaying) {
*got_picture_ptr=0;
if (avpkt->size)
return avpkt->size;
}
/*
* Return the next available frame from the oldest thread.
* If we're at the end of the stream, then we have to skip threads that
* didn't output a frame, because we don't want to accidentally signal
* EOF (avpkt->size == 0 && *got_picture_ptr == 0).
*/
do {
p = &fctx->threads[finished++];
if (p->state != STATE_INPUT_READY) {
pthread_mutex_lock(&p->progress_mutex);
while (p->state != STATE_INPUT_READY)
pthread_cond_wait(&p->output_cond, &p->progress_mutex);
pthread_mutex_unlock(&p->progress_mutex);
}
av_frame_move_ref(picture, p->frame);
*got_picture_ptr = p->got_frame;
picture->pkt_dts = p->avpkt.dts;
if (p->result < 0)
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
* stopped by the "finished != fctx->next_finished" condition.
* Make sure we don't mistakenly return the same frame again.
*/
p->got_frame = 0;
if (finished >= avctx->thread_count) finished = 0;
} while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished);
update_context_from_thread(avctx, p->avctx, 1);
if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
fctx->next_finished = finished;
/*
* 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;
}
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;
p = f->owner->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);
pthread_mutex_lock(&p->progress_mutex);
progress[field] = n;
pthread_cond_broadcast(&p->progress_cond);
pthread_mutex_unlock(&p->progress_mutex);
}
void ff_thread_await_progress(ThreadFrame *f, int n, int field)
{
PerThreadContext *p;
atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
if (!progress || progress[field] >= n) return;
p = f->owner->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);
pthread_mutex_lock(&p->progress_mutex);
while (progress[field] < n)
pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
pthread_mutex_unlock(&p->progress_mutex);
}
void ff_thread_finish_setup(AVCodecContext *avctx) {
PerThreadContext *p = avctx->internal->thread_ctx;
if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
if(p->state == STATE_SETUP_FINISHED){
av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
}
pthread_mutex_lock(&p->progress_mutex);
p->state = STATE_SETUP_FINISHED;
pthread_cond_broadcast(&p->progress_cond);
pthread_mutex_unlock(&p->progress_mutex);
}
/// Waits for all threads to finish.
static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
{
int i;
for (i = 0; i < thread_count; i++) {
PerThreadContext *p = &fctx->threads[i];
if (p->state != STATE_INPUT_READY) {
pthread_mutex_lock(&p->progress_mutex);
while (p->state != STATE_INPUT_READY)
pthread_cond_wait(&p->output_cond, &p->progress_mutex);
pthread_mutex_unlock(&p->progress_mutex);
}
p->got_frame = 0;
}
}
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
{
FrameThreadContext *fctx = avctx->internal->thread_ctx;
const AVCodec *codec = avctx->codec;
int i;
park_frame_worker_threads(fctx, thread_count);
if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy;
fctx->threads->avctx->internal->is_copy = 1;
}
for (i = 0; i < thread_count; i++) {
PerThreadContext *p = &fctx->threads[i];
pthread_mutex_lock(&p->mutex);
p->die = 1;
pthread_cond_signal(&p->input_cond);
pthread_mutex_unlock(&p->mutex);
if (p->thread_init)
pthread_join(p->thread, NULL);
p->thread_init=0;
if (codec->close && p->avctx)
codec->close(p->avctx);
release_delayed_buffers(p);
av_frame_free(&p->frame);
}
for (i = 0; i < thread_count; i++) {
PerThreadContext *p = &fctx->threads[i];
pthread_mutex_destroy(&p->mutex);
pthread_mutex_destroy(&p->progress_mutex);
pthread_cond_destroy(&p->input_cond);
pthread_cond_destroy(&p->progress_cond);
pthread_cond_destroy(&p->output_cond);
av_packet_unref(&p->avpkt);
av_freep(&p->released_buffers);
if (i && p->avctx) {
av_freep(&p->avctx->priv_data);
av_freep(&p->avctx->slice_offset);
}
if (p->avctx)
av_freep(&p->avctx->internal);
av_freep(&p->avctx);
}
av_freep(&fctx->threads);
pthread_mutex_destroy(&fctx->buffer_mutex);
av_freep(&avctx->internal->thread_ctx);
if (avctx->priv_data && avctx->codec && avctx->codec->priv_class)
av_opt_free(avctx->priv_data);
avctx->codec = NULL;
}
int ff_frame_thread_init(AVCodecContext *avctx)
{
int thread_count = avctx->thread_count;
const AVCodec *codec = avctx->codec;
AVCodecContext *src = avctx;
FrameThreadContext *fctx;
int i, err = 0;
#if HAVE_W32THREADS
w32thread_init();
#endif
if (!thread_count) {
int nb_cpus = av_cpu_count();
if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
nb_cpus = 1;
// use number of cores + 1 as thread count if there is more than one
if (nb_cpus > 1)
thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
else
thread_count = avctx->thread_count = 1;
}
if (thread_count <= 1) {
avctx->active_thread_type = 0;
return 0;
}
avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
if (!fctx)
return AVERROR(ENOMEM);
fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext));
if (!fctx->threads) {
av_freep(&avctx->internal->thread_ctx);
return AVERROR(ENOMEM);
}
pthread_mutex_init(&fctx->buffer_mutex, NULL);
fctx->delaying = 1;
for (i = 0; i < thread_count; i++) {
AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
PerThreadContext *p = &fctx->threads[i];
pthread_mutex_init(&p->mutex, NULL);
pthread_mutex_init(&p->progress_mutex, NULL);
pthread_cond_init(&p->input_cond, NULL);
pthread_cond_init(&p->progress_cond, NULL);
pthread_cond_init(&p->output_cond, NULL);
p->frame = av_frame_alloc();
if (!p->frame) {
av_freep(&copy);
err = AVERROR(ENOMEM);
goto error;
}
p->parent = fctx;
p->avctx = copy;
if (!copy) {
err = AVERROR(ENOMEM);
goto error;
}
*copy = *src;
copy->internal = av_malloc(sizeof(AVCodecInternal));
if (!copy->internal) {
copy->priv_data = NULL;
err = AVERROR(ENOMEM);
goto error;
}
*copy->internal = *src->internal;
copy->internal->thread_ctx = p;
copy->internal->pkt = &p->avpkt;
if (!i) {
src = copy;
if (codec->init)
err = codec->init(copy);
update_context_from_thread(avctx, copy, 1);
} else {
copy->priv_data = av_malloc(codec->priv_data_size);
if (!copy->priv_data) {
err = AVERROR(ENOMEM);
goto error;
}
memcpy(copy->priv_data, src->priv_data, codec->priv_data_size);
copy->internal->is_copy = 1;
if (codec->init_thread_copy)
err = codec->init_thread_copy(copy);
}
if (err) goto error;
err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
p->thread_init= !err;
if(!p->thread_init)
goto error;
}
return 0;
error:
ff_frame_thread_free(avctx, i+1);
return err;
}
void ff_thread_flush(AVCodecContext *avctx)
{
int i;
FrameThreadContext *fctx = avctx->internal->thread_ctx;
if (!fctx) return;
park_frame_worker_threads(fctx, avctx->thread_count);
if (fctx->prev_thread) {
if (fctx->prev_thread != &fctx->threads[0])
update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);
}
fctx->next_decoding = fctx->next_finished = 0;
fctx->delaying = 1;
fctx->prev_thread = NULL;
for (i = 0; i < avctx->thread_count; i++) {
PerThreadContext *p = &fctx->threads[i];
// Make sure decode flush calls with size=0 won't return old frames
p->got_frame = 0;
av_frame_unref(p->frame);
release_delayed_buffers(p);
if (avctx->codec->flush)
avctx->codec->flush(p->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 &&
(avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
return 0;
}
return 1;
}
static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)
{
PerThreadContext *p = avctx->internal->thread_ctx;
int err;
f->owner = avctx;
ff_init_buffer_info(avctx, f->f);
if (!(avctx->active_thread_type & FF_THREAD_FRAME))
return ff_get_buffer(avctx, f->f, flags);
if (p->state != STATE_SETTING_UP &&
(avctx->codec->update_thread_context || !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));
if (!f->progress) {
return AVERROR(ENOMEM);
}
progress = (int*)f->progress->data;
progress[0] = progress[1] = -1;
}
pthread_mutex_lock(&p->parent->buffer_mutex);
if (avctx->thread_safe_callbacks ||
avctx->get_buffer2 == avcodec_default_get_buffer2) {
err = ff_get_buffer(avctx, f->f, flags);
} else {
pthread_mutex_lock(&p->progress_mutex);
p->requested_frame = f->f;
p->requested_flags = flags;
p->state = STATE_GET_BUFFER;
pthread_cond_broadcast(&p->progress_cond);
while (p->state != STATE_SETTING_UP)
pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
err = p->result;
pthread_mutex_unlock(&p->progress_mutex);
}
if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context)
ff_thread_finish_setup(avctx);
if (err)
av_buffer_unref(&f->progress);
pthread_mutex_unlock(&p->parent->buffer_mutex);
return err;
}
enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
{
enum AVPixelFormat res;
PerThreadContext *p = avctx->internal->thread_ctx;
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) {
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;
pthread_cond_broadcast(&p->progress_cond);
while (p->state != STATE_SETTING_UP)
pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
res = p->result_format;
pthread_mutex_unlock(&p->progress_mutex);
return res;
}
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
{
int ret = thread_get_buffer_internal(avctx, f, flags);
if (ret < 0)
av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
return ret;
}
void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
{
PerThreadContext *p = avctx->internal->thread_ctx;
FrameThreadContext *fctx;
AVFrame *dst, *tmp;
int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
avctx->thread_safe_callbacks ||
avctx->get_buffer2 == avcodec_default_get_buffer2;
if (!f->f || !f->f->buf[0])
return;
if (avctx->debug & FF_DEBUG_BUFFERS)
av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
av_buffer_unref(&f->progress);
f->owner = NULL;
if (can_direct_free) {
av_frame_unref(f->f);
return;
}
fctx = p->parent;
pthread_mutex_lock(&fctx->buffer_mutex);
if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers))
goto fail;
tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
(p->num_released_buffers + 1) *
sizeof(*p->released_buffers));
if (!tmp)
goto fail;
p->released_buffers = tmp;
dst = &p->released_buffers[p->num_released_buffers];
av_frame_move_ref(dst, f->f);
p->num_released_buffers++;
fail:
pthread_mutex_unlock(&fctx->buffer_mutex);
}

View file

@ -0,0 +1,34 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_PTHREAD_INTERNAL_H
#define AVCODEC_PTHREAD_INTERNAL_H
#include "avcodec.h"
/* H.264 slice threading seems to be buggy with more than 16 threads,
* limit the number of threads to 16 for automatic detection */
#define MAX_AUTO_THREADS 16
int ff_slice_thread_init(AVCodecContext *avctx);
void ff_slice_thread_free(AVCodecContext *avctx);
int ff_frame_thread_init(AVCodecContext *avctx);
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count);
#endif // AVCODEC_PTHREAD_INTERNAL_H

View file

@ -0,0 +1,314 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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
* Slice multithreading support functions
* @see doc/multithreading.txt
*/
#include "config.h"
#include "avcodec.h"
#include "internal.h"
#include "pthread_internal.h"
#include "thread.h"
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/cpu.h"
#include "libavutil/mem.h"
#include "libavutil/thread.h"
typedef int (action_func)(AVCodecContext *c, void *arg);
typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
typedef struct SliceThreadContext {
pthread_t *workers;
action_func *func;
action_func2 *func2;
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;
pthread_cond_t *progress_cond;
pthread_mutex_t *progress_mutex;
} SliceThreadContext;
static void* attribute_align_arg worker(void *v)
{
AVCodecContext *avctx = v;
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);
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;
pthread_mutex_lock(&c->current_job_lock);
our_job = c->current_job++;
}
}
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);
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;
if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1)
return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size);
if (job_count <= 0)
return 0;
pthread_mutex_lock(&c->current_job_lock);
c->current_job = avctx->thread_count;
c->job_count = job_count;
c->job_size = job_size;
c->args = arg;
c->func = func;
if (ret) {
c->rets = ret;
} else {
c->rets = NULL;
}
c->current_execute++;
pthread_cond_broadcast(&c->current_job_cond);
thread_park_workers(c, avctx->thread_count);
return 0;
}
static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count)
{
SliceThreadContext *c = avctx->internal->thread_ctx;
c->func2 = func2;
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;
#if HAVE_W32THREADS
w32thread_init();
#endif
// We cannot do this in the encoder init as the threads are created before
if (av_codec_is_encoder(avctx->codec) &&
avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO &&
avctx->height > 2800)
thread_count = avctx->thread_count = 1;
if (!thread_count) {
int nb_cpus = av_cpu_count();
if (avctx->height)
nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);
// use number of cores + 1 as thread count if there is more than one
if (nb_cpus > 1)
thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
else
thread_count = avctx->thread_count = 1;
}
if (thread_count <= 1) {
avctx->active_thread_type = 0;
return 0;
}
c = av_mallocz(sizeof(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;
}
}
thread_park_workers(c, thread_count);
avctx->execute = thread_execute;
avctx->execute2 = thread_execute2;
return 0;
}
void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n)
{
SliceThreadContext *p = avctx->internal->thread_ctx;
int *entries = p->entries;
pthread_mutex_lock(&p->progress_mutex[thread]);
entries[field] +=n;
pthread_cond_signal(&p->progress_cond[thread]);
pthread_mutex_unlock(&p->progress_mutex[thread]);
}
void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift)
{
SliceThreadContext *p = avctx->internal->thread_ctx;
int *entries = p->entries;
if (!entries || !field) return;
thread = thread ? thread - 1 : p->thread_count - 1;
pthread_mutex_lock(&p->progress_mutex[thread]);
while ((entries[field - 1] - entries[field]) < shift){
pthread_cond_wait(&p->progress_cond[thread], &p->progress_mutex[thread]);
}
pthread_mutex_unlock(&p->progress_mutex[thread]);
}
int ff_alloc_entries(AVCodecContext *avctx, int count)
{
int i;
if (avctx->active_thread_type & FF_THREAD_SLICE) {
SliceThreadContext *p = avctx->internal->thread_ctx;
if (p->entries) {
av_assert0(p->thread_count == avctx->thread_count);
av_freep(&p->entries);
}
p->thread_count = avctx->thread_count;
p->entries = av_mallocz_array(count, sizeof(int));
if (!p->progress_mutex) {
p->progress_mutex = av_malloc_array(p->thread_count, sizeof(pthread_mutex_t));
p->progress_cond = av_malloc_array(p->thread_count, sizeof(pthread_cond_t));
}
if (!p->entries || !p->progress_mutex || !p->progress_cond) {
av_freep(&p->entries);
av_freep(&p->progress_mutex);
av_freep(&p->progress_cond);
return AVERROR(ENOMEM);
}
p->entries_count = count;
for (i = 0; i < p->thread_count; i++) {
pthread_mutex_init(&p->progress_mutex[i], NULL);
pthread_cond_init(&p->progress_cond[i], NULL);
}
}
return 0;
}
void ff_reset_entries(AVCodecContext *avctx)
{
SliceThreadContext *p = avctx->internal->thread_ctx;
memset(p->entries, 0, p->entries_count * sizeof(int));
}

View file

@ -0,0 +1,268 @@
/*
* copyright (c) 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
*/
/**
* @file
* bitstream writer API
*/
#ifndef AVCODEC_PUT_BITS_H
#define AVCODEC_PUT_BITS_H
#include <stdint.h>
#include <stddef.h>
#include "libavutil/intreadwrite.h"
#include "libavutil/avassert.h"
typedef struct PutBitContext {
uint32_t bit_buf;
int bit_left;
uint8_t *buf, *buf_ptr, *buf_end;
int size_in_bits;
} PutBitContext;
/**
* Initialize the PutBitContext s.
*
* @param buffer the buffer where to put bits
* @param buffer_size the size in bytes of buffer
*/
static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
int buffer_size)
{
if (buffer_size < 0) {
buffer_size = 0;
buffer = NULL;
}
s->size_in_bits = 8 * buffer_size;
s->buf = buffer;
s->buf_end = s->buf + buffer_size;
s->buf_ptr = s->buf;
s->bit_left = 32;
s->bit_buf = 0;
}
/**
* Rebase the bit writer onto a reallocated buffer.
*
* @param buffer the buffer where to put bits
* @param buffer_size the size in bytes of buffer,
* must be larger than the previous size
*/
static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
int buffer_size)
{
av_assert0(8*buffer_size > s->size_in_bits);
s->buf_end = buffer + buffer_size;
s->buf_ptr = buffer + (s->buf_ptr - s->buf);
s->buf = buffer;
s->size_in_bits = 8 * buffer_size;
}
/**
* @return the total number of bits written to the bitstream.
*/
static inline int put_bits_count(PutBitContext *s)
{
return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
}
/**
* @return the number of bits available in the bitstream.
*/
static inline int put_bits_left(PutBitContext* s)
{
return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left;
}
/**
* Pad the end of the output stream with zeros.
*/
static inline void flush_put_bits(PutBitContext *s)
{
#ifndef BITSTREAM_WRITER_LE
if (s->bit_left < 32)
s->bit_buf <<= s->bit_left;
#endif
while (s->bit_left < 32) {
av_assert0(s->buf_ptr < s->buf_end);
#ifdef BITSTREAM_WRITER_LE
*s->buf_ptr++ = s->bit_buf;
s->bit_buf >>= 8;
#else
*s->buf_ptr++ = s->bit_buf >> 24;
s->bit_buf <<= 8;
#endif
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
#define avpriv_copy_bits avpriv_copy_bits_unsupported_here
#else
/**
* Pad the bitstream with zeros up to the next byte boundary.
*/
void avpriv_align_put_bits(PutBitContext *s);
/**
* Put the string string in the bitstream.
*
* @param terminate_string 0-terminates the written string if value is 1
*/
void avpriv_put_string(PutBitContext *pb, const char *string,
int terminate_string);
/**
* Copy the content of src to the bitstream.
*
* @param length the number of bits of src to copy
*/
void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
#endif
/**
* Write up to 31 bits into a bitstream.
* Use put_bits32 to write 32 bits.
*/
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
{
unsigned int bit_buf;
int bit_left;
av_assert2(n <= 31 && value < (1U << n));
bit_buf = s->bit_buf;
bit_left = s->bit_left;
/* XXX: optimize */
#ifdef BITSTREAM_WRITER_LE
bit_buf |= value << (32 - bit_left);
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;
#else
if (n < bit_left) {
bit_buf = (bit_buf << n) | value;
bit_left -= n;
} else {
bit_buf <<= bit_left;
bit_buf |= value >> (n - bit_left);
if (3 < s->buf_end - s->buf_ptr) {
AV_WB32(s->buf_ptr, bit_buf);
s->buf_ptr += 4;
} else {
av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
av_assert2(0);
}
bit_left += 32 - n;
bit_buf = value;
}
#endif
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);
put_bits(pb, n, av_mod_uintp2(value, n));
}
/**
* Write exactly 32 bits into a bitstream.
*/
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
{
int lo = value & 0xffff;
int hi = value >> 16;
#ifdef BITSTREAM_WRITER_LE
put_bits(s, 16, lo);
put_bits(s, 16, hi);
#else
put_bits(s, 16, hi);
put_bits(s, 16, lo);
#endif
}
/**
* Return the pointer to the byte where the bitstream writer will put
* the next bit.
*/
static inline uint8_t *put_bits_ptr(PutBitContext *s)
{
return s->buf_ptr;
}
/**
* Skip the given number of bytes.
* PutBitContext must be flushed & aligned to a byte boundary before calling this.
*/
static inline void skip_put_bytes(PutBitContext *s, int n)
{
av_assert2((put_bits_count(s) & 7) == 0);
av_assert2(s->bit_left == 32);
av_assert0(n <= s->buf_end - s->buf_ptr);
s->buf_ptr += n;
}
/**
* Skip the given number of bits.
* Must only be used if the actual values in the bitstream do not matter.
* If n is 0 the behavior is undefined.
*/
static inline void skip_put_bits(PutBitContext *s, int n)
{
s->bit_left -= n;
s->buf_ptr -= 4 * (s->bit_left >> 5);
s->bit_left &= 31;
}
/**
* Change the end of the buffer.
*
* @param size the new size in bytes of the buffer where to put bits
*/
static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
{
av_assert0(size <= INT_MAX/8 - 32);
s->buf_end = s->buf + size;
s->size_in_bits = 8*size;
}
#endif /* AVCODEC_PUT_BITS_H */

View file

@ -0,0 +1,83 @@
/*
* quarterpel DSP functions
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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
* quarterpel DSP functions
*/
#ifndef AVCODEC_QPELDSP_H
#define AVCODEC_QPELDSP_H
#include <stddef.h>
#include <stdint.h>
void ff_put_pixels8x8_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_avg_pixels8x8_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_put_pixels16x16_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_avg_pixels16x16_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_put_pixels8_l2_8(uint8_t *dst, const uint8_t *src1, const uint8_t *src2,
int dst_stride, int src_stride1, int src_stride2,
int h);
#define DEF_OLD_QPEL(name) \
void ff_put_ ## name(uint8_t *dst /* align width (8 or 16) */, \
const uint8_t *src /* align 1 */, \
ptrdiff_t stride); \
void ff_put_no_rnd_ ## name(uint8_t *dst /* align width (8 or 16) */, \
const uint8_t *src /* align 1 */, \
ptrdiff_t stride); \
void ff_avg_ ## name(uint8_t *dst /* align width (8 or 16) */, \
const uint8_t *src /* align 1 */, \
ptrdiff_t stride);
DEF_OLD_QPEL(qpel16_mc11_old_c)
DEF_OLD_QPEL(qpel16_mc31_old_c)
DEF_OLD_QPEL(qpel16_mc12_old_c)
DEF_OLD_QPEL(qpel16_mc32_old_c)
DEF_OLD_QPEL(qpel16_mc13_old_c)
DEF_OLD_QPEL(qpel16_mc33_old_c)
DEF_OLD_QPEL(qpel8_mc11_old_c)
DEF_OLD_QPEL(qpel8_mc31_old_c)
DEF_OLD_QPEL(qpel8_mc12_old_c)
DEF_OLD_QPEL(qpel8_mc32_old_c)
DEF_OLD_QPEL(qpel8_mc13_old_c)
DEF_OLD_QPEL(qpel8_mc33_old_c)
typedef void (*qpel_mc_func)(uint8_t *dst /* align width (8 or 16) */,
const uint8_t *src /* align 1 */,
ptrdiff_t stride);
/**
* quarterpel DSP context
*/
typedef struct QpelDSPContext {
qpel_mc_func put_qpel_pixels_tab[2][16];
qpel_mc_func avg_qpel_pixels_tab[2][16];
qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16];
} QpelDSPContext;
void ff_qpeldsp_init(QpelDSPContext *c);
void ff_qpeldsp_init_x86(QpelDSPContext *c);
void ff_qpeldsp_init_mips(QpelDSPContext *c);
#endif /* AVCODEC_QPELDSP_H */

View file

@ -0,0 +1,42 @@
/*
* Intel MediaSDK QSV public API functions
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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 <stddef.h>
#include "libavutil/mem.h"
#if CONFIG_QSV
#include "qsv.h"
AVQSVContext *av_qsv_alloc_context(void)
{
return av_mallocz(sizeof(AVQSVContext));
}
#else
struct AVQSVContext *av_qsv_alloc_context(void);
struct AVQSVContext *av_qsv_alloc_context(void)
{
return NULL;
}
#endif

View file

@ -0,0 +1,103 @@
/*
* Ratecontrol
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_RATECONTROL_H
#define AVCODEC_RATECONTROL_H
/**
* @file
* ratecontrol header.
*/
#include <stdio.h>
#include <stdint.h>
#include "libavutil/eval.h"
typedef struct Predictor{
double coeff;
double count;
double decay;
} Predictor;
typedef struct RateControlEntry{
int pict_type;
float qscale;
int mv_bits;
int i_tex_bits;
int p_tex_bits;
int misc_bits;
int header_bits;
uint64_t expected_bits;
int new_pict_type;
float new_qscale;
int64_t mc_mb_var_sum;
int64_t mb_var_sum;
int i_count;
int skip_count;
int f_code;
int b_code;
}RateControlEntry;
/**
* rate control context.
*/
typedef struct RateControlContext{
int num_entries; ///< number of RateControlEntries
RateControlEntry *entry;
double buffer_index; ///< amount of bits in the video/audio buffer
Predictor pred[5];
double short_term_qsum; ///< sum of recent qscales
double short_term_qcount; ///< count of recent qscales
double pass1_rc_eq_output_sum;///< sum of the output of the rc equation, this is used for normalization
double pass1_wanted_bits; ///< bits which should have been output by the pass1 code (including complexity init)
double last_qscale;
double last_qscale_for[5]; ///< last qscale for a specific pict type, used for max_diff & ipb factor stuff
int64_t last_mc_mb_var_sum;
int64_t last_mb_var_sum;
uint64_t i_cplx_sum[5];
uint64_t p_cplx_sum[5];
uint64_t mv_bits_sum[5];
uint64_t qscale_sum[5];
int frame_count[5];
int last_non_b_pict_type;
void *non_lavc_opaque; ///< context for non lavc rc code (for example xvid)
float dry_run_qscale; ///< for xvid rc
int last_picture_number; ///< for xvid rc
AVExpr * rc_eq_eval;
}RateControlContext;
struct MpegEncContext;
/* rate control */
int ff_rate_control_init(struct MpegEncContext *s);
float ff_rate_estimate_qscale(struct MpegEncContext *s, int dry_run);
void ff_write_pass1_stats(struct MpegEncContext *s);
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 */

View file

@ -0,0 +1,308 @@
/*
* Raw Video Codec
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Raw Video Codec
*/
#include "avcodec.h"
#include "raw.h"
#include "libavutil/common.h"
const PixelFormatTag ff_raw_pix_fmt_tags[] = {
{ AV_PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */
{ AV_PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') },
{ AV_PIX_FMT_YUV420P, MKTAG('Y', 'V', '1', '2') },
{ AV_PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') },
{ AV_PIX_FMT_YUV410P, MKTAG('Y', 'V', 'U', '9') },
{ AV_PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') },
{ AV_PIX_FMT_YUV422P, MKTAG('Y', '4', '2', 'B') },
{ AV_PIX_FMT_YUV422P, MKTAG('P', '4', '2', '2') },
{ AV_PIX_FMT_YUV422P, MKTAG('Y', 'V', '1', '6') },
/* yuvjXXX formats are deprecated hacks specific to libav*,
they are identical to yuvXXX */
{ AV_PIX_FMT_YUVJ420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */
{ AV_PIX_FMT_YUVJ420P, MKTAG('I', 'Y', 'U', 'V') },
{ AV_PIX_FMT_YUVJ420P, MKTAG('Y', 'V', '1', '2') },
{ AV_PIX_FMT_YUVJ422P, MKTAG('Y', '4', '2', 'B') },
{ AV_PIX_FMT_YUVJ422P, MKTAG('P', '4', '2', '2') },
{ AV_PIX_FMT_GRAY8, MKTAG('Y', '8', '0', '0') },
{ AV_PIX_FMT_GRAY8, MKTAG('Y', '8', ' ', ' ') },
{ AV_PIX_FMT_YUYV422, MKTAG('Y', 'U', 'Y', '2') }, /* Packed formats */
{ AV_PIX_FMT_YUYV422, MKTAG('Y', '4', '2', '2') },
{ AV_PIX_FMT_YUYV422, MKTAG('V', '4', '2', '2') },
{ AV_PIX_FMT_YUYV422, MKTAG('V', 'Y', 'U', 'Y') },
{ AV_PIX_FMT_YUYV422, MKTAG('Y', 'U', 'N', 'V') },
{ AV_PIX_FMT_YUYV422, MKTAG('Y', 'U', 'Y', 'V') },
{ AV_PIX_FMT_YVYU422, MKTAG('Y', 'V', 'Y', 'U') }, /* Philips */
{ AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') },
{ AV_PIX_FMT_UYVY422, MKTAG('H', 'D', 'Y', 'C') },
{ AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'N', 'V') },
{ AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'N', 'Y') },
{ AV_PIX_FMT_UYVY422, MKTAG('u', 'y', 'v', '1') },
{ AV_PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', '1') },
{ AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'R', 'n') }, /* Avid AVI Codec 1:1 */
{ AV_PIX_FMT_UYVY422, MKTAG('A', 'V', '1', 'x') }, /* Avid 1:1x */
{ AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'u', 'p') },
{ AV_PIX_FMT_UYVY422, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */
{ AV_PIX_FMT_UYVY422, MKTAG('a', 'u', 'v', '2') },
{ AV_PIX_FMT_UYVY422, MKTAG('c', 'y', 'u', 'v') }, /* CYUV is also Creative YUV */
{ AV_PIX_FMT_UYYVYY411, MKTAG('Y', '4', '1', '1') },
{ AV_PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') },
{ AV_PIX_FMT_NV12, MKTAG('N', 'V', '1', '2') },
{ AV_PIX_FMT_NV21, MKTAG('N', 'V', '2', '1') },
/* nut */
{ AV_PIX_FMT_RGB555LE, MKTAG('R', 'G', 'B', 15) },
{ AV_PIX_FMT_BGR555LE, MKTAG('B', 'G', 'R', 15) },
{ AV_PIX_FMT_RGB565LE, MKTAG('R', 'G', 'B', 16) },
{ AV_PIX_FMT_BGR565LE, MKTAG('B', 'G', 'R', 16) },
{ AV_PIX_FMT_RGB555BE, MKTAG(15 , 'B', 'G', 'R') },
{ AV_PIX_FMT_BGR555BE, MKTAG(15 , 'R', 'G', 'B') },
{ AV_PIX_FMT_RGB565BE, MKTAG(16 , 'B', 'G', 'R') },
{ AV_PIX_FMT_BGR565BE, MKTAG(16 , 'R', 'G', 'B') },
{ AV_PIX_FMT_RGB444LE, MKTAG('R', 'G', 'B', 12) },
{ AV_PIX_FMT_BGR444LE, MKTAG('B', 'G', 'R', 12) },
{ AV_PIX_FMT_RGB444BE, MKTAG(12 , 'B', 'G', 'R') },
{ AV_PIX_FMT_BGR444BE, MKTAG(12 , 'R', 'G', 'B') },
{ AV_PIX_FMT_RGBA64LE, MKTAG('R', 'B', 'A', 64 ) },
{ AV_PIX_FMT_BGRA64LE, MKTAG('B', 'R', 'A', 64 ) },
{ AV_PIX_FMT_RGBA64BE, MKTAG(64 , 'R', 'B', 'A') },
{ AV_PIX_FMT_BGRA64BE, MKTAG(64 , 'B', 'R', 'A') },
{ AV_PIX_FMT_RGBA, MKTAG('R', 'G', 'B', 'A') },
{ AV_PIX_FMT_RGB0, MKTAG('R', 'G', 'B', 0 ) },
{ AV_PIX_FMT_BGRA, MKTAG('B', 'G', 'R', 'A') },
{ AV_PIX_FMT_BGR0, MKTAG('B', 'G', 'R', 0 ) },
{ AV_PIX_FMT_ABGR, MKTAG('A', 'B', 'G', 'R') },
{ AV_PIX_FMT_0BGR, MKTAG( 0 , 'B', 'G', 'R') },
{ AV_PIX_FMT_ARGB, MKTAG('A', 'R', 'G', 'B') },
{ AV_PIX_FMT_0RGB, MKTAG( 0 , 'R', 'G', 'B') },
{ AV_PIX_FMT_RGB24, MKTAG('R', 'G', 'B', 24 ) },
{ AV_PIX_FMT_BGR24, MKTAG('B', 'G', 'R', 24 ) },
{ AV_PIX_FMT_YUV411P, MKTAG('4', '1', '1', 'P') },
{ AV_PIX_FMT_YUV422P, MKTAG('4', '2', '2', 'P') },
{ AV_PIX_FMT_YUVJ422P, MKTAG('4', '2', '2', 'P') },
{ AV_PIX_FMT_YUV440P, MKTAG('4', '4', '0', 'P') },
{ AV_PIX_FMT_YUVJ440P, MKTAG('4', '4', '0', 'P') },
{ AV_PIX_FMT_YUV444P, MKTAG('4', '4', '4', 'P') },
{ AV_PIX_FMT_YUVJ444P, MKTAG('4', '4', '4', 'P') },
{ AV_PIX_FMT_MONOWHITE,MKTAG('B', '1', 'W', '0') },
{ AV_PIX_FMT_MONOBLACK,MKTAG('B', '0', 'W', '1') },
{ AV_PIX_FMT_BGR8, MKTAG('B', 'G', 'R', 8 ) },
{ AV_PIX_FMT_RGB8, MKTAG('R', 'G', 'B', 8 ) },
{ AV_PIX_FMT_BGR4, MKTAG('B', 'G', 'R', 4 ) },
{ AV_PIX_FMT_RGB4, MKTAG('R', 'G', 'B', 4 ) },
{ AV_PIX_FMT_RGB4_BYTE,MKTAG('B', '4', 'B', 'Y') },
{ AV_PIX_FMT_BGR4_BYTE,MKTAG('R', '4', 'B', 'Y') },
{ AV_PIX_FMT_RGB48LE, MKTAG('R', 'G', 'B', 48 ) },
{ 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_GRAY16LE, MKTAG('Y', '1', 0 , 16 ) },
{ AV_PIX_FMT_GRAY16BE, MKTAG(16 , 0 , '1', 'Y') },
{ AV_PIX_FMT_YUV420P9LE, MKTAG('Y', '3', 11 , 9 ) },
{ AV_PIX_FMT_YUV420P9BE, MKTAG( 9 , 11 , '3', 'Y') },
{ AV_PIX_FMT_YUV422P9LE, MKTAG('Y', '3', 10 , 9 ) },
{ AV_PIX_FMT_YUV422P9BE, MKTAG( 9 , 10 , '3', 'Y') },
{ AV_PIX_FMT_YUV444P9LE, MKTAG('Y', '3', 0 , 9 ) },
{ AV_PIX_FMT_YUV444P9BE, MKTAG( 9 , 0 , '3', 'Y') },
{ AV_PIX_FMT_YUV420P10LE, MKTAG('Y', '3', 11 , 10 ) },
{ AV_PIX_FMT_YUV420P10BE, MKTAG(10 , 11 , '3', 'Y') },
{ AV_PIX_FMT_YUV422P10LE, MKTAG('Y', '3', 10 , 10 ) },
{ AV_PIX_FMT_YUV422P10BE, MKTAG(10 , 10 , '3', 'Y') },
{ AV_PIX_FMT_YUV444P10LE, MKTAG('Y', '3', 0 , 10 ) },
{ AV_PIX_FMT_YUV444P10BE, MKTAG(10 , 0 , '3', 'Y') },
{ AV_PIX_FMT_YUV420P12LE, MKTAG('Y', '3', 11 , 12 ) },
{ AV_PIX_FMT_YUV420P12BE, MKTAG(12 , 11 , '3', 'Y') },
{ AV_PIX_FMT_YUV422P12LE, MKTAG('Y', '3', 10 , 12 ) },
{ AV_PIX_FMT_YUV422P12BE, MKTAG(12 , 10 , '3', 'Y') },
{ AV_PIX_FMT_YUV444P12LE, MKTAG('Y', '3', 0 , 12 ) },
{ AV_PIX_FMT_YUV444P12BE, MKTAG(12 , 0 , '3', 'Y') },
{ AV_PIX_FMT_YUV420P14LE, MKTAG('Y', '3', 11 , 14 ) },
{ AV_PIX_FMT_YUV420P14BE, MKTAG(14 , 11 , '3', 'Y') },
{ AV_PIX_FMT_YUV422P14LE, MKTAG('Y', '3', 10 , 14 ) },
{ AV_PIX_FMT_YUV422P14BE, MKTAG(14 , 10 , '3', 'Y') },
{ AV_PIX_FMT_YUV444P14LE, MKTAG('Y', '3', 0 , 14 ) },
{ AV_PIX_FMT_YUV444P14BE, MKTAG(14 , 0 , '3', 'Y') },
{ AV_PIX_FMT_YUV420P16LE, MKTAG('Y', '3', 11 , 16 ) },
{ AV_PIX_FMT_YUV420P16BE, MKTAG(16 , 11 , '3', 'Y') },
{ AV_PIX_FMT_YUV422P16LE, MKTAG('Y', '3', 10 , 16 ) },
{ AV_PIX_FMT_YUV422P16BE, MKTAG(16 , 10 , '3', 'Y') },
{ AV_PIX_FMT_YUV444P16LE, MKTAG('Y', '3', 0 , 16 ) },
{ AV_PIX_FMT_YUV444P16BE, MKTAG(16 , 0 , '3', 'Y') },
{ AV_PIX_FMT_YUVA420P, MKTAG('Y', '4', 11 , 8 ) },
{ AV_PIX_FMT_YUVA422P, MKTAG('Y', '4', 10 , 8 ) },
{ AV_PIX_FMT_YUVA444P, MKTAG('Y', '4', 0 , 8 ) },
{ AV_PIX_FMT_YA8, MKTAG('Y', '2', 0 , 8 ) },
{ AV_PIX_FMT_PAL8, MKTAG('P', 'A', 'L', 8 ) },
{ AV_PIX_FMT_YUVA420P9LE, MKTAG('Y', '4', 11 , 9 ) },
{ AV_PIX_FMT_YUVA420P9BE, MKTAG( 9 , 11 , '4', 'Y') },
{ AV_PIX_FMT_YUVA422P9LE, MKTAG('Y', '4', 10 , 9 ) },
{ AV_PIX_FMT_YUVA422P9BE, MKTAG( 9 , 10 , '4', 'Y') },
{ AV_PIX_FMT_YUVA444P9LE, MKTAG('Y', '4', 0 , 9 ) },
{ AV_PIX_FMT_YUVA444P9BE, MKTAG( 9 , 0 , '4', 'Y') },
{ AV_PIX_FMT_YUVA420P10LE, MKTAG('Y', '4', 11 , 10 ) },
{ AV_PIX_FMT_YUVA420P10BE, MKTAG(10 , 11 , '4', 'Y') },
{ AV_PIX_FMT_YUVA422P10LE, MKTAG('Y', '4', 10 , 10 ) },
{ AV_PIX_FMT_YUVA422P10BE, MKTAG(10 , 10 , '4', 'Y') },
{ AV_PIX_FMT_YUVA444P10LE, MKTAG('Y', '4', 0 , 10 ) },
{ AV_PIX_FMT_YUVA444P10BE, MKTAG(10 , 0 , '4', 'Y') },
{ AV_PIX_FMT_YUVA420P16LE, MKTAG('Y', '4', 11 , 16 ) },
{ AV_PIX_FMT_YUVA420P16BE, MKTAG(16 , 11 , '4', 'Y') },
{ AV_PIX_FMT_YUVA422P16LE, MKTAG('Y', '4', 10 , 16 ) },
{ AV_PIX_FMT_YUVA422P16BE, MKTAG(16 , 10 , '4', 'Y') },
{ AV_PIX_FMT_YUVA444P16LE, MKTAG('Y', '4', 0 , 16 ) },
{ AV_PIX_FMT_YUVA444P16BE, MKTAG(16 , 0 , '4', 'Y') },
{ AV_PIX_FMT_GBRP, MKTAG('G', '3', 00 , 8 ) },
{ AV_PIX_FMT_GBRP9LE, MKTAG('G', '3', 00 , 9 ) },
{ AV_PIX_FMT_GBRP9BE, MKTAG( 9 , 00 , '3', 'G') },
{ AV_PIX_FMT_GBRP10LE, MKTAG('G', '3', 00 , 10 ) },
{ AV_PIX_FMT_GBRP10BE, MKTAG(10 , 00 , '3', 'G') },
{ AV_PIX_FMT_GBRP12LE, MKTAG('G', '3', 00 , 12 ) },
{ AV_PIX_FMT_GBRP12BE, MKTAG(12 , 00 , '3', 'G') },
{ AV_PIX_FMT_GBRP14LE, MKTAG('G', '3', 00 , 14 ) },
{ AV_PIX_FMT_GBRP14BE, MKTAG(14 , 00 , '3', 'G') },
{ AV_PIX_FMT_GBRP16LE, MKTAG('G', '3', 00 , 16 ) },
{ AV_PIX_FMT_GBRP16BE, MKTAG(16 , 00 , '3', 'G') },
{ AV_PIX_FMT_XYZ12LE, MKTAG('X', 'Y', 'Z' , 36 ) },
{ AV_PIX_FMT_XYZ12BE, MKTAG(36 , 'Z' , 'Y', 'X') },
{ AV_PIX_FMT_BAYER_BGGR8, MKTAG(0xBA, 'B', 'G', 8 ) },
{ AV_PIX_FMT_BAYER_BGGR16LE, MKTAG(0xBA, 'B', 'G', 16 ) },
{ AV_PIX_FMT_BAYER_BGGR16BE, MKTAG(16 , 'G', 'B', 0xBA) },
{ AV_PIX_FMT_BAYER_RGGB8, MKTAG(0xBA, 'R', 'G', 8 ) },
{ AV_PIX_FMT_BAYER_RGGB16LE, MKTAG(0xBA, 'R', 'G', 16 ) },
{ AV_PIX_FMT_BAYER_RGGB16BE, MKTAG(16 , 'G', 'R', 0xBA) },
{ AV_PIX_FMT_BAYER_GBRG8, MKTAG(0xBA, 'G', 'B', 8 ) },
{ AV_PIX_FMT_BAYER_GBRG16LE, MKTAG(0xBA, 'G', 'B', 16 ) },
{ AV_PIX_FMT_BAYER_GBRG16BE, MKTAG(16, 'B', 'G', 0xBA) },
{ AV_PIX_FMT_BAYER_GRBG8, MKTAG(0xBA, 'G', 'R', 8 ) },
{ AV_PIX_FMT_BAYER_GRBG16LE, MKTAG(0xBA, 'G', 'R', 16 ) },
{ AV_PIX_FMT_BAYER_GRBG16BE, MKTAG(16, 'R', 'G', 0xBA) },
/* quicktime */
{ AV_PIX_FMT_YUV420P, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */
{ AV_PIX_FMT_YUV411P, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */
{ AV_PIX_FMT_UYVY422, MKTAG('2', 'v', 'u', 'y') },
{ AV_PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', 'y') },
{ AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'U', 'I') }, /* FIXME merge both fields */
{ AV_PIX_FMT_UYVY422, MKTAG('b', 'x', 'y', 'v') },
{ AV_PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', '2') },
{ AV_PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', 's') },
{ AV_PIX_FMT_YUYV422, MKTAG('D', 'V', 'O', 'O') }, /* Digital Voodoo SD 8 Bit */
{ AV_PIX_FMT_RGB555LE,MKTAG('L', '5', '5', '5') },
{ AV_PIX_FMT_RGB565LE,MKTAG('L', '5', '6', '5') },
{ AV_PIX_FMT_RGB565BE,MKTAG('B', '5', '6', '5') },
{ AV_PIX_FMT_BGR24, MKTAG('2', '4', 'B', 'G') },
{ AV_PIX_FMT_BGR24, MKTAG('b', 'x', 'b', 'g') },
{ AV_PIX_FMT_BGRA, MKTAG('B', 'G', 'R', 'A') },
{ AV_PIX_FMT_RGBA, MKTAG('R', 'G', 'B', 'A') },
{ AV_PIX_FMT_RGB24, MKTAG('b', 'x', 'r', 'g') },
{ AV_PIX_FMT_ABGR, MKTAG('A', 'B', 'G', 'R') },
{ AV_PIX_FMT_GRAY16BE,MKTAG('b', '1', '6', 'g') },
{ AV_PIX_FMT_RGB48BE, MKTAG('b', '4', '8', 'r') },
/* vlc */
{ AV_PIX_FMT_YUV410P, MKTAG('I', '4', '1', '0') },
{ AV_PIX_FMT_YUV411P, MKTAG('I', '4', '1', '1') },
{ AV_PIX_FMT_YUV422P, MKTAG('I', '4', '2', '2') },
{ AV_PIX_FMT_YUV440P, MKTAG('I', '4', '4', '0') },
{ AV_PIX_FMT_YUV444P, MKTAG('I', '4', '4', '4') },
{ AV_PIX_FMT_YUVJ420P, MKTAG('J', '4', '2', '0') },
{ AV_PIX_FMT_YUVJ422P, MKTAG('J', '4', '2', '2') },
{ AV_PIX_FMT_YUVJ440P, MKTAG('J', '4', '4', '0') },
{ AV_PIX_FMT_YUVJ444P, MKTAG('J', '4', '4', '4') },
{ AV_PIX_FMT_YUVA444P, MKTAG('Y', 'U', 'V', 'A') },
{ AV_PIX_FMT_YUVA420P, MKTAG('I', '4', '0', 'A') },
{ AV_PIX_FMT_YUVA422P, MKTAG('I', '4', '2', 'A') },
{ AV_PIX_FMT_RGB8, MKTAG('R', 'G', 'B', '2') },
{ AV_PIX_FMT_RGB555LE, MKTAG('R', 'V', '1', '5') },
{ AV_PIX_FMT_RGB565LE, MKTAG('R', 'V', '1', '6') },
{ AV_PIX_FMT_BGR24, MKTAG('R', 'V', '2', '4') },
{ AV_PIX_FMT_BGR0, MKTAG('R', 'V', '3', '2') },
{ AV_PIX_FMT_RGBA, MKTAG('A', 'V', '3', '2') },
{ AV_PIX_FMT_YUV420P9LE, MKTAG('I', '0', '9', 'L') },
{ AV_PIX_FMT_YUV420P9BE, MKTAG('I', '0', '9', 'B') },
{ AV_PIX_FMT_YUV422P9LE, MKTAG('I', '2', '9', 'L') },
{ AV_PIX_FMT_YUV422P9BE, MKTAG('I', '2', '9', 'B') },
{ AV_PIX_FMT_YUV444P9LE, MKTAG('I', '4', '9', 'L') },
{ AV_PIX_FMT_YUV444P9BE, MKTAG('I', '4', '9', 'B') },
{ AV_PIX_FMT_YUV420P10LE, MKTAG('I', '0', 'A', 'L') },
{ AV_PIX_FMT_YUV420P10BE, MKTAG('I', '0', 'A', 'B') },
{ AV_PIX_FMT_YUV422P10LE, MKTAG('I', '2', 'A', 'L') },
{ 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_YUV444P16LE, MKTAG('I', '4', 'F', 'L') },
{ AV_PIX_FMT_YUV444P16BE, MKTAG('I', '4', 'F', 'B') },
/* special */
{ AV_PIX_FMT_RGB565LE,MKTAG( 3 , 0 , 0 , 0 ) }, /* flipped RGB565LE */
{ AV_PIX_FMT_YUV444P, MKTAG('Y', 'V', '2', '4') }, /* YUV444P, swapped UV */
{ AV_PIX_FMT_NONE, 0 },
};
const struct PixelFormatTag *avpriv_get_raw_pix_fmt_tags(void)
{
return ff_raw_pix_fmt_tags;
}
unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat fmt)
{
const PixelFormatTag *tags = ff_raw_pix_fmt_tags;
while (tags->pix_fmt >= 0) {
if (tags->pix_fmt == fmt)
return tags->fourcc;
tags++;
}
return 0;
}
const PixelFormatTag avpriv_pix_fmt_bps_avi[] = {
{ AV_PIX_FMT_PAL8, 1 },
{ AV_PIX_FMT_PAL8, 2 },
{ AV_PIX_FMT_PAL8, 4 },
{ AV_PIX_FMT_PAL8, 8 },
{ AV_PIX_FMT_RGB444LE, 12 },
{ AV_PIX_FMT_RGB555LE, 15 },
{ AV_PIX_FMT_RGB555LE, 16 },
{ AV_PIX_FMT_BGR24, 24 },
{ AV_PIX_FMT_BGRA, 32 },
{ AV_PIX_FMT_NONE, 0 },
};
const PixelFormatTag avpriv_pix_fmt_bps_mov[] = {
{ AV_PIX_FMT_PAL8, 1 },
{ AV_PIX_FMT_PAL8, 2 },
{ AV_PIX_FMT_PAL8, 4 },
{ AV_PIX_FMT_PAL8, 8 },
{ AV_PIX_FMT_RGB555BE, 16 },
{ AV_PIX_FMT_RGB24, 24 },
{ AV_PIX_FMT_ARGB, 32 },
{ AV_PIX_FMT_PAL8, 33 },
{ AV_PIX_FMT_NONE, 0 },
};

View file

@ -0,0 +1,47 @@
/*
* Raw Video Codec
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Raw Video Codec
*/
#ifndef AVCODEC_RAW_H
#define AVCODEC_RAW_H
#include "avcodec.h"
#include "libavutil/internal.h"
typedef struct PixelFormatTag {
enum AVPixelFormat pix_fmt;
unsigned int fourcc;
} PixelFormatTag;
extern const PixelFormatTag ff_raw_pix_fmt_tags[]; // exposed through avpriv_get_raw_pix_fmt_tags()
const struct PixelFormatTag *avpriv_get_raw_pix_fmt_tags(void);
enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc);
extern av_export const PixelFormatTag avpriv_pix_fmt_bps_avi[];
extern av_export const PixelFormatTag avpriv_pix_fmt_bps_mov[];
#endif /* AVCODEC_RAW_H */

View file

@ -0,0 +1,124 @@
/*
* rectangle filling function
* 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
* useful rectangle filling function
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#ifndef AVCODEC_RECTANGLE_H
#define AVCODEC_RECTANGLE_H
#include "config.h"
#include "libavutil/common.h"
#include "libavutil/avassert.h"
/**
* fill a rectangle.
* @param h height of the rectangle, should be a constant
* @param w width of the rectangle, should be a constant
* @param size the size of val (1, 2 or 4), should be a constant
*/
static av_always_inline void fill_rectangle(void *vp, int w, int h, int stride, uint32_t val, int size){
uint8_t *p= (uint8_t*)vp;
av_assert2(size==1 || size==2 || size==4);
av_assert2(w<=4);
w *= size;
stride *= size;
av_assert2((((long)vp)&(FFMIN(w, 8<<(HAVE_NEON|ARCH_PPC|HAVE_MMX))-1)) == 0);
av_assert2((stride&(w-1))==0);
if(w==2){
const uint16_t v= size==4 ? val : val*0x0101;
*(uint16_t*)(p + 0*stride)= v;
if(h==1) return;
*(uint16_t*)(p + 1*stride)= v;
if(h==2) return;
*(uint16_t*)(p + 2*stride)= v;
*(uint16_t*)(p + 3*stride)= v;
}else if(w==4){
const uint32_t v= size==4 ? val : size==2 ? val*0x00010001 : val*0x01010101;
*(uint32_t*)(p + 0*stride)= v;
if(h==1) return;
*(uint32_t*)(p + 1*stride)= v;
if(h==2) return;
*(uint32_t*)(p + 2*stride)= v;
*(uint32_t*)(p + 3*stride)= v;
}else if(w==8){
// gcc cannot optimize 64-bit math on x86_32
#if HAVE_FAST_64BIT
const uint64_t v= size==2 ? val*0x0001000100010001ULL : val*0x0100000001ULL;
*(uint64_t*)(p + 0*stride)= v;
if(h==1) return;
*(uint64_t*)(p + 1*stride)= v;
if(h==2) return;
*(uint64_t*)(p + 2*stride)= v;
*(uint64_t*)(p + 3*stride)= v;
}else if(w==16){
const uint64_t v= val*0x0100000001ULL;
*(uint64_t*)(p + 0+0*stride)= v;
*(uint64_t*)(p + 8+0*stride)= v;
*(uint64_t*)(p + 0+1*stride)= v;
*(uint64_t*)(p + 8+1*stride)= v;
if(h==2) return;
*(uint64_t*)(p + 0+2*stride)= v;
*(uint64_t*)(p + 8+2*stride)= v;
*(uint64_t*)(p + 0+3*stride)= v;
*(uint64_t*)(p + 8+3*stride)= v;
#else
const uint32_t v= size==2 ? val*0x00010001 : val;
*(uint32_t*)(p + 0+0*stride)= v;
*(uint32_t*)(p + 4+0*stride)= v;
if(h==1) return;
*(uint32_t*)(p + 0+1*stride)= v;
*(uint32_t*)(p + 4+1*stride)= v;
if(h==2) return;
*(uint32_t*)(p + 0+2*stride)= v;
*(uint32_t*)(p + 4+2*stride)= v;
*(uint32_t*)(p + 0+3*stride)= v;
*(uint32_t*)(p + 4+3*stride)= v;
}else if(w==16){
*(uint32_t*)(p + 0+0*stride)= val;
*(uint32_t*)(p + 4+0*stride)= val;
*(uint32_t*)(p + 8+0*stride)= val;
*(uint32_t*)(p +12+0*stride)= val;
*(uint32_t*)(p + 0+1*stride)= val;
*(uint32_t*)(p + 4+1*stride)= val;
*(uint32_t*)(p + 8+1*stride)= val;
*(uint32_t*)(p +12+1*stride)= val;
if(h==2) return;
*(uint32_t*)(p + 0+2*stride)= val;
*(uint32_t*)(p + 4+2*stride)= val;
*(uint32_t*)(p + 8+2*stride)= val;
*(uint32_t*)(p +12+2*stride)= val;
*(uint32_t*)(p + 0+3*stride)= val;
*(uint32_t*)(p + 4+3*stride)= val;
*(uint32_t*)(p + 8+3*stride)= val;
*(uint32_t*)(p +12+3*stride)= val;
#endif
}else
av_assert2(0);
av_assert2(h==4);
}
#endif /* AVCODEC_RECTANGLE_H */

View file

@ -0,0 +1,439 @@
/*
* samplerate conversion for both audio and video
* Copyright (c) 2000 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* samplerate conversion for both audio and video
*/
#include <string.h>
#include "avcodec.h"
#include "audioconvert.h"
#include "libavutil/opt.h"
#include "libavutil/mem.h"
#include "libavutil/samplefmt.h"
#if FF_API_AVCODEC_RESAMPLE
FF_DISABLE_DEPRECATION_WARNINGS
#define MAX_CHANNELS 8
struct AVResampleContext;
static const char *context_to_name(void *ptr)
{
return "audioresample";
}
static const AVOption options[] = {{NULL}};
static const AVClass audioresample_context_class = {
"ReSampleContext", context_to_name, options, LIBAVUTIL_VERSION_INT
};
struct ReSampleContext {
struct AVResampleContext *resample_context;
short *temp[MAX_CHANNELS];
int temp_len;
float ratio;
/* channel convert */
int input_channels, output_channels, filter_channels;
AVAudioConvert *convert_ctx[2];
enum AVSampleFormat sample_fmt[2]; ///< input and output sample format
unsigned sample_size[2]; ///< size of one sample in sample_fmt
short *buffer[2]; ///< buffers used for conversion to S16
unsigned buffer_size[2]; ///< sizes of allocated buffers
};
/* n1: number of samples */
static void stereo_to_mono(short *output, short *input, int n1)
{
short *p, *q;
int n = n1;
p = input;
q = output;
while (n >= 4) {
q[0] = (p[0] + p[1]) >> 1;
q[1] = (p[2] + p[3]) >> 1;
q[2] = (p[4] + p[5]) >> 1;
q[3] = (p[6] + p[7]) >> 1;
q += 4;
p += 8;
n -= 4;
}
while (n > 0) {
q[0] = (p[0] + p[1]) >> 1;
q++;
p += 2;
n--;
}
}
/* n1: number of samples */
static void mono_to_stereo(short *output, short *input, int n1)
{
short *p, *q;
int n = n1;
int v;
p = input;
q = output;
while (n >= 4) {
v = p[0]; q[0] = v; q[1] = v;
v = p[1]; q[2] = v; q[3] = v;
v = p[2]; q[4] = v; q[5] = v;
v = p[3]; q[6] = v; q[7] = v;
q += 8;
p += 4;
n -= 4;
}
while (n > 0) {
v = p[0]; q[0] = v; q[1] = v;
q += 2;
p += 1;
n--;
}
}
/*
5.1 to stereo input: [fl, fr, c, lfe, rl, rr]
- Left = front_left + rear_gain * rear_left + center_gain * center
- Right = front_right + rear_gain * rear_right + center_gain * center
Where rear_gain is usually around 0.5-1.0 and
center_gain is almost always 0.7 (-3 dB)
*/
static void surround_to_stereo(short **output, short *input, int channels, int samples)
{
int i;
short l, r;
for (i = 0; i < samples; i++) {
int fl,fr,c,rl,rr;
fl = input[0];
fr = input[1];
c = input[2];
// lfe = input[3];
rl = input[4];
rr = input[5];
l = av_clip_int16(fl + (0.5 * rl) + (0.7 * c));
r = av_clip_int16(fr + (0.5 * rr) + (0.7 * c));
/* output l & r. */
*output[0]++ = l;
*output[1]++ = r;
/* increment input. */
input += channels;
}
}
static void deinterleave(short **output, short *input, int channels, int samples)
{
int i, j;
for (i = 0; i < samples; i++) {
for (j = 0; j < channels; j++) {
*output[j]++ = *input++;
}
}
}
static void interleave(short *output, short **input, int channels, int samples)
{
int i, j;
for (i = 0; i < samples; i++) {
for (j = 0; j < channels; j++) {
*output++ = *input[j]++;
}
}
}
static void ac3_5p1_mux(short *output, short *input1, short *input2, int n)
{
int i;
short l, r;
for (i = 0; i < n; i++) {
l = *input1++;
r = *input2++;
*output++ = l; /* left */
*output++ = (l / 2) + (r / 2); /* center */
*output++ = r; /* right */
*output++ = 0; /* left surround */
*output++ = 0; /* right surroud */
*output++ = 0; /* low freq */
}
}
#define SUPPORT_RESAMPLE(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8) \
ch8<<7 | ch7<<6 | ch6<<5 | ch5<<4 | ch4<<3 | ch3<<2 | ch2<<1 | ch1<<0
static const uint8_t supported_resampling[MAX_CHANNELS] = {
// output ch: 1 2 3 4 5 6 7 8
SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 0, 0, 0), // 1 input channel
SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 1, 0, 0), // 2 input channels
SUPPORT_RESAMPLE(0, 0, 1, 0, 0, 0, 0, 0), // 3 input channels
SUPPORT_RESAMPLE(0, 0, 0, 1, 0, 0, 0, 0), // 4 input channels
SUPPORT_RESAMPLE(0, 0, 0, 0, 1, 0, 0, 0), // 5 input channels
SUPPORT_RESAMPLE(0, 1, 0, 0, 0, 1, 0, 0), // 6 input channels
SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 1, 0), // 7 input channels
SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 0, 1), // 8 input channels
};
ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
int output_rate, int input_rate,
enum AVSampleFormat sample_fmt_out,
enum AVSampleFormat sample_fmt_in,
int filter_length, int log2_phase_count,
int linear, double cutoff)
{
ReSampleContext *s;
if (input_channels > MAX_CHANNELS) {
av_log(NULL, AV_LOG_ERROR,
"Resampling with input channels greater than %d is unsupported.\n",
MAX_CHANNELS);
return NULL;
}
if (!(supported_resampling[input_channels-1] & (1<<(output_channels-1)))) {
int i;
av_log(NULL, AV_LOG_ERROR, "Unsupported audio resampling. Allowed "
"output channels for %d input channel%s", input_channels,
input_channels > 1 ? "s:" : ":");
for (i = 0; i < MAX_CHANNELS; i++)
if (supported_resampling[input_channels-1] & (1<<i))
av_log(NULL, AV_LOG_ERROR, " %d", i + 1);
av_log(NULL, AV_LOG_ERROR, "\n");
return NULL;
}
s = av_mallocz(sizeof(ReSampleContext));
if (!s) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for resample context.\n");
return NULL;
}
s->ratio = (float)output_rate / (float)input_rate;
s->input_channels = input_channels;
s->output_channels = output_channels;
s->filter_channels = s->input_channels;
if (s->output_channels < s->filter_channels)
s->filter_channels = s->output_channels;
s->sample_fmt[0] = sample_fmt_in;
s->sample_fmt[1] = sample_fmt_out;
s->sample_size[0] = av_get_bytes_per_sample(s->sample_fmt[0]);
s->sample_size[1] = av_get_bytes_per_sample(s->sample_fmt[1]);
if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) {
if (!(s->convert_ctx[0] = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
s->sample_fmt[0], 1, NULL, 0))) {
av_log(s, AV_LOG_ERROR,
"Cannot convert %s sample format to s16 sample format\n",
av_get_sample_fmt_name(s->sample_fmt[0]));
av_free(s);
return NULL;
}
}
if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
if (!(s->convert_ctx[1] = av_audio_convert_alloc(s->sample_fmt[1], 1,
AV_SAMPLE_FMT_S16, 1, NULL, 0))) {
av_log(s, AV_LOG_ERROR,
"Cannot convert s16 sample format to %s sample format\n",
av_get_sample_fmt_name(s->sample_fmt[1]));
av_audio_convert_free(s->convert_ctx[0]);
av_free(s);
return NULL;
}
}
s->resample_context = av_resample_init(output_rate, input_rate,
filter_length, log2_phase_count,
linear, cutoff);
*(const AVClass**)s->resample_context = &audioresample_context_class;
return s;
}
/* resample audio. 'nb_samples' is the number of input samples */
/* XXX: optimize it ! */
int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples)
{
int i, nb_samples1;
short *bufin[MAX_CHANNELS];
short *bufout[MAX_CHANNELS];
short *buftmp2[MAX_CHANNELS], *buftmp3[MAX_CHANNELS];
short *output_bak = NULL;
int lenout;
if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) {
int istride[1] = { s->sample_size[0] };
int ostride[1] = { 2 };
const void *ibuf[1] = { input };
void *obuf[1];
unsigned input_size = nb_samples * s->input_channels * 2;
if (!s->buffer_size[0] || s->buffer_size[0] < input_size) {
av_free(s->buffer[0]);
s->buffer_size[0] = input_size;
s->buffer[0] = av_malloc(s->buffer_size[0]);
if (!s->buffer[0]) {
av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n");
return 0;
}
}
obuf[0] = s->buffer[0];
if (av_audio_convert(s->convert_ctx[0], obuf, ostride,
ibuf, istride, nb_samples * s->input_channels) < 0) {
av_log(s->resample_context, AV_LOG_ERROR,
"Audio sample format conversion failed\n");
return 0;
}
input = s->buffer[0];
}
lenout= 2*s->output_channels*nb_samples * s->ratio + 16;
if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
int out_size = lenout * av_get_bytes_per_sample(s->sample_fmt[1]) *
s->output_channels;
output_bak = output;
if (!s->buffer_size[1] || s->buffer_size[1] < out_size) {
av_free(s->buffer[1]);
s->buffer_size[1] = out_size;
s->buffer[1] = av_malloc(s->buffer_size[1]);
if (!s->buffer[1]) {
av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n");
return 0;
}
}
output = s->buffer[1];
}
/* XXX: move those malloc to resample init code */
for (i = 0; i < s->filter_channels; i++) {
bufin[i] = av_malloc_array((nb_samples + s->temp_len), sizeof(short));
bufout[i] = av_malloc_array(lenout, sizeof(short));
if (!bufin[i] || !bufout[i]) {
av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n");
nb_samples1 = 0;
goto fail;
}
memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short));
buftmp2[i] = bufin[i] + s->temp_len;
}
if (s->input_channels == 2 && s->output_channels == 1) {
buftmp3[0] = output;
stereo_to_mono(buftmp2[0], input, nb_samples);
} else if (s->output_channels >= 2 && s->input_channels == 1) {
buftmp3[0] = bufout[0];
memcpy(buftmp2[0], input, nb_samples * sizeof(short));
} else if (s->input_channels == 6 && s->output_channels ==2) {
buftmp3[0] = bufout[0];
buftmp3[1] = bufout[1];
surround_to_stereo(buftmp2, input, s->input_channels, nb_samples);
} else if (s->output_channels >= s->input_channels && s->input_channels >= 2) {
for (i = 0; i < s->input_channels; i++) {
buftmp3[i] = bufout[i];
}
deinterleave(buftmp2, input, s->input_channels, nb_samples);
} else {
buftmp3[0] = output;
memcpy(buftmp2[0], input, nb_samples * sizeof(short));
}
nb_samples += s->temp_len;
/* resample each channel */
nb_samples1 = 0; /* avoid warning */
for (i = 0; i < s->filter_channels; i++) {
int consumed;
int is_last = i + 1 == s->filter_channels;
nb_samples1 = av_resample(s->resample_context, buftmp3[i], bufin[i],
&consumed, nb_samples, lenout, is_last);
s->temp_len = nb_samples - consumed;
s->temp[i] = av_realloc_array(s->temp[i], s->temp_len, sizeof(short));
memcpy(s->temp[i], bufin[i] + consumed, s->temp_len * sizeof(short));
}
if (s->output_channels == 2 && s->input_channels == 1) {
mono_to_stereo(output, buftmp3[0], nb_samples1);
} else if (s->output_channels == 6 && s->input_channels == 2) {
ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1);
} else if ((s->output_channels == s->input_channels && s->input_channels >= 2) ||
(s->output_channels == 2 && s->input_channels == 6)) {
interleave(output, buftmp3, s->output_channels, nb_samples1);
}
if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
int istride[1] = { 2 };
int ostride[1] = { s->sample_size[1] };
const void *ibuf[1] = { output };
void *obuf[1] = { output_bak };
if (av_audio_convert(s->convert_ctx[1], obuf, ostride,
ibuf, istride, nb_samples1 * s->output_channels) < 0) {
av_log(s->resample_context, AV_LOG_ERROR,
"Audio sample format conversion failed\n");
return 0;
}
}
fail:
for (i = 0; i < s->filter_channels; i++) {
av_free(bufin[i]);
av_free(bufout[i]);
}
return nb_samples1;
}
void audio_resample_close(ReSampleContext *s)
{
int i;
av_resample_close(s->resample_context);
for (i = 0; i < s->filter_channels; i++)
av_freep(&s->temp[i]);
av_freep(&s->buffer[0]);
av_freep(&s->buffer[1]);
av_audio_convert_free(s->convert_ctx[0]);
av_audio_convert_free(s->convert_ctx[1]);
av_free(s);
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif

View file

@ -0,0 +1,319 @@
/*
* audio resampling
* Copyright (c) 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
*/
/**
* @file
* audio resampling
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include "libavutil/avassert.h"
#include "avcodec.h"
#include "libavutil/common.h"
#if FF_API_AVCODEC_RESAMPLE
#ifndef CONFIG_RESAMPLE_HP
#define FILTER_SHIFT 15
typedef int16_t FELEM;
typedef int32_t FELEM2;
typedef int64_t FELEML;
#define FELEM_MAX INT16_MAX
#define FELEM_MIN INT16_MIN
#define WINDOW_TYPE 9
#elif !defined(CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE)
#define FILTER_SHIFT 30
#define FELEM int32_t
#define FELEM2 int64_t
#define FELEML int64_t
#define FELEM_MAX INT32_MAX
#define FELEM_MIN INT32_MIN
#define WINDOW_TYPE 12
#else
#define FILTER_SHIFT 0
typedef double FELEM;
typedef double FELEM2;
typedef double FELEML;
#define WINDOW_TYPE 24
#endif
typedef struct AVResampleContext{
const AVClass *av_class;
FELEM *filter_bank;
int filter_length;
int ideal_dst_incr;
int dst_incr;
int index;
int frac;
int src_incr;
int compensation_distance;
int phase_shift;
int phase_mask;
int linear;
}AVResampleContext;
/**
* 0th order modified bessel function of the first kind.
*/
static double bessel(double x){
double v=1;
double lastv=0;
double t=1;
int i;
x= x*x/4;
for(i=1; v != lastv; i++){
lastv=v;
t *= x/(i*i);
v += t;
}
return v;
}
/**
* Build a polyphase filterbank.
* @param factor resampling factor
* @param scale wanted sum of coefficients for each filter
* @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16
* @return 0 on success, negative on error
*/
static int build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){
int ph, i;
double x, y, w;
double *tab = av_malloc_array(tap_count, sizeof(*tab));
const int center= (tap_count-1)/2;
if (!tab)
return AVERROR(ENOMEM);
/* if upsampling, only need to interpolate, no filter */
if (factor > 1.0)
factor = 1.0;
for(ph=0;ph<phase_count;ph++) {
double norm = 0;
for(i=0;i<tap_count;i++) {
x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
if (x == 0) y = 1.0;
else y = sin(x) / x;
switch(type){
case 0:{
const float d= -0.5; //first order derivative = -0.5
x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x);
else y= d*(-4 + 8*x - 5*x*x + x*x*x);
break;}
case 1:
w = 2.0*x / (factor*tap_count) + M_PI;
y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w);
break;
default:
w = 2.0*x / (factor*tap_count*M_PI);
y *= bessel(type*sqrt(FFMAX(1-w*w, 0)));
break;
}
tab[i] = y;
norm += y;
}
/* normalize so that an uniform color remains the same */
for(i=0;i<tap_count;i++) {
#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE
filter[ph * tap_count + i] = tab[i] / norm;
#else
filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm), FELEM_MIN, FELEM_MAX);
#endif
}
}
#if 0
{
#define LEN 1024
int j,k;
double sine[LEN + tap_count];
double filtered[LEN];
double maxff=-2, minff=2, maxsf=-2, minsf=2;
for(i=0; i<LEN; i++){
double ss=0, sf=0, ff=0;
for(j=0; j<LEN+tap_count; j++)
sine[j]= cos(i*j*M_PI/LEN);
for(j=0; j<LEN; j++){
double sum=0;
ph=0;
for(k=0; k<tap_count; k++)
sum += filter[ph * tap_count + k] * sine[k+j];
filtered[j]= sum / (1<<FILTER_SHIFT);
ss+= sine[j + center] * sine[j + center];
ff+= filtered[j] * filtered[j];
sf+= sine[j + center] * filtered[j];
}
ss= sqrt(2*ss/LEN);
ff= sqrt(2*ff/LEN);
sf= 2*sf/LEN;
maxff= FFMAX(maxff, ff);
minff= FFMIN(minff, ff);
maxsf= FFMAX(maxsf, sf);
minsf= FFMIN(minsf, sf);
if(i%11==0){
av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);
minff=minsf= 2;
maxff=maxsf= -2;
}
}
}
#endif
av_free(tab);
return 0;
}
AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){
AVResampleContext *c= av_mallocz(sizeof(AVResampleContext));
double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
int phase_count= 1<<phase_shift;
if (!c)
return NULL;
c->phase_shift= phase_shift;
c->phase_mask= phase_count-1;
c->linear= linear;
c->filter_length= FFMAX((int)ceil(filter_size/factor), 1);
c->filter_bank= av_mallocz_array(c->filter_length, (phase_count+1)*sizeof(FELEM));
if (!c->filter_bank)
goto error;
if (build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<<FILTER_SHIFT, WINDOW_TYPE))
goto error;
memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM));
c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1];
if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2))
goto error;
c->ideal_dst_incr= c->dst_incr;
c->index= -phase_count*((c->filter_length-1)/2);
return c;
error:
av_free(c->filter_bank);
av_free(c);
return NULL;
}
void av_resample_close(AVResampleContext *c){
av_freep(&c->filter_bank);
av_freep(&c);
}
void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){
// sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr;
c->compensation_distance= compensation_distance;
c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
}
int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){
int dst_index, i;
int index= c->index;
int frac= c->frac;
int dst_incr_frac= c->dst_incr % c->src_incr;
int dst_incr= c->dst_incr / c->src_incr;
int compensation_distance= c->compensation_distance;
if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){
int64_t index2= ((int64_t)index)<<32;
int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr);
for(dst_index=0; dst_index < dst_size; dst_index++){
dst[dst_index] = src[index2>>32];
index2 += incr;
}
index += dst_index * dst_incr;
index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
}else{
for(dst_index=0; dst_index < dst_size; dst_index++){
FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask);
int sample_index= index >> c->phase_shift;
FELEM2 val=0;
if(sample_index < 0){
for(i=0; i<c->filter_length; i++)
val += src[FFABS(sample_index + i) % src_size] * filter[i];
}else if(sample_index + c->filter_length > src_size){
break;
}else if(c->linear){
FELEM2 v2=0;
for(i=0; i<c->filter_length; i++){
val += src[sample_index + i] * (FELEM2)filter[i];
v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_length];
}
val+=(v2-val)*(FELEML)frac / c->src_incr;
}else{
for(i=0; i<c->filter_length; i++){
val += src[sample_index + i] * (FELEM2)filter[i];
}
}
#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE
dst[dst_index] = av_clip_int16(lrintf(val));
#else
val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;
dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val;
#endif
frac += dst_incr_frac;
index += dst_incr;
if(frac >= c->src_incr){
frac -= c->src_incr;
index++;
}
if(dst_index + 1 == compensation_distance){
compensation_distance= 0;
dst_incr_frac= c->ideal_dst_incr % c->src_incr;
dst_incr= c->ideal_dst_incr / c->src_incr;
}
}
}
*consumed= FFMAX(index, 0) >> c->phase_shift;
if(index>=0) index &= c->phase_mask;
if(compensation_distance){
compensation_distance -= dst_index;
av_assert2(compensation_distance > 0);
}
if(update_ctx){
c->frac= frac;
c->index= index;
c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;
c->compensation_distance= compensation_distance;
}
return dst_index;
}
#endif

View file

@ -0,0 +1 @@
#include "libavutil/reverse.c"

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2000-2002 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* rl header.
*/
#ifndef AVCODEC_RL_H
#define AVCODEC_RL_H
#include <stdint.h>
#include "vlc.h"
/* run length table */
#define MAX_RUN 64
#define MAX_LEVEL 64
/** RLTable. */
typedef struct RLTable {
int n; ///< number of entries of table_vlc minus 1
int last; ///< number of values for last = 0
const uint16_t (*table_vlc)[2];
const int8_t *table_run;
const int8_t *table_level;
uint8_t *index_run[2]; ///< encoding only
int8_t *max_level[2]; ///< encoding & decoding
int8_t *max_run[2]; ///< encoding & decoding
RL_VLC_ELEM *rl_vlc[32]; ///< decoding only
} RLTable;
/**
* @param static_store static uint8_t array[2][2*MAX_RUN + MAX_LEVEL + 3] which will hold
* the level and run tables, if this is NULL av_malloc() will be used
*/
int ff_rl_init(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]);
void ff_rl_init_vlc(RLTable *rl, unsigned static_size);
/**
* Free the contents of a dynamically allocated table.
*/
void ff_rl_free(RLTable *rl);
#define INIT_VLC_RL(rl, static_size)\
{\
int q;\
static RL_VLC_ELEM rl_vlc_table[32][static_size];\
\
if(!rl.rl_vlc[0]){\
for(q=0; q<32; q++)\
rl.rl_vlc[q]= rl_vlc_table[q];\
\
ff_rl_init_vlc(&rl, static_size);\
}\
}
static inline int get_rl_index(const RLTable *rl, int last, int run, int level)
{
int index;
index = rl->index_run[last][run];
if (index >= rl->n)
return rl->n;
if (level > rl->max_level[last][run])
return rl->n;
return index + level - 1;
}
#endif /* AVCODEC_RL_H */

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2001-2003 BERO <bero@geocities.co.jp>
* Copyright (c) 2011 Oskar Arvidsson
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_RND_AVG_H
#define AVCODEC_RND_AVG_H
#include <stddef.h>
#include <stdint.h>
#define BYTE_VEC32(c) ((c) * 0x01010101UL)
#define BYTE_VEC64(c) ((c) * 0x0001000100010001UL)
static inline uint32_t rnd_avg32(uint32_t a, uint32_t b)
{
return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
}
static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
{
return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
}
static inline uint64_t rnd_avg64(uint64_t a, uint64_t b)
{
return (a | b) - (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
}
static inline uint64_t no_rnd_avg64(uint64_t a, uint64_t b)
{
return (a & b) + (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
}
#endif /* AVCODEC_RND_AVG_H */

View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 2008 Alexander Strange <astrange@ithinksw.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Multithreading support functions
* @author Alexander Strange <astrange@ithinksw.com>
*/
#ifndef AVCODEC_THREAD_H
#define AVCODEC_THREAD_H
#include "libavutil/buffer.h"
#include "config.h"
#include "avcodec.h"
typedef struct ThreadFrame {
AVFrame *f;
AVCodecContext *owner;
// progress->data is an array of 2 ints holding progress for top/bottom
// fields
AVBufferRef *progress;
} ThreadFrame;
/**
* Wait for decoding threads to finish and reset internal state.
* Called by avcodec_flush_buffers().
*
* @param avctx The context.
*/
void ff_thread_flush(AVCodecContext *avctx);
/**
* Submit a new frame to a decoding thread.
* Returns the next available frame in picture. *got_picture_ptr
* will be 0 if none is available.
* The return value on success is the size of the consumed packet for
* compatibility with avcodec_decode_video2(). This means the decoder
* has to consume the full packet.
*
* Parameters are the same as avcodec_decode_video2().
*/
int ff_thread_decode_frame(AVCodecContext *avctx, AVFrame *picture,
int *got_picture_ptr, AVPacket *avpkt);
/**
* If the codec defines update_thread_context(), call this
* when they are ready for the next thread to start decoding
* the next frame. After calling it, do not change any variables
* read by the update_thread_context() method, or call ff_thread_get_buffer().
*
* @param avctx The context.
*/
void ff_thread_finish_setup(AVCodecContext *avctx);
/**
* Notify later decoding threads when part of their reference picture is ready.
* Call this when some part of the picture is finished decoding.
* Later calls with lower values of progress have no effect.
*
* @param f The picture being decoded.
* @param progress Value, in arbitrary units, of how much of the picture has decoded.
* @param field The field being decoded, for field-picture codecs.
* 0 for top field or frame pictures, 1 for bottom field.
*/
void ff_thread_report_progress(ThreadFrame *f, int progress, int field);
/**
* Wait for earlier decoding threads to finish reference pictures.
* Call this before accessing some part of a picture, with a given
* value for progress, and it will return after the responsible decoding
* thread calls ff_thread_report_progress() with the same or
* higher value for progress.
*
* @param f The picture being referenced.
* @param progress Value, in arbitrary units, to wait for.
* @param field The field being referenced, for field-picture codecs.
* 0 for top field or frame pictures, 1 for bottom field.
*/
void ff_thread_await_progress(ThreadFrame *f, int progress, int field);
/**
* Wrapper around get_format() for frame-multithreaded codecs.
* Call this function instead of avctx->get_format().
* Cannot be called after the codec has called ff_thread_finish_setup().
*
* @param avctx The current context.
* @param fmt The list of available formats.
*/
enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt);
/**
* Wrapper around get_buffer() for frame-multithreaded codecs.
* Call this function instead of ff_get_buffer(f).
* Cannot be called after the codec has called ff_thread_finish_setup().
*
* @param avctx The current context.
* @param f The frame to write into.
*/
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags);
/**
* Wrapper around release_buffer() frame-for multithreaded codecs.
* Call this function instead of avctx->release_buffer(f).
* The AVFrame will be copied and the actual release_buffer() call
* will be performed later. The contents of data pointed to by the
* AVFrame should not be changed until ff_thread_get_buffer() is called
* on it.
*
* @param avctx The current context.
* @param f The picture being released.
*/
void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f);
int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src);
int ff_thread_init(AVCodecContext *s);
void ff_thread_free(AVCodecContext *s);
int ff_alloc_entries(AVCodecContext *avctx, int count);
void ff_reset_entries(AVCodecContext *avctx);
void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n);
void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift);
#endif /* AVCODEC_THREAD_H */

View file

@ -0,0 +1,56 @@
/*
* copyright (c) 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_UNARY_H
#define AVCODEC_UNARY_H
#include "get_bits.h"
/**
* Get unary code of limited length
* @param gb GetBitContext
* @param[in] stop The bitstop value (unary code of 1's or 0's)
* @param[in] len Maximum length
* @return Unary length/index
*/
static inline int get_unary(GetBitContext *gb, int stop, int len)
{
int i;
for(i = 0; i < len && get_bits1(gb) != stop; i++);
return i;
}
/**
* Get unary code terminated by a 0 with a maximum length of 33
* @param gb GetBitContext
* @return Unary length/index
*/
static inline int get_unary_0_33(GetBitContext *gb)
{
return get_unary(gb, 0, 33);
}
static inline int get_unary_0_9(GetBitContext *gb)
{
return get_unary(gb, 0, 9);
}
#endif /* AVCODEC_UNARY_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,230 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_VERSION_H
#define AVCODEC_VERSION_H
/**
* @file
* @ingroup libavc
* Libavcodec version macros.
*/
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 57
#define LIBAVCODEC_VERSION_MINOR 48
#define LIBAVCODEC_VERSION_MICRO 101
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
LIBAVCODEC_VERSION_MICRO)
#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
LIBAVCODEC_VERSION_MICRO)
#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT
#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
/**
* FF_API_* defines may be placed below to indicate public API that will be
* dropped at a future version bump. The defines themselves are not part of
* the public API and may change, break or disappear at any time.
*
* @note, when bumping the major version it is recommended to manually
* disable each FF_API_* in its own commit instead of disabling them all
* at once through the bump. This improves the git bisect-ability of the change.
*/
#ifndef FF_API_VIMA_DECODER
#define FF_API_VIMA_DECODER (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_AUDIO_CONVERT
#define FF_API_AUDIO_CONVERT (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#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
#ifndef FF_API_LOWRES
#define FF_API_LOWRES (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_CAP_VDPAU
#define FF_API_CAP_VDPAU (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_BUFS_VDPAU
#define FF_API_BUFS_VDPAU (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_VOXWARE
#define FF_API_VOXWARE (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_SET_DIMENSIONS
#define FF_API_SET_DIMENSIONS (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_DEBUG_MV
#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_AC_VLC
#define FF_API_AC_VLC (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_OLD_MSMPEG4
#define FF_API_OLD_MSMPEG4 (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_ASPECT_EXTENDED
#define FF_API_ASPECT_EXTENDED (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_ARCH_ALPHA
#define FF_API_ARCH_ALPHA (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_XVMC
#define FF_API_XVMC (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_ERROR_RATE
#define FF_API_ERROR_RATE (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_QSCALE_TYPE
#define FF_API_QSCALE_TYPE (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_MB_TYPE
#define FF_API_MB_TYPE (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_MAX_BFRAMES
#define FF_API_MAX_BFRAMES (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_NEG_LINESIZES
#define FF_API_NEG_LINESIZES (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_EMU_EDGE
#define FF_API_EMU_EDGE (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_ARCH_SH4
#define FF_API_ARCH_SH4 (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_ARCH_SPARC
#define FF_API_ARCH_SPARC (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_UNUSED_MEMBERS
#define FF_API_UNUSED_MEMBERS (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_IDCT_XVIDMMX
#define FF_API_IDCT_XVIDMMX (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_INPUT_PRESERVED
#define FF_API_INPUT_PRESERVED (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_NORMALIZE_AQP
#define FF_API_NORMALIZE_AQP (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_GMC
#define FF_API_GMC (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_MV0
#define FF_API_MV0 (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_CODEC_NAME
#define FF_API_CODEC_NAME (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_AFD
#define FF_API_AFD (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_VISMV
/* XXX: don't forget to drop the -vismv documentation */
#define FF_API_VISMV (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_AUDIOENC_DELAY
#define FF_API_AUDIOENC_DELAY (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_VAAPI_CONTEXT
#define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 58)
#endif
#ifndef FF_API_AVCTX_TIMEBASE
#define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_MPV_OPT
#define FF_API_MPV_OPT (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_STREAM_CODEC_TAG
#define FF_API_STREAM_CODEC_TAG (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_QUANT_BIAS
#define FF_API_QUANT_BIAS (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_RC_STRATEGY
#define FF_API_RC_STRATEGY (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_CODED_FRAME
#define FF_API_CODED_FRAME (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_MOTION_EST
#define FF_API_MOTION_EST (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_WITHOUT_PREFIX
#define FF_API_WITHOUT_PREFIX (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_SIDEDATA_ONLY_PKT
#define FF_API_SIDEDATA_ONLY_PKT (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_VDPAU_PROFILE
#define FF_API_VDPAU_PROFILE (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_CONVERGENCE_DURATION
#define FF_API_CONVERGENCE_DURATION (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_AVPICTURE
#define FF_API_AVPICTURE (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_AVPACKET_OLD_API
#define FF_API_AVPACKET_OLD_API (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_RTP_CALLBACK
#define FF_API_RTP_CALLBACK (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_VBV_DELAY
#define FF_API_VBV_DELAY (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_CODER_TYPE
#define FF_API_CODER_TYPE (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_STAT_BITS
#define FF_API_STAT_BITS (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_PRIVATE_OPT
#define FF_API_PRIVATE_OPT (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_ASS_TIMING
#define FF_API_ASS_TIMING (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_OLD_BSF
#define FF_API_OLD_BSF (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_COPY_CONTEXT
#define FF_API_COPY_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_GET_CONTEXT_DEFAULTS
#define FF_API_GET_CONTEXT_DEFAULTS (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#ifndef FF_API_NVENC_OLD_NAME
#define FF_API_NVENC_OLD_NAME (LIBAVCODEC_VERSION_MAJOR < 59)
#endif
#endif /* AVCODEC_VERSION_H */

View file

@ -0,0 +1,55 @@
/*
* Copyright (C) 2012 Ronald S. Bultje
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "videodsp.h"
#define BIT_DEPTH 8
#include "videodsp_template.c"
#undef BIT_DEPTH
#define BIT_DEPTH 16
#include "videodsp_template.c"
#undef BIT_DEPTH
static void just_return(uint8_t *buf, ptrdiff_t stride, int h)
{
}
av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
{
ctx->prefetch = just_return;
if (bpc <= 8) {
ctx->emulated_edge_mc = ff_emulated_edge_mc_8;
} else {
ctx->emulated_edge_mc = ff_emulated_edge_mc_16;
}
if (ARCH_AARCH64)
ff_videodsp_init_aarch64(ctx, bpc);
if (ARCH_ARM)
ff_videodsp_init_arm(ctx, bpc);
if (ARCH_PPC)
ff_videodsp_init_ppc(ctx, bpc);
if (ARCH_X86)
ff_videodsp_init_x86(ctx, bpc);
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (C) 2012 Ronald S. Bultje
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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
* Core video DSP helper functions
*/
#ifndef AVCODEC_VIDEODSP_H
#define AVCODEC_VIDEODSP_H
#include <stddef.h>
#include <stdint.h>
#define EMULATED_EDGE(depth) \
void ff_emulated_edge_mc_ ## depth(uint8_t *dst, const uint8_t *src, \
ptrdiff_t dst_stride, ptrdiff_t src_stride, \
int block_w, int block_h,\
int src_x, int src_y, int w, int h);
EMULATED_EDGE(8)
EMULATED_EDGE(16)
typedef struct VideoDSPContext {
/**
* Copy a rectangular area of samples to a temporary buffer and replicate
* the border samples.
*
* @param dst destination buffer
* @param dst_stride number of bytes between 2 vertically adjacent samples
* in destination buffer
* @param src source buffer
* @param dst_linesize number of bytes between 2 vertically adjacent
* samples in the destination buffer
* @param src_linesize number of bytes between 2 vertically adjacent
* samples in both the source buffer
* @param block_w width of block
* @param block_h height of block
* @param src_x x coordinate of the top left sample of the block in the
* source buffer
* @param src_y y coordinate of the top left sample of the block in the
* source buffer
* @param w width of the source buffer
* @param h height of the source buffer
*/
void (*emulated_edge_mc)(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_linesize,
ptrdiff_t src_linesize,
int block_w, int block_h,
int src_x, int src_y, int w, int h);
/**
* Prefetch memory into cache (if supported by hardware).
*
* @param buf pointer to buffer to prefetch memory from
* @param stride distance between two lines of buf (in bytes)
* @param h number of lines to prefetch
*/
void (*prefetch)(uint8_t *buf, ptrdiff_t stride, int h);
} VideoDSPContext;
void ff_videodsp_init(VideoDSPContext *ctx, int bpc);
/* for internal use only (i.e. called by ff_videodsp_init() */
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);
#endif /* AVCODEC_VIDEODSP_H */

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2002-2012 Michael Niedermayer
* Copyright (C) 2012 Ronald S. Bultje
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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 "bit_depth_template.c"
void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
ptrdiff_t buf_linesize,
ptrdiff_t src_linesize,
int block_w, int block_h,
int src_x, int src_y, int w, int h)
{
int x, y;
int start_y, start_x, end_y, end_x;
if (!w || !h)
return;
av_assert2(block_w * sizeof(pixel) <= FFABS(buf_linesize));
if (src_y >= h) {
src -= src_y * src_linesize;
src += (h - 1) * src_linesize;
src_y = h - 1;
} else if (src_y <= -block_h) {
src -= src_y * src_linesize;
src += (1 - block_h) * src_linesize;
src_y = 1 - block_h;
}
if (src_x >= w) {
src += (w - 1 - src_x) * sizeof(pixel);
src_x = w - 1;
} else if (src_x <= -block_w) {
src += (1 - block_w - src_x) * sizeof(pixel);
src_x = 1 - block_w;
}
start_y = FFMAX(0, -src_y);
start_x = FFMAX(0, -src_x);
end_y = FFMIN(block_h, h-src_y);
end_x = FFMIN(block_w, w-src_x);
av_assert2(start_y < end_y && block_h);
av_assert2(start_x < end_x && block_w);
w = end_x - start_x;
src += start_y * src_linesize + start_x * sizeof(pixel);
buf += start_x * sizeof(pixel);
// top
for (y = 0; y < start_y; y++) {
memcpy(buf, src, w * sizeof(pixel));
buf += buf_linesize;
}
// copy existing part
for (; y < end_y; y++) {
memcpy(buf, src, w * sizeof(pixel));
src += src_linesize;
buf += buf_linesize;
}
// bottom
src -= src_linesize;
for (; y < block_h; y++) {
memcpy(buf, src, w * sizeof(pixel));
buf += buf_linesize;
}
buf -= block_h * buf_linesize + start_x * sizeof(pixel);
while (block_h--) {
pixel *bufp = (pixel *) buf;
// left
for(x = 0; x < start_x; x++) {
bufp[x] = bufp[start_x];
}
// right
for (x = end_x; x < block_w; x++) {
bufp[x] = bufp[end_x - 1];
}
buf += buf_linesize;
}
}

View file

@ -0,0 +1,65 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_VLC_H
#define AVCODEC_VLC_H
#include <stdint.h>
#define VLC_TYPE int16_t
typedef struct VLC {
int bits;
VLC_TYPE (*table)[2]; ///< code, bits
int table_size, table_allocated;
} VLC;
typedef struct RL_VLC_ELEM {
int16_t level;
int8_t len;
uint8_t run;
} RL_VLC_ELEM;
#define init_vlc(vlc, nb_bits, nb_codes, \
bits, bits_wrap, bits_size, \
codes, codes_wrap, codes_size, \
flags) \
ff_init_vlc_sparse(vlc, nb_bits, nb_codes, \
bits, bits_wrap, bits_size, \
codes, codes_wrap, codes_size, \
NULL, 0, 0, flags)
int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
const void *symbols, int symbols_wrap, int symbols_size,
int flags);
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) \
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); \
} while (0)
#endif /* AVCODEC_VLC_H */

View file

@ -0,0 +1,341 @@
/*
* Copyright (c) 2012 Justin Ruggles
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Vorbis audio parser
*
* Determines the duration for each packet.
*/
#include "libavutil/log.h"
#include "get_bits.h"
#include "parser.h"
#include "xiph.h"
#include "vorbis_parser_internal.h"
static const AVClass vorbis_parser_class = {
.class_name = "Vorbis parser",
.item_name = av_default_item_name,
.version = LIBAVUTIL_VERSION_INT,
};
static int parse_id_header(AVVorbisParseContext *s,
const uint8_t *buf, int buf_size)
{
/* Id header should be 30 bytes */
if (buf_size < 30) {
av_log(s, AV_LOG_ERROR, "Id header is too short\n");
return AVERROR_INVALIDDATA;
}
/* make sure this is the Id header */
if (buf[0] != 1) {
av_log(s, AV_LOG_ERROR, "Wrong packet type in Id header\n");
return AVERROR_INVALIDDATA;
}
/* check for header signature */
if (memcmp(&buf[1], "vorbis", 6)) {
av_log(s, AV_LOG_ERROR, "Invalid packet signature in Id header\n");
return AVERROR_INVALIDDATA;
}
if (!(buf[29] & 0x1)) {
av_log(s, AV_LOG_ERROR, "Invalid framing bit in Id header\n");
return AVERROR_INVALIDDATA;
}
s->blocksize[0] = 1 << (buf[28] & 0xF);
s->blocksize[1] = 1 << (buf[28] >> 4);
return 0;
}
static int parse_setup_header(AVVorbisParseContext *s,
const uint8_t *buf, int buf_size)
{
GetBitContext gb, gb0;
uint8_t *rev_buf;
int i, ret = 0;
int got_framing_bit, mode_count, got_mode_header, last_mode_count = 0;
/* avoid overread */
if (buf_size < 7) {
av_log(s, AV_LOG_ERROR, "Setup header is too short\n");
return AVERROR_INVALIDDATA;
}
/* make sure this is the Setup header */
if (buf[0] != 5) {
av_log(s, AV_LOG_ERROR, "Wrong packet type in Setup header\n");
return AVERROR_INVALIDDATA;
}
/* check for header signature */
if (memcmp(&buf[1], "vorbis", 6)) {
av_log(s, AV_LOG_ERROR, "Invalid packet signature in Setup header\n");
return AVERROR_INVALIDDATA;
}
/* reverse bytes so we can easily read backwards with get_bits() */
if (!(rev_buf = av_malloc(buf_size))) {
av_log(s, AV_LOG_ERROR, "Out of memory\n");
return AVERROR(ENOMEM);
}
for (i = 0; i < buf_size; i++)
rev_buf[i] = buf[buf_size - 1 - i];
init_get_bits(&gb, rev_buf, buf_size * 8);
got_framing_bit = 0;
while (get_bits_left(&gb) > 97) {
if (get_bits1(&gb)) {
got_framing_bit = get_bits_count(&gb);
break;
}
}
if (!got_framing_bit) {
av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
ret = AVERROR_INVALIDDATA;
goto bad_header;
}
/* Now we search backwards to find possible valid mode counts. This is not
* fool-proof because we could have false positive matches and read too
* far, but there isn't really any way to be sure without parsing through
* all the many variable-sized fields before the modes. This approach seems
* to work well in testing, and it is similar to how it is handled in
* liboggz. */
mode_count = 0;
got_mode_header = 0;
while (get_bits_left(&gb) >= 97) {
if (get_bits(&gb, 8) > 63 || get_bits(&gb, 16) || get_bits(&gb, 16))
break;
skip_bits(&gb, 1);
mode_count++;
if (mode_count > 64)
break;
gb0 = gb;
if (get_bits(&gb0, 6) + 1 == mode_count) {
got_mode_header = 1;
last_mode_count = mode_count;
}
}
if (!got_mode_header) {
av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
ret = AVERROR_INVALIDDATA;
goto bad_header;
}
/* All samples I've seen use <= 2 modes, so ask for a sample if we find
* more than that, as it is most likely a false positive. If we get any
* we may need to approach this the long way and parse the whole Setup
* header, but I hope very much that it never comes to that. */
if (last_mode_count > 2) {
avpriv_request_sample(s,
"%d modes (either a false positive or a "
"sample from an unknown encoder)",
last_mode_count);
}
/* We're limiting the mode count to 63 so that we know that the previous
* block flag will be in the first packet byte. */
if (last_mode_count > 63) {
av_log(s, AV_LOG_ERROR, "Unsupported mode count: %d\n",
last_mode_count);
ret = AVERROR_INVALIDDATA;
goto bad_header;
}
s->mode_count = mode_count = last_mode_count;
/* Determine the number of bits required to code the mode and turn that
* into a bitmask to directly access the mode from the first frame byte. */
s->mode_mask = ((1 << (av_log2(mode_count - 1) + 1)) - 1) << 1;
/* The previous window flag is the next bit after the mode */
s->prev_mask = (s->mode_mask | 0x1) + 1;
init_get_bits(&gb, rev_buf, buf_size * 8);
skip_bits_long(&gb, got_framing_bit);
for (i = mode_count - 1; i >= 0; i--) {
skip_bits_long(&gb, 40);
s->mode_blocksize[i] = get_bits1(&gb);
}
bad_header:
av_free(rev_buf);
return ret;
}
static int vorbis_parse_init(AVVorbisParseContext *s,
const uint8_t *extradata, int extradata_size)
{
const uint8_t *header_start[3];
int header_len[3];
int ret;
s->class = &vorbis_parser_class;
s->extradata_parsed = 1;
if ((ret = avpriv_split_xiph_headers(extradata,
extradata_size, 30,
header_start, header_len)) < 0) {
av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
return ret;
}
if ((ret = parse_id_header(s, header_start[0], header_len[0])) < 0)
return ret;
if ((ret = parse_setup_header(s, header_start[2], header_len[2])) < 0)
return ret;
s->valid_extradata = 1;
s->previous_blocksize = s->blocksize[s->mode_blocksize[0]];
return 0;
}
int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf,
int buf_size, int *flags)
{
int duration = 0;
if (s->valid_extradata && buf_size > 0) {
int mode, current_blocksize;
int previous_blocksize = s->previous_blocksize;
if (buf[0] & 1) {
/* If the user doesn't care about special packets, it's a bad one. */
if (!flags)
goto bad_packet;
/* Set the flag for which kind of special packet it is. */
if (buf[0] == 1)
*flags |= VORBIS_FLAG_HEADER;
else if (buf[0] == 3)
*flags |= VORBIS_FLAG_COMMENT;
else if (buf[0] == 5)
*flags |= VORBIS_FLAG_SETUP;
else
goto bad_packet;
/* Special packets have no duration. */
return 0;
bad_packet:
av_log(s, AV_LOG_ERROR, "Invalid packet\n");
return AVERROR_INVALIDDATA;
}
if (s->mode_count == 1)
mode = 0;
else
mode = (buf[0] & s->mode_mask) >> 1;
if (mode >= s->mode_count) {
av_log(s, AV_LOG_ERROR, "Invalid mode in packet\n");
return AVERROR_INVALIDDATA;
}
if(s->mode_blocksize[mode]){
int flag = !!(buf[0] & s->prev_mask);
previous_blocksize = s->blocksize[flag];
}
current_blocksize = s->blocksize[s->mode_blocksize[mode]];
duration = (previous_blocksize + current_blocksize) >> 2;
s->previous_blocksize = current_blocksize;
}
return duration;
}
int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf,
int buf_size)
{
return av_vorbis_parse_frame_flags(s, buf, buf_size, NULL);
}
void av_vorbis_parse_reset(AVVorbisParseContext *s)
{
if (s->valid_extradata)
s->previous_blocksize = s->blocksize[0];
}
void av_vorbis_parse_free(AVVorbisParseContext **s)
{
av_freep(s);
}
AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata,
int extradata_size)
{
AVVorbisParseContext *s = av_mallocz(sizeof(*s));
int ret;
if (!s)
return NULL;
ret = vorbis_parse_init(s, extradata, extradata_size);
if (ret < 0) {
av_vorbis_parse_free(&s);
return NULL;
}
return s;
}
#if CONFIG_VORBIS_PARSER
typedef struct VorbisParseContext {
AVVorbisParseContext *vp;
} VorbisParseContext;
static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
VorbisParseContext *s = s1->priv_data;
int duration;
if (!s->vp && avctx->extradata && avctx->extradata_size) {
s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size);
}
if (!s->vp)
goto end;
if ((duration = av_vorbis_parse_frame(s->vp, buf, buf_size)) >= 0)
s1->duration = duration;
end:
/* always return the full packet. this parser isn't doing any splitting or
combining, only packet analysis */
*poutbuf = buf;
*poutbuf_size = buf_size;
return buf_size;
}
static void vorbis_parser_close(AVCodecParserContext *ctx)
{
VorbisParseContext *s = ctx->priv_data;
av_vorbis_parse_free(&s->vp);
}
AVCodecParser ff_vorbis_parser = {
.codec_ids = { AV_CODEC_ID_VORBIS },
.priv_data_size = sizeof(VorbisParseContext),
.parser_parse = vorbis_parse,
.parser_close = vorbis_parser_close,
};
#endif /* CONFIG_VORBIS_PARSER */

View file

@ -0,0 +1,77 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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
* A public API for Vorbis parsing
*
* Determines the duration for each packet.
*/
#ifndef AVCODEC_VORBIS_PARSER_H
#define AVCODEC_VORBIS_PARSER_H
#include <stdint.h>
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);
/**
* Free the parser and everything associated with it.
*/
void av_vorbis_parse_free(AVVorbisParseContext **s);
#define VORBIS_FLAG_HEADER 0x00000001
#define VORBIS_FLAG_COMMENT 0x00000002
#define VORBIS_FLAG_SETUP 0x00000004
/**
* Get the duration for a Vorbis packet.
*
* If @p flags is @c NULL,
* special frames are considered invalid.
*
* @param s Vorbis parser context
* @param buf buffer containing a Vorbis frame
* @param buf_size size of the buffer
* @param flags flags for special frames
*/
int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf,
int buf_size, int *flags);
/**
* Get the duration for a Vorbis packet.
*
* @param s Vorbis parser context
* @param buf buffer containing a Vorbis frame
* @param buf_size size of the buffer
*/
int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf,
int buf_size);
void av_vorbis_parse_reset(AVVorbisParseContext *s);
#endif /* AVCODEC_VORBIS_PARSER_H */

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2012 Justin Ruggles
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Vorbis audio parser
*
* Determines the duration for each packet.
*/
#ifndef AVCODEC_VORBIS_PARSER_INTERNAL_H
#define AVCODEC_VORBIS_PARSER_INTERNAL_H
#include "avcodec.h"
#include "vorbis_parser.h"
struct AVVorbisParseContext {
const AVClass *class;
int extradata_parsed; ///< we have attempted to parse extradata
int valid_extradata; ///< extradata is valid, so we can calculate duration
int blocksize[2]; ///< short and long window sizes
int previous_blocksize; ///< previous window size
int mode_blocksize[64]; ///< window size mapping for each mode
int mode_count; ///< number of modes
int mode_mask; ///< bitmask used to get the mode in each packet
int prev_mask; ///< bitmask used to get the previous mode flag in each packet
};
#endif /* AVCODEC_VORBIS_PARSER_INTERNAL_H */

View file

@ -0,0 +1,53 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General 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_VP3DSP_H
#define AVCODEC_VP3DSP_H
#include <stddef.h>
#include <stdint.h>
typedef struct VP3DSPContext {
/**
* Copy 8xH pixels from source to destination buffer using a bilinear
* filter with no rounding (i.e. *dst = (*a + *b) >> 1).
*
* @param dst destination buffer, aligned by 8
* @param a first source buffer, no alignment
* @param b second source buffer, no alignment
* @param stride distance between two lines in source/dest buffers
* @param h height
*/
void (*put_no_rnd_pixels_l2)(uint8_t *dst,
const uint8_t *a,
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);
} VP3DSPContext;
void ff_vp3dsp_init(VP3DSPContext *c, int flags);
void ff_vp3dsp_init_arm(VP3DSPContext *c, int flags);
void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags);
void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags);
#endif /* AVCODEC_VP3DSP_H */

View file

@ -0,0 +1,400 @@
/*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* VP5 and VP6 compatible video decoder (common features)
*/
#ifndef AVCODEC_VP56_H
#define AVCODEC_VP56_H
#include "get_bits.h"
#include "hpeldsp.h"
#include "bytestream.h"
#include "h264chroma.h"
#include "videodsp.h"
#include "vp3dsp.h"
#include "vp56dsp.h"
typedef struct vp56_context VP56Context;
typedef enum {
VP56_FRAME_NONE =-1,
VP56_FRAME_CURRENT = 0,
VP56_FRAME_PREVIOUS = 1,
VP56_FRAME_GOLDEN = 2,
VP56_FRAME_GOLDEN2 = 3,
} VP56Frame;
typedef enum {
VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */
VP56_MB_INTRA = 1, /**< Intra MB */
VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */
VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */
VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */
VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */
VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */
VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */
VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */
VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */
} VP56mb;
typedef struct VP56Tree {
int8_t val;
int8_t prob_idx;
} VP56Tree;
typedef struct VP56mv {
DECLARE_ALIGNED(4, int16_t, x);
int16_t y;
} VP56mv;
#define VP56_SIZE_CHANGE 1
typedef void (*VP56ParseVectorAdjustment)(VP56Context *s,
VP56mv *vect);
typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src,
int offset1, int offset2, int stride,
VP56mv mv, int mask, int select, int luma);
typedef void (*VP56ParseCoeff)(VP56Context *s);
typedef void (*VP56DefaultModelsInit)(VP56Context *s);
typedef void (*VP56ParseVectorModels)(VP56Context *s);
typedef int (*VP56ParseCoeffModels)(VP56Context *s);
typedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf,
int buf_size);
typedef struct VP56RangeCoder {
int high;
int bits; /* stored negated (i.e. negative "bits" is a positive number of
bits left) in order to eliminate a negate in cache refilling */
const uint8_t *buffer;
const uint8_t *end;
unsigned int code_word;
} VP56RangeCoder;
typedef struct VP56RefDc {
uint8_t not_null_dc;
VP56Frame ref_frame;
int16_t dc_coeff;
} VP56RefDc;
typedef struct VP56Macroblock {
uint8_t type;
VP56mv mv;
} VP56Macroblock;
typedef struct VP56Model {
uint8_t coeff_reorder[64]; /* used in vp6 only */
uint8_t coeff_index_to_pos[64]; /* used in vp6 only */
uint8_t vector_sig[2]; /* delta sign */
uint8_t vector_dct[2]; /* delta coding types */
uint8_t vector_pdi[2][2]; /* predefined delta init */
uint8_t vector_pdv[2][7]; /* predefined delta values */
uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */
uint8_t coeff_dccv[2][11]; /* DC coeff value */
uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */
uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */
uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */
uint8_t coeff_runv[2][14]; /* run value (vp6 only) */
uint8_t mb_type[3][10][10]; /* model for decoding MB type */
uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */
} VP56Model;
struct vp56_context {
AVCodecContext *avctx;
H264ChromaContext h264chroma;
HpelDSPContext hdsp;
VideoDSPContext vdsp;
VP3DSPContext vp3dsp;
VP56DSPContext vp56dsp;
uint8_t idct_scantable[64];
AVFrame *frames[4];
uint8_t *edge_emu_buffer_alloc;
uint8_t *edge_emu_buffer;
VP56RangeCoder c;
VP56RangeCoder cc;
VP56RangeCoder *ccp;
int sub_version;
/* frame info */
int golden_frame;
int plane_width[4];
int plane_height[4];
int mb_width; /* number of horizontal MB */
int mb_height; /* number of vertical MB */
int block_offset[6];
int quantizer;
uint16_t dequant_dc;
uint16_t dequant_ac;
/* DC predictors management */
VP56RefDc *above_blocks;
VP56RefDc left_block[4];
int above_block_idx[6];
int16_t prev_dc[3][3]; /* [plan][ref_frame] */
/* blocks / macroblock */
VP56mb mb_type;
VP56Macroblock *macroblocks;
DECLARE_ALIGNED(16, int16_t, block_coeff)[6][64];
/* motion vectors */
VP56mv mv[6]; /* vectors for each block in MB */
VP56mv vector_candidate[2];
int vector_candidate_pos;
/* filtering hints */
int filter_header; /* used in vp6 only */
int deblock_filtering;
int filter_selection;
int filter_mode;
int max_vector_length;
int sample_variance_threshold;
uint8_t coeff_ctx[4][64]; /* used in vp5 only */
uint8_t coeff_ctx_last[4]; /* used in vp5 only */
int has_alpha;
/* upside-down flipping hints */
int flip; /* are we flipping ? */
int frbi; /* first row block index in MB */
int srbi; /* second row block index in MB */
int stride[4]; /* stride for each plan */
const uint8_t *vp56_coord_div;
VP56ParseVectorAdjustment parse_vector_adjustment;
VP56Filter filter;
VP56ParseCoeff parse_coeff;
VP56DefaultModelsInit default_models_init;
VP56ParseVectorModels parse_vector_models;
VP56ParseCoeffModels parse_coeff_models;
VP56ParseHeader parse_header;
/* for "slice" parallelism between YUV and A */
VP56Context *alpha_context;
VP56Model *modelp;
VP56Model model;
/* huffman decoding */
int use_huffman;
GetBitContext gb;
VLC dccv_vlc[2];
VLC runv_vlc[2];
VLC ract_vlc[2][3][6];
unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */
};
int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
int flip, int has_alpha);
int ff_vp56_free(AVCodecContext *avctx);
int ff_vp56_free_context(VP56Context *s);
void ff_vp56_init_dequant(VP56Context *s, int quantizer);
int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
AVPacket *avpkt);
/**
* vp56 specific range coder implementation
*/
extern const uint8_t ff_vp56_norm_shift[256];
void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size);
static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
{
int shift = ff_vp56_norm_shift[c->high];
int bits = c->bits;
unsigned int code_word = c->code_word;
c->high <<= shift;
code_word <<= shift;
bits += shift;
if(bits >= 0 && c->buffer < c->end) {
code_word |= bytestream_get_be16(&c->buffer) << bits;
bits -= 16;
}
c->bits = bits;
return code_word;
}
#if ARCH_ARM
#include "arm/vp56_arith.h"
#elif ARCH_X86
#include "x86/vp56_arith.h"
#endif
#ifndef vp56_rac_get_prob
#define vp56_rac_get_prob vp56_rac_get_prob
static av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob)
{
unsigned int code_word = vp56_rac_renorm(c);
unsigned int low = 1 + (((c->high - 1) * prob) >> 8);
unsigned int low_shift = low << 16;
int bit = code_word >= low_shift;
c->high = bit ? c->high - low : low;
c->code_word = bit ? code_word - low_shift : code_word;
return bit;
}
#endif
#ifndef vp56_rac_get_prob_branchy
// branchy variant, to be used where there's a branch based on the bit decoded
static av_always_inline int vp56_rac_get_prob_branchy(VP56RangeCoder *c, int prob)
{
unsigned long code_word = vp56_rac_renorm(c);
unsigned low = 1 + (((c->high - 1) * prob) >> 8);
unsigned low_shift = low << 16;
if (code_word >= low_shift) {
c->high -= low;
c->code_word = code_word - low_shift;
return 1;
}
c->high = low;
c->code_word = code_word;
return 0;
}
#endif
static av_always_inline int vp56_rac_get(VP56RangeCoder *c)
{
unsigned int code_word = vp56_rac_renorm(c);
/* equiprobable */
int low = (c->high + 1) >> 1;
unsigned int low_shift = low << 16;
int bit = code_word >= low_shift;
if (bit) {
c->high -= low;
code_word -= low_shift;
} else {
c->high = low;
}
c->code_word = code_word;
return bit;
}
// rounding is different than vp56_rac_get, is vp56_rac_get wrong?
static av_always_inline int vp8_rac_get(VP56RangeCoder *c)
{
return vp56_rac_get_prob(c, 128);
}
static int vp56_rac_gets(VP56RangeCoder *c, int bits)
{
int value = 0;
while (bits--) {
value = (value << 1) | vp56_rac_get(c);
}
return value;
}
static int vp8_rac_get_uint(VP56RangeCoder *c, int bits)
{
int value = 0;
while (bits--) {
value = (value << 1) | vp8_rac_get(c);
}
return value;
}
// fixme: add 1 bit to all the calls to this?
static av_unused int vp8_rac_get_sint(VP56RangeCoder *c, int bits)
{
int v;
if (!vp8_rac_get(c))
return 0;
v = vp8_rac_get_uint(c, bits);
if (vp8_rac_get(c))
v = -v;
return v;
}
// P(7)
static av_unused int vp56_rac_gets_nn(VP56RangeCoder *c, int bits)
{
int v = vp56_rac_gets(c, 7) << 1;
return v + !v;
}
static av_unused int vp8_rac_get_nn(VP56RangeCoder *c)
{
int v = vp8_rac_get_uint(c, 7) << 1;
return v + !v;
}
static av_always_inline
int vp56_rac_get_tree(VP56RangeCoder *c,
const VP56Tree *tree,
const uint8_t *probs)
{
while (tree->val > 0) {
if (vp56_rac_get_prob_branchy(c, probs[tree->prob_idx]))
tree += tree->val;
else
tree++;
}
return -tree->val;
}
// how probabilities are associated with decisions is different I think
// well, the new scheme fits in the old but this way has one fewer branches per decision
static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2],
const uint8_t *probs)
{
int i = 0;
do {
i = tree[i][vp56_rac_get_prob(c, probs[i])];
} while (i > 0);
return -i;
}
// DCTextra
static av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob)
{
int v = 0;
do {
v = (v<<1) + vp56_rac_get_prob(c, *prob++);
} while (*prob);
return v;
}
#endif /* AVCODEC_VP56_H */

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_VP56DSP_H
#define AVCODEC_VP56DSP_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 (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, int 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,
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);
#endif /* AVCODEC_VP56DSP_H */

View file

@ -0,0 +1,47 @@
/*
* VP5/6/8 decoder
* Copyright (c) 2010 Fiona Glaser <fiona@x264.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/common.h"
#include "vp56.h"
const uint8_t ff_vp56_norm_shift[256]= {
8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size)
{
c->high = 255;
c->bits = -16;
c->buffer = buf;
c->end = buf + buf_size;
c->code_word = bytestream_get_be24(&c->buffer);
}

2858
media/ffvpx/libavcodec/vp8.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,311 @@
/*
* VP8 compatible video decoder
*
* Copyright (C) 2010 David Conrad
* Copyright (C) 2010 Ronald S. Bultje
* Copyright (C) 2010 Fiona Glaser
* Copyright (C) 2012 Daniel Kang
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_VP8_H
#define AVCODEC_VP8_H
#include "libavutil/buffer.h"
#include "libavutil/thread.h"
#include "h264pred.h"
#include "thread.h"
#include "vp56.h"
#include "vp8dsp.h"
#define VP8_MAX_QUANT 127
enum dct_token {
DCT_0,
DCT_1,
DCT_2,
DCT_3,
DCT_4,
DCT_CAT1,
DCT_CAT2,
DCT_CAT3,
DCT_CAT4,
DCT_CAT5,
DCT_CAT6,
DCT_EOB,
NUM_DCT_TOKENS
};
// used to signal 4x4 intra pred in luma MBs
#define MODE_I4x4 4
enum inter_mvmode {
VP8_MVMODE_ZERO = MODE_I4x4 + 1,
VP8_MVMODE_MV,
VP8_MVMODE_SPLIT
};
enum inter_splitmvmode {
VP8_SPLITMVMODE_16x8 = 0, ///< 2 16x8 blocks (vertical)
VP8_SPLITMVMODE_8x16, ///< 2 8x16 blocks (horizontal)
VP8_SPLITMVMODE_8x8, ///< 2x2 blocks of 8x8px each
VP8_SPLITMVMODE_4x4, ///< 4x4 blocks of 4x4px each
VP8_SPLITMVMODE_NONE, ///< (only used in prediction) no split MVs
};
typedef struct VP8FilterStrength {
uint8_t filter_level;
uint8_t inner_limit;
uint8_t inner_filter;
} VP8FilterStrength;
typedef struct VP8Macroblock {
uint8_t skip;
// TODO: make it possible to check for at least (i4x4 or split_mv)
// in one op. are others needed?
uint8_t mode;
uint8_t ref_frame;
uint8_t partitioning;
uint8_t chroma_pred_mode;
uint8_t segment;
uint8_t intra4x4_pred_mode_mb[16];
DECLARE_ALIGNED(4, uint8_t, intra4x4_pred_mode_top)[4];
VP56mv mv;
VP56mv bmv[16];
} VP8Macroblock;
typedef struct VP8ThreadData {
DECLARE_ALIGNED(16, int16_t, block)[6][4][16];
DECLARE_ALIGNED(16, int16_t, block_dc)[16];
/**
* This is the index plus one of the last non-zero coeff
* for each of the blocks in the current macroblock.
* So, 0 -> no coeffs
* 1 -> dc-only (special transform)
* 2+-> full transform
*/
DECLARE_ALIGNED(16, uint8_t, non_zero_count_cache)[6][4];
/**
* For coeff decode, we need to know whether the above block had non-zero
* coefficients. This means for each macroblock, we need data for 4 luma
* blocks, 2 u blocks, 2 v blocks, and the luma dc block, for a total of 9
* per macroblock. We keep the last row in top_nnz.
*/
DECLARE_ALIGNED(8, uint8_t, left_nnz)[9];
int thread_nr;
#if HAVE_THREADS
pthread_mutex_t lock;
pthread_cond_t cond;
#endif
int thread_mb_pos; // (mb_y << 16) | (mb_x & 0xFFFF)
int wait_mb_pos; // What the current thread is waiting on.
#define EDGE_EMU_LINESIZE 32
DECLARE_ALIGNED(16, uint8_t, edge_emu_buffer)[21 * EDGE_EMU_LINESIZE];
VP8FilterStrength *filter_strength;
} VP8ThreadData;
typedef struct VP8Frame {
ThreadFrame tf;
AVBufferRef *seg_map;
} VP8Frame;
typedef struct VP8intmv {
int x;
int y;
} VP8intmv;
#define MAX_THREADS 8
typedef struct VP8Context {
VP8ThreadData *thread_data;
AVCodecContext *avctx;
VP8Frame *framep[4];
VP8Frame *next_framep[4];
VP8Frame *curframe;
VP8Frame *prev_frame;
uint16_t mb_width; /* number of horizontal MB */
uint16_t mb_height; /* number of vertical MB */
int linesize;
int uvlinesize;
uint8_t keyframe;
uint8_t deblock_filter;
uint8_t mbskip_enabled;
uint8_t profile;
VP8intmv mv_min;
VP8intmv mv_max;
int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type
int ref_count[3];
/**
* Base parameters for segmentation, i.e. per-macroblock parameters.
* These must be kept unchanged even if segmentation is not used for
* a frame, since the values persist between interframes.
*/
struct {
uint8_t enabled;
uint8_t absolute_vals;
uint8_t update_map;
int8_t base_quant[4];
int8_t filter_level[4]; ///< base loop filter level
} segmentation;
struct {
uint8_t simple;
uint8_t level;
uint8_t sharpness;
} filter;
VP8Macroblock *macroblocks;
uint8_t *intra4x4_pred_mode_top;
uint8_t intra4x4_pred_mode_left[4];
/**
* Macroblocks can have one of 4 different quants in a frame when
* segmentation is enabled.
* If segmentation is disabled, only the first segment's values are used.
*/
struct {
// [0] - DC qmul [1] - AC qmul
int16_t luma_qmul[2];
int16_t luma_dc_qmul[2]; ///< luma dc-only block quant
int16_t chroma_qmul[2];
} qmat[4];
struct {
uint8_t enabled; ///< whether each mb can have a different strength based on mode/ref
/**
* filter strength adjustment for the following macroblock modes:
* [0-3] - i16x16 (always zero)
* [4] - i4x4
* [5] - zero mv
* [6] - inter modes except for zero or split mv
* [7] - split mv
* i16x16 modes never have any adjustment
*/
int8_t mode[VP8_MVMODE_SPLIT + 1];
/**
* filter strength adjustment for macroblocks that reference:
* [0] - intra / VP56_FRAME_CURRENT
* [1] - VP56_FRAME_PREVIOUS
* [2] - VP56_FRAME_GOLDEN
* [3] - altref / VP56_FRAME_GOLDEN2
*/
int8_t ref[4];
} lf_delta;
uint8_t (*top_border)[16 + 8 + 8];
uint8_t (*top_nnz)[9];
VP56RangeCoder c; ///< header context, includes mb modes and motion vectors
/**
* These are all of the updatable probabilities for binary decisions.
* They are only implicitly reset on keyframes, making it quite likely
* for an interframe to desync if a prior frame's header was corrupt
* or missing outright!
*/
struct {
uint8_t segmentid[3];
uint8_t mbskip;
uint8_t intra;
uint8_t last;
uint8_t golden;
uint8_t pred16x16[4];
uint8_t pred8x8c[3];
uint8_t token[4][16][3][NUM_DCT_TOKENS - 1];
uint8_t mvc[2][19];
uint8_t scan[16];
} prob[2];
VP8Macroblock *macroblocks_base;
int invisible;
int update_last; ///< update VP56_FRAME_PREVIOUS with the current one
int update_golden; ///< VP56_FRAME_NONE if not updated, or which frame to copy if so
int update_altref;
/**
* If this flag is not set, all the probability updates
* are discarded after this frame is decoded.
*/
int update_probabilities;
/**
* All coefficients are contained in separate arith coding contexts.
* There can be 1, 2, 4, or 8 of these after the header context.
*/
int num_coeff_partitions;
VP56RangeCoder coeff_partition[8];
VideoDSPContext vdsp;
VP8DSPContext vp8dsp;
H264PredContext hpc;
vp8_mc_func put_pixels_tab[3][3][3];
VP8Frame frames[5];
uint8_t colorspace; ///< 0 is the only value allowed (meaning bt601)
uint8_t fullrange; ///< whether we can skip clamping in dsp functions
int num_jobs;
/**
* This describes the macroblock memory layout.
* 0 -> Only width+height*2+1 macroblocks allocated (frame/single thread).
* 1 -> Macroblocks for entire frame allocated (sliced thread).
*/
int mb_layout;
void (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
int vp7;
/**
* Fade bit present in bitstream (VP7)
*/
int fade_present;
/**
* Interframe DC prediction (VP7)
* [0] VP56_FRAME_PREVIOUS
* [1] VP56_FRAME_GOLDEN
*/
uint16_t inter_dc_pred[2][2];
/**
* Macroblock features (VP7)
*/
uint8_t feature_enabled[4];
uint8_t feature_present_prob[4];
uint8_t feature_index_prob[4][3];
uint8_t feature_value[4][4];
} VP8Context;
int ff_vp8_decode_init(AVCodecContext *avctx);
int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
AVPacket *avpkt);
int ff_vp8_decode_free(AVCodecContext *avctx);
#endif /* AVCODEC_VP8_H */

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2008 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "parser.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;
*poutbuf = buf;
*poutbuf_size = buf_size;
return buf_size;
}
AVCodecParser ff_vp8_parser = {
.codec_ids = { AV_CODEC_ID_VP8 },
.parser_parse = parse,
};

View file

@ -0,0 +1,830 @@
/*
* Copyright (C) 2010 David Conrad
* Copyright (C) 2010 Ronald S. Bultje
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* VP8 compatible video decoder
*/
#ifndef AVCODEC_VP8DATA_H
#define AVCODEC_VP8DATA_H
#include "vp8.h"
#include "h264pred.h"
static const uint8_t vp7_pred4x4_mode[] = {
[DC_PRED8x8] = DC_PRED,
[VERT_PRED8x8] = TM_VP8_PRED,
[HOR_PRED8x8] = TM_VP8_PRED,
[PLANE_PRED8x8] = TM_VP8_PRED,
};
static const uint8_t vp8_pred4x4_mode[] = {
[DC_PRED8x8] = DC_PRED,
[VERT_PRED8x8] = VERT_PRED,
[HOR_PRED8x8] = HOR_PRED,
[PLANE_PRED8x8] = TM_VP8_PRED,
};
static const int8_t vp8_pred16x16_tree_intra[4][2] = {
{ -MODE_I4x4, 1 }, // '0'
{ 2, 3 },
{ -DC_PRED8x8, -VERT_PRED8x8 }, // '100', '101'
{ -HOR_PRED8x8, -PLANE_PRED8x8 }, // '110', '111'
};
static const int8_t vp8_pred16x16_tree_inter[4][2] = {
{ -DC_PRED8x8, 1 }, // '0'
{ 2, 3 },
{ -VERT_PRED8x8, -HOR_PRED8x8 }, // '100', '101'
{ -PLANE_PRED8x8, -MODE_I4x4 }, // '110', '111'
};
typedef struct VP7MVPred {
int8_t yoffset;
int8_t xoffset;
uint8_t subblock;
uint8_t score;
} VP7MVPred;
#define VP7_MV_PRED_COUNT 12
static const VP7MVPred vp7_mv_pred[VP7_MV_PRED_COUNT] = {
{ -1, 0, 12, 8 },
{ 0, -1, 3, 8 },
{ -1, -1, 15, 2 },
{ -1, 1, 12, 2 },
{ -2, 0, 12, 2 },
{ 0, -2, 3, 2 },
{ -1, -2, 15, 1 },
{ -2, -1, 15, 1 },
{ -2, 1, 12, 1 },
{ -1, 2, 12, 1 },
{ -2, -2, 15, 1 },
{ -2, 2, 12, 1 },
};
static const int vp7_mode_contexts[31][4] = {
{ 3, 3, 1, 246 },
{ 7, 89, 66, 239 },
{ 10, 90, 78, 238 },
{ 14, 118, 95, 241 },
{ 14, 123, 106, 238 },
{ 20, 140, 109, 240 },
{ 13, 155, 103, 238 },
{ 21, 158, 99, 240 },
{ 27, 82, 108, 232 },
{ 19, 99, 123, 217 },
{ 45, 139, 148, 236 },
{ 50, 117, 144, 235 },
{ 57, 128, 164, 238 },
{ 69, 139, 171, 239 },
{ 74, 154, 179, 238 },
{ 112, 165, 186, 242 },
{ 98, 143, 185, 245 },
{ 105, 153, 190, 250 },
{ 124, 167, 192, 245 },
{ 131, 186, 203, 246 },
{ 59, 184, 222, 224 },
{ 148, 215, 214, 213 },
{ 137, 211, 210, 219 },
{ 190, 227, 128, 228 },
{ 183, 228, 128, 228 },
{ 194, 234, 128, 228 },
{ 202, 236, 128, 228 },
{ 205, 240, 128, 228 },
{ 205, 244, 128, 228 },
{ 225, 246, 128, 228 },
{ 233, 251, 128, 228 },
};
static const int vp8_mode_contexts[6][4] = {
{ 7, 1, 1, 143 },
{ 14, 18, 14, 107 },
{ 135, 64, 57, 68 },
{ 60, 56, 128, 65 },
{ 159, 134, 128, 34 },
{ 234, 188, 128, 28 },
};
static const uint8_t vp8_mbsplits[5][16] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 },
{ 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
static const uint8_t vp8_mbfirstidx[4][16] = {
{ 0, 8 },
{ 0, 2 },
{ 0, 2, 8, 10 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
};
static const uint8_t vp8_mbsplit_count[4] = {
2, 2, 4, 16
};
static const uint8_t vp8_mbsplit_prob[3] = {
110, 111, 150
};
static const uint8_t vp7_submv_prob[3] = {
180, 162, 25
};
static const uint8_t vp8_submv_prob[5][3] = {
{ 147, 136, 18 },
{ 106, 145, 1 },
{ 179, 121, 1 },
{ 223, 1, 34 },
{ 208, 1, 1 }
};
static const uint8_t vp8_pred16x16_prob_intra[4] = {
145, 156, 163, 128
};
static const uint8_t vp8_pred16x16_prob_inter[4] = {
112, 86, 140, 37
};
static const int8_t vp8_pred4x4_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 }, // '111010', '111011'
{ -DIAG_DOWN_LEFT_PRED, 7 }, // '11110'
{ -VERT_LEFT_PRED, 8 }, // '111110'
{ -HOR_DOWN_PRED, -HOR_UP_PRED }, // '1111110', '1111111'
};
static const int8_t vp8_pred8x8c_tree[3][2] = {
{ -DC_PRED8x8, 1 }, // '0'
{ -VERT_PRED8x8, 2 }, // '10
{ -HOR_PRED8x8, -PLANE_PRED8x8 }, // '110', '111'
};
static const uint8_t vp8_pred8x8c_prob_intra[3] = {
142, 114, 183
};
static const uint8_t vp8_pred8x8c_prob_inter[3] = {
162, 101, 204
};
static const uint8_t vp8_pred4x4_prob_inter[9] = {
120, 90, 79, 133, 87, 85, 80, 111, 151
};
static const uint8_t vp8_pred4x4_prob_intra[10][10][9] = {
{
{ 39, 53, 200, 87, 26, 21, 43, 232, 171 },
{ 56, 34, 51, 104, 114, 102, 29, 93, 77 },
{ 88, 88, 147, 150, 42, 46, 45, 196, 205 },
{ 107, 54, 32, 26, 51, 1, 81, 43, 31 },
{ 39, 28, 85, 171, 58, 165, 90, 98, 64 },
{ 34, 22, 116, 206, 23, 34, 43, 166, 73 },
{ 34, 19, 21, 102, 132, 188, 16, 76, 124 },
{ 68, 25, 106, 22, 64, 171, 36, 225, 114 },
{ 62, 18, 78, 95, 85, 57, 50, 48, 51 },
{ 43, 97, 183, 117, 85, 38, 35, 179, 61 },
},
{
{ 112, 113, 77, 85, 179, 255, 38, 120, 114 },
{ 40, 42, 1, 196, 245, 209, 10, 25, 109 },
{ 193, 101, 35, 159, 215, 111, 89, 46, 111 },
{ 100, 80, 8, 43, 154, 1, 51, 26, 71 },
{ 88, 43, 29, 140, 166, 213, 37, 43, 154 },
{ 61, 63, 30, 155, 67, 45, 68, 1, 209 },
{ 41, 40, 5, 102, 211, 183, 4, 1, 221 },
{ 142, 78, 78, 16, 255, 128, 34, 197, 171 },
{ 51, 50, 17, 168, 209, 192, 23, 25, 82 },
{ 60, 148, 31, 172, 219, 228, 21, 18, 111 },
},
{
{ 175, 69, 143, 80, 85, 82, 72, 155, 103 },
{ 56, 58, 10, 171, 218, 189, 17, 13, 152 },
{ 231, 120, 48, 89, 115, 113, 120, 152, 112 },
{ 144, 71, 10, 38, 171, 213, 144, 34, 26 },
{ 114, 26, 17, 163, 44, 195, 21, 10, 173 },
{ 121, 24, 80, 195, 26, 62, 44, 64, 85 },
{ 63, 20, 8, 114, 114, 208, 12, 9, 226 },
{ 170, 46, 55, 19, 136, 160, 33, 206, 71 },
{ 81, 40, 11, 96, 182, 84, 29, 16, 36 },
{ 152, 179, 64, 126, 170, 118, 46, 70, 95 },
},
{
{ 75, 79, 123, 47, 51, 128, 81, 171, 1 },
{ 57, 17, 5, 71, 102, 57, 53, 41, 49 },
{ 125, 98, 42, 88, 104, 85, 117, 175, 82 },
{ 115, 21, 2, 10, 102, 255, 166, 23, 6 },
{ 38, 33, 13, 121, 57, 73, 26, 1, 85 },
{ 41, 10, 67, 138, 77, 110, 90, 47, 114 },
{ 57, 18, 10, 102, 102, 213, 34, 20, 43 },
{ 101, 29, 16, 10, 85, 128, 101, 196, 26 },
{ 117, 20, 15, 36, 163, 128, 68, 1, 26 },
{ 95, 84, 53, 89, 128, 100, 113, 101, 45 },
},
{
{ 63, 59, 90, 180, 59, 166, 93, 73, 154 },
{ 40, 40, 21, 116, 143, 209, 34, 39, 175 },
{ 138, 31, 36, 171, 27, 166, 38, 44, 229 },
{ 57, 46, 22, 24, 128, 1, 54, 17, 37 },
{ 47, 15, 16, 183, 34, 223, 49, 45, 183 },
{ 46, 17, 33, 183, 6, 98, 15, 32, 183 },
{ 40, 3, 9, 115, 51, 192, 18, 6, 223 },
{ 65, 32, 73, 115, 28, 128, 23, 128, 205 },
{ 87, 37, 9, 115, 59, 77, 64, 21, 47 },
{ 67, 87, 58, 169, 82, 115, 26, 59, 179 },
},
{
{ 54, 57, 112, 184, 5, 41, 38, 166, 213 },
{ 30, 34, 26, 133, 152, 116, 10, 32, 134 },
{ 104, 55, 44, 218, 9, 54, 53, 130, 226 },
{ 75, 32, 12, 51, 192, 255, 160, 43, 51 },
{ 39, 19, 53, 221, 26, 114, 32, 73, 255 },
{ 31, 9, 65, 234, 2, 15, 1, 118, 73 },
{ 56, 21, 23, 111, 59, 205, 45, 37, 192 },
{ 88, 31, 35, 67, 102, 85, 55, 186, 85 },
{ 55, 38, 70, 124, 73, 102, 1, 34, 98 },
{ 64, 90, 70, 205, 40, 41, 23, 26, 57 },
},
{
{ 86, 40, 64, 135, 148, 224, 45, 183, 128 },
{ 22, 26, 17, 131, 240, 154, 14, 1, 209 },
{ 164, 50, 31, 137, 154, 133, 25, 35, 218 },
{ 83, 12, 13, 54, 192, 255, 68, 47, 28 },
{ 45, 16, 21, 91, 64, 222, 7, 1, 197 },
{ 56, 21, 39, 155, 60, 138, 23, 102, 213 },
{ 18, 11, 7, 63, 144, 171, 4, 4, 246 },
{ 85, 26, 85, 85, 128, 128, 32, 146, 171 },
{ 35, 27, 10, 146, 174, 171, 12, 26, 128 },
{ 51, 103, 44, 131, 131, 123, 31, 6, 158 },
},
{
{ 68, 45, 128, 34, 1, 47, 11, 245, 171 },
{ 62, 17, 19, 70, 146, 85, 55, 62, 70 },
{ 102, 61, 71, 37, 34, 53, 31, 243, 192 },
{ 75, 15, 9, 9, 64, 255, 184, 119, 16 },
{ 37, 43, 37, 154, 100, 163, 85, 160, 1 },
{ 63, 9, 92, 136, 28, 64, 32, 201, 85 },
{ 56, 8, 17, 132, 137, 255, 55, 116, 128 },
{ 86, 6, 28, 5, 64, 255, 25, 248, 1 },
{ 58, 15, 20, 82, 135, 57, 26, 121, 40 },
{ 69, 60, 71, 38, 73, 119, 28, 222, 37 },
},
{
{ 101, 75, 128, 139, 118, 146, 116, 128, 85 },
{ 56, 41, 15, 176, 236, 85, 37, 9, 62 },
{ 190, 80, 35, 99, 180, 80, 126, 54, 45 },
{ 146, 36, 19, 30, 171, 255, 97, 27, 20 },
{ 71, 30, 17, 119, 118, 255, 17, 18, 138 },
{ 101, 38, 60, 138, 55, 70, 43, 26, 142 },
{ 32, 41, 20, 117, 151, 142, 20, 21, 163 },
{ 138, 45, 61, 62, 219, 1, 81, 188, 64 },
{ 112, 19, 12, 61, 195, 128, 48, 4, 24 },
{ 85, 126, 47, 87, 176, 51, 41, 20, 32 },
},
{
{ 66, 102, 167, 99, 74, 62, 40, 234, 128 },
{ 41, 53, 9, 178, 241, 141, 26, 8, 107 },
{ 134, 183, 89, 137, 98, 101, 106, 165, 148 },
{ 104, 79, 12, 27, 217, 255, 87, 17, 7 },
{ 74, 43, 26, 146, 73, 166, 49, 23, 157 },
{ 65, 38, 105, 160, 51, 52, 31, 115, 128 },
{ 47, 41, 14, 110, 182, 183, 21, 17, 194 },
{ 87, 68, 71, 44, 114, 51, 15, 186, 23 },
{ 66, 45, 25, 102, 197, 189, 23, 18, 22 },
{ 72, 187, 100, 130, 157, 111, 32, 75, 80 },
},
};
static const int8_t vp8_segmentid_tree[][2] = {
{ 1, 2 },
{ -0, -1 }, // '00', '01'
{ -2, -3 }, // '10', '11'
};
static const uint8_t vp8_coeff_band[16] = {
0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7
};
/* Inverse of vp8_coeff_band: mappings of bands to coefficient indexes.
* Each list is -1-terminated. */
static const int8_t vp8_coeff_band_indexes[8][10] = {
{ 0, -1 },
{ 1, -1 },
{ 2, -1 },
{ 3, -1 },
{ 5, -1 },
{ 6, -1 },
{ 4, 7, 8, 9, 10, 11, 12, 13, 14, -1 },
{ 15, -1 }
};
static const uint8_t vp8_dct_cat1_prob[] = {
159, 0
};
static const uint8_t vp8_dct_cat2_prob[] = {
165, 145, 0
};
static const uint8_t vp8_dct_cat3_prob[] = {
173, 148, 140, 0
};
static const uint8_t vp8_dct_cat4_prob[] = {
176, 155, 140, 135, 0
};
static const uint8_t vp8_dct_cat5_prob[] = {
180, 157, 141, 134, 130, 0
};
static const uint8_t vp8_dct_cat6_prob[] = {
254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0
};
// only used for cat3 and above; cat 1 and 2 are referenced directly
const uint8_t *const ff_vp8_dct_cat_prob[] = {
vp8_dct_cat3_prob,
vp8_dct_cat4_prob,
vp8_dct_cat5_prob,
vp8_dct_cat6_prob,
};
static const uint8_t vp8_token_default_probs[4][8][3][NUM_DCT_TOKENS - 1] = {
{
{
{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
},
{
{ 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 },
{ 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 },
{ 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 },
},
{
{ 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 },
{ 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 },
{ 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 },
},
{
{ 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 },
{ 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 },
{ 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 },
},
{
{ 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 },
{ 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 },
{ 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 },
},
{
{ 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 },
{ 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 },
{ 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 },
},
{
{ 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 },
{ 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 },
{ 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 },
},
{
{ 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
},
},
{
{
{ 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 },
{ 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 },
{ 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 },
},
{
{ 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 },
{ 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 },
{ 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 },
},
{
{ 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 },
{ 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 },
{ 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 },
},
{
{ 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 },
{ 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 },
{ 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 },
},
{
{ 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 },
{ 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 },
{ 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 },
},
{
{ 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 },
{ 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 },
{ 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 },
},
{
{ 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 },
{ 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 },
{ 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 },
},
{
{ 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 },
{ 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
{ 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 },
},
},
{
{
{ 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 },
{ 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 },
{ 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 },
},
{
{ 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 },
{ 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 },
{ 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 },
},
{
{ 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 },
{ 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 },
{ 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 },
},
{
{ 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 },
{ 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 },
{ 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
},
{
{ 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
{ 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 },
{ 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
},
{
{ 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
},
{
{ 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 },
{ 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 },
{ 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
},
{
{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
},
},
{
{
{ 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 },
{ 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 },
{ 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 },
},
{
{ 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 },
{ 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 },
{ 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 },
},
{
{ 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 },
{ 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 },
{ 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 },
},
{
{ 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 },
{ 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 },
{ 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 },
},
{
{ 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 },
{ 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 },
{ 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 },
},
{
{ 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 },
{ 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 },
{ 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 },
},
{
{ 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 },
{ 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 },
{ 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 },
},
{
{ 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
},
},
};
static const uint8_t vp8_token_update_probs[4][8][3][NUM_DCT_TOKENS - 1] = {
{
{
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 },
{ 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 },
{ 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
},
{
{
{ 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 },
{ 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 },
},
{
{ 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
},
{
{
{ 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 },
{ 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 },
},
{
{ 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
},
{
{
{ 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 },
{ 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
},
};
static const uint8_t vp8_dc_qlookup[VP8_MAX_QUANT + 1] = {
4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17,
18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 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, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
91, 93, 95, 96, 98, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118,
122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157,
};
static const uint16_t vp8_ac_qlookup[VP8_MAX_QUANT + 1] = {
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108,
110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152,
155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209,
213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284,
};
static const uint8_t vp8_mv_update_prob[2][19] = {
{ 237,
246,
253, 253, 254, 254, 254, 254, 254,
254, 254, 254, 254, 254, 250, 250, 252, /* VP8 only: */ 254, 254 },
{ 231,
243,
245, 253, 254, 254, 254, 254, 254,
254, 254, 254, 254, 254, 251, 251, 254, /* VP8 only: */ 254, 254 }
};
static const uint8_t vp7_mv_default_prob[2][17] = {
{ 162,
128,
225, 146, 172, 147, 214, 39, 156,
247, 210, 135, 68, 138, 220, 239, 246 },
{ 164,
128,
204, 170, 119, 235, 140, 230, 228,
244, 184, 201, 44, 173, 221, 239, 253 }
};
static const uint8_t vp8_mv_default_prob[2][19] = {
{ 162,
128,
225, 146, 172, 147, 214, 39, 156,
128, 129, 132, 75, 145, 178, 206, 239, 254, 254 },
{ 164,
128,
204, 170, 119, 235, 140, 230, 228,
128, 130, 130, 74, 148, 180, 203, 236, 254, 254 }
};
static const uint8_t vp7_feature_value_size[2][4] = {
{ 7, 6, 0, 8 },
{ 7, 6, 0, 5 },
};
static const int8_t vp7_feature_index_tree[4][2] =
{
{ 1, 2 },
{ -0, -1 }, // '00', '01'
{ -2, -3 }, // '10', '11'
};
static const uint16_t vp7_ydc_qlookup[] = {
4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 39, 39, 40, 41,
41, 42, 43, 43, 44, 45, 45, 46, 47, 48, 48, 49, 50, 51, 52,
53, 53, 54, 56, 57, 58, 59, 60, 62, 63, 65, 66, 68, 70, 72,
74, 76, 79, 81, 84, 87, 90, 93, 96, 100, 104, 108, 112, 116, 121,
126, 131, 136, 142, 148, 154, 160, 167, 174, 182, 189, 198, 206, 215, 224,
234, 244, 254, 265, 277, 288, 301, 313, 327, 340, 355, 370, 385, 401, 417,
434, 452, 470, 489, 509, 529, 550, 572,
};
static const uint16_t vp7_yac_qlookup[] = {
4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15,
16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35,
37, 38, 40, 41, 42, 44, 45, 46, 48, 49, 50, 51, 53, 54,
55, 56, 57, 58, 59, 61, 62, 63, 64, 65, 67, 68, 69, 70,
72, 73, 75, 76, 78, 80, 82, 84, 86, 88, 91, 93, 96, 99,
102, 105, 109, 112, 116, 121, 125, 130, 135, 140, 146, 152, 158, 165,
172, 180, 188, 196, 205, 214, 224, 234, 245, 256, 268, 281, 294, 308,
322, 337, 353, 369, 386, 404, 423, 443, 463, 484, 506, 529, 553, 578,
604, 631, 659, 688, 718, 749, 781, 814, 849, 885, 922, 960, 1000, 1041,
1083, 1127,
};
static const uint16_t vp7_y2dc_qlookup[] = {
7, 9, 11, 13, 15, 17, 19, 21, 23, 26, 28, 30, 33, 35,
37, 39, 42, 44, 46, 48, 51, 53, 55, 57, 59, 61, 63, 65,
67, 69, 70, 72, 74, 75, 77, 78, 80, 81, 83, 84, 85, 87,
88, 89, 90, 92, 93, 94, 95, 96, 97, 99, 100, 101, 102, 104,
105, 106, 108, 109, 111, 113, 114, 116, 118, 120, 123, 125, 128, 131,
134, 137, 140, 144, 148, 152, 156, 161, 166, 171, 176, 182, 188, 195,
202, 209, 217, 225, 234, 243, 253, 263, 274, 285, 297, 309, 322, 336,
350, 365, 381, 397, 414, 432, 450, 470, 490, 511, 533, 556, 579, 604,
630, 656, 684, 713, 742, 773, 805, 838, 873, 908, 945, 983, 1022, 1063,
1105, 1148,
};
static const uint16_t vp7_y2ac_qlookup[] = {
7, 9, 11, 13, 16, 18, 21, 24, 26, 29, 32, 35,
38, 41, 43, 46, 49, 52, 55, 58, 61, 64, 66, 69,
72, 74, 77, 79, 82, 84, 86, 88, 91, 93, 95, 97,
98, 100, 102, 104, 105, 107, 109, 110, 112, 113, 115, 116,
117, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 136,
138, 141, 143, 146, 149, 152, 155, 158, 162, 166, 171, 175,
180, 185, 191, 197, 204, 210, 218, 226, 234, 243, 252, 262,
273, 284, 295, 308, 321, 335, 350, 365, 381, 398, 416, 435,
455, 476, 497, 520, 544, 569, 595, 622, 650, 680, 711, 743,
776, 811, 848, 885, 925, 965, 1008, 1052, 1097, 1144, 1193, 1244,
1297, 1351, 1407, 1466, 1526, 1588, 1652, 1719,
};
#endif /* AVCODEC_VP8DATA_H */

View file

@ -0,0 +1,741 @@
/*
* Copyright (C) 2010 David Conrad
* Copyright (C) 2010 Ronald S. Bultje
* Copyright (C) 2014 Peter Ross
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* VP8 compatible video decoder
*/
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "mathops.h"
#include "vp8dsp.h"
#define MK_IDCT_DC_ADD4_C(name) \
static void name ## _idct_dc_add4uv_c(uint8_t *dst, int16_t block[4][16], \
ptrdiff_t stride) \
{ \
name ## _idct_dc_add_c(dst + stride * 0 + 0, block[0], stride); \
name ## _idct_dc_add_c(dst + stride * 0 + 4, block[1], stride); \
name ## _idct_dc_add_c(dst + stride * 4 + 0, block[2], stride); \
name ## _idct_dc_add_c(dst + stride * 4 + 4, block[3], stride); \
} \
\
static void name ## _idct_dc_add4y_c(uint8_t *dst, int16_t block[4][16], \
ptrdiff_t stride) \
{ \
name ## _idct_dc_add_c(dst + 0, block[0], stride); \
name ## _idct_dc_add_c(dst + 4, block[1], stride); \
name ## _idct_dc_add_c(dst + 8, block[2], stride); \
name ## _idct_dc_add_c(dst + 12, block[3], stride); \
}
#if CONFIG_VP7_DECODER
static void vp7_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16])
{
int i, a1, b1, c1, d1;
int16_t tmp[16];
for (i = 0; i < 4; i++) {
a1 = (dc[i * 4 + 0] + dc[i * 4 + 2]) * 23170;
b1 = (dc[i * 4 + 0] - dc[i * 4 + 2]) * 23170;
c1 = dc[i * 4 + 1] * 12540 - dc[i * 4 + 3] * 30274;
d1 = dc[i * 4 + 1] * 30274 + dc[i * 4 + 3] * 12540;
tmp[i * 4 + 0] = (a1 + d1) >> 14;
tmp[i * 4 + 3] = (a1 - d1) >> 14;
tmp[i * 4 + 1] = (b1 + c1) >> 14;
tmp[i * 4 + 2] = (b1 - c1) >> 14;
}
for (i = 0; i < 4; i++) {
a1 = (tmp[i + 0] + tmp[i + 8]) * 23170;
b1 = (tmp[i + 0] - tmp[i + 8]) * 23170;
c1 = tmp[i + 4] * 12540 - tmp[i + 12] * 30274;
d1 = tmp[i + 4] * 30274 + tmp[i + 12] * 12540;
AV_ZERO64(dc + i * 4);
block[0][i][0] = (a1 + d1 + 0x20000) >> 18;
block[3][i][0] = (a1 - d1 + 0x20000) >> 18;
block[1][i][0] = (b1 + c1 + 0x20000) >> 18;
block[2][i][0] = (b1 - c1 + 0x20000) >> 18;
}
}
static void vp7_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16])
{
int i, val = (23170 * (23170 * dc[0] >> 14) + 0x20000) >> 18;
dc[0] = 0;
for (i = 0; i < 4; i++) {
block[i][0][0] = val;
block[i][1][0] = val;
block[i][2][0] = val;
block[i][3][0] = val;
}
}
static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
{
int i, a1, b1, c1, d1;
int16_t tmp[16];
for (i = 0; i < 4; i++) {
a1 = (block[i * 4 + 0] + block[i * 4 + 2]) * 23170;
b1 = (block[i * 4 + 0] - block[i * 4 + 2]) * 23170;
c1 = block[i * 4 + 1] * 12540 - block[i * 4 + 3] * 30274;
d1 = block[i * 4 + 1] * 30274 + block[i * 4 + 3] * 12540;
AV_ZERO64(block + i * 4);
tmp[i * 4 + 0] = (a1 + d1) >> 14;
tmp[i * 4 + 3] = (a1 - d1) >> 14;
tmp[i * 4 + 1] = (b1 + c1) >> 14;
tmp[i * 4 + 2] = (b1 - c1) >> 14;
}
for (i = 0; i < 4; i++) {
a1 = (tmp[i + 0] + tmp[i + 8]) * 23170;
b1 = (tmp[i + 0] - tmp[i + 8]) * 23170;
c1 = tmp[i + 4] * 12540 - tmp[i + 12] * 30274;
d1 = tmp[i + 4] * 30274 + tmp[i + 12] * 12540;
dst[0 * stride + i] = av_clip_uint8(dst[0 * stride + i] +
((a1 + d1 + 0x20000) >> 18));
dst[3 * stride + i] = av_clip_uint8(dst[3 * stride + i] +
((a1 - d1 + 0x20000) >> 18));
dst[1 * stride + i] = av_clip_uint8(dst[1 * stride + i] +
((b1 + c1 + 0x20000) >> 18));
dst[2 * stride + i] = av_clip_uint8(dst[2 * stride + i] +
((b1 - c1 + 0x20000) >> 18));
}
}
static void vp7_idct_dc_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
{
int i, dc = (23170 * (23170 * block[0] >> 14) + 0x20000) >> 18;
block[0] = 0;
for (i = 0; i < 4; i++) {
dst[0] = av_clip_uint8(dst[0] + dc);
dst[1] = av_clip_uint8(dst[1] + dc);
dst[2] = av_clip_uint8(dst[2] + dc);
dst[3] = av_clip_uint8(dst[3] + dc);
dst += stride;
}
}
MK_IDCT_DC_ADD4_C(vp7)
#endif /* CONFIG_VP7_DECODER */
// TODO: Maybe add dequant
#if CONFIG_VP8_DECODER
static void vp8_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16])
{
int i, t0, t1, t2, t3;
for (i = 0; i < 4; i++) {
t0 = dc[0 * 4 + i] + dc[3 * 4 + i];
t1 = dc[1 * 4 + i] + dc[2 * 4 + i];
t2 = dc[1 * 4 + i] - dc[2 * 4 + i];
t3 = dc[0 * 4 + i] - dc[3 * 4 + i];
dc[0 * 4 + i] = t0 + t1;
dc[1 * 4 + i] = t3 + t2;
dc[2 * 4 + i] = t0 - t1;
dc[3 * 4 + i] = t3 - t2;
}
for (i = 0; i < 4; i++) {
t0 = dc[i * 4 + 0] + dc[i * 4 + 3] + 3; // rounding
t1 = dc[i * 4 + 1] + dc[i * 4 + 2];
t2 = dc[i * 4 + 1] - dc[i * 4 + 2];
t3 = dc[i * 4 + 0] - dc[i * 4 + 3] + 3; // rounding
AV_ZERO64(dc + i * 4);
block[i][0][0] = (t0 + t1) >> 3;
block[i][1][0] = (t3 + t2) >> 3;
block[i][2][0] = (t0 - t1) >> 3;
block[i][3][0] = (t3 - t2) >> 3;
}
}
static void vp8_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16])
{
int i, val = (dc[0] + 3) >> 3;
dc[0] = 0;
for (i = 0; i < 4; i++) {
block[i][0][0] = val;
block[i][1][0] = val;
block[i][2][0] = val;
block[i][3][0] = val;
}
}
#define MUL_20091(a) ((((a) * 20091) >> 16) + (a))
#define MUL_35468(a) (((a) * 35468) >> 16)
static void vp8_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
{
int i, t0, t1, t2, t3;
int16_t tmp[16];
for (i = 0; i < 4; i++) {
t0 = block[0 * 4 + i] + block[2 * 4 + i];
t1 = block[0 * 4 + i] - block[2 * 4 + i];
t2 = MUL_35468(block[1 * 4 + i]) - MUL_20091(block[3 * 4 + i]);
t3 = MUL_20091(block[1 * 4 + i]) + MUL_35468(block[3 * 4 + i]);
block[0 * 4 + i] = 0;
block[1 * 4 + i] = 0;
block[2 * 4 + i] = 0;
block[3 * 4 + i] = 0;
tmp[i * 4 + 0] = t0 + t3;
tmp[i * 4 + 1] = t1 + t2;
tmp[i * 4 + 2] = t1 - t2;
tmp[i * 4 + 3] = t0 - t3;
}
for (i = 0; i < 4; i++) {
t0 = tmp[0 * 4 + i] + tmp[2 * 4 + i];
t1 = tmp[0 * 4 + i] - tmp[2 * 4 + i];
t2 = MUL_35468(tmp[1 * 4 + i]) - MUL_20091(tmp[3 * 4 + i]);
t3 = MUL_20091(tmp[1 * 4 + i]) + MUL_35468(tmp[3 * 4 + i]);
dst[0] = av_clip_uint8(dst[0] + ((t0 + t3 + 4) >> 3));
dst[1] = av_clip_uint8(dst[1] + ((t1 + t2 + 4) >> 3));
dst[2] = av_clip_uint8(dst[2] + ((t1 - t2 + 4) >> 3));
dst[3] = av_clip_uint8(dst[3] + ((t0 - t3 + 4) >> 3));
dst += stride;
}
}
static void vp8_idct_dc_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
{
int i, dc = (block[0] + 4) >> 3;
block[0] = 0;
for (i = 0; i < 4; i++) {
dst[0] = av_clip_uint8(dst[0] + dc);
dst[1] = av_clip_uint8(dst[1] + dc);
dst[2] = av_clip_uint8(dst[2] + dc);
dst[3] = av_clip_uint8(dst[3] + dc);
dst += stride;
}
}
MK_IDCT_DC_ADD4_C(vp8)
#endif /* CONFIG_VP8_DECODER */
// because I like only having two parameters to pass functions...
#define LOAD_PIXELS \
int av_unused p3 = p[-4 * stride]; \
int av_unused p2 = p[-3 * stride]; \
int av_unused p1 = p[-2 * stride]; \
int av_unused p0 = p[-1 * stride]; \
int av_unused q0 = p[ 0 * stride]; \
int av_unused q1 = p[ 1 * stride]; \
int av_unused q2 = p[ 2 * stride]; \
int av_unused q3 = p[ 3 * stride];
#define clip_int8(n) (cm[(n) + 0x80] - 0x80)
static av_always_inline void filter_common(uint8_t *p, ptrdiff_t stride,
int is4tap, int is_vp7)
{
LOAD_PIXELS
int a, f1, f2;
const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
a = 3 * (q0 - p0);
if (is4tap)
a += clip_int8(p1 - q1);
a = clip_int8(a);
// We deviate from the spec here with c(a+3) >> 3
// since that's what libvpx does.
f1 = FFMIN(a + 4, 127) >> 3;
if (is_vp7)
f2 = f1 - ((a & 7) == 4);
else
f2 = FFMIN(a + 3, 127) >> 3;
// Despite what the spec says, we do need to clamp here to
// be bitexact with libvpx.
p[-1 * stride] = cm[p0 + f2];
p[ 0 * stride] = cm[q0 - f1];
// only used for _inner on blocks without high edge variance
if (!is4tap) {
a = (f1 + 1) >> 1;
p[-2 * stride] = cm[p1 + a];
p[ 1 * stride] = cm[q1 - a];
}
}
static av_always_inline void vp7_filter_common(uint8_t *p, ptrdiff_t stride,
int is4tap)
{
filter_common(p, stride, is4tap, IS_VP7);
}
static av_always_inline void vp8_filter_common(uint8_t *p, ptrdiff_t stride,
int is4tap)
{
filter_common(p, stride, is4tap, IS_VP8);
}
static av_always_inline int vp7_simple_limit(uint8_t *p, ptrdiff_t stride,
int flim)
{
LOAD_PIXELS
return FFABS(p0 - q0) <= flim;
}
static av_always_inline int vp8_simple_limit(uint8_t *p, ptrdiff_t stride,
int flim)
{
LOAD_PIXELS
return 2 * FFABS(p0 - q0) + (FFABS(p1 - q1) >> 1) <= flim;
}
/**
* E - limit at the macroblock edge
* I - limit for interior difference
*/
#define NORMAL_LIMIT(vpn) \
static av_always_inline int vp ## vpn ## _normal_limit(uint8_t *p, \
ptrdiff_t stride, \
int E, int I) \
{ \
LOAD_PIXELS \
return vp ## vpn ## _simple_limit(p, stride, E) && \
FFABS(p3 - p2) <= I && FFABS(p2 - p1) <= I && \
FFABS(p1 - p0) <= I && FFABS(q3 - q2) <= I && \
FFABS(q2 - q1) <= I && FFABS(q1 - q0) <= I; \
}
NORMAL_LIMIT(7)
NORMAL_LIMIT(8)
// high edge variance
static av_always_inline int hev(uint8_t *p, ptrdiff_t stride, int thresh)
{
LOAD_PIXELS
return FFABS(p1 - p0) > thresh || FFABS(q1 - q0) > thresh;
}
static av_always_inline void filter_mbedge(uint8_t *p, ptrdiff_t stride)
{
int a0, a1, a2, w;
const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
LOAD_PIXELS
w = clip_int8(p1 - q1);
w = clip_int8(w + 3 * (q0 - p0));
a0 = (27 * w + 63) >> 7;
a1 = (18 * w + 63) >> 7;
a2 = (9 * w + 63) >> 7;
p[-3 * stride] = cm[p2 + a2];
p[-2 * stride] = cm[p1 + a1];
p[-1 * stride] = cm[p0 + a0];
p[ 0 * stride] = cm[q0 - a0];
p[ 1 * stride] = cm[q1 - a1];
p[ 2 * stride] = cm[q2 - a2];
}
#define LOOP_FILTER(vpn, dir, size, stridea, strideb, maybe_inline) \
static maybe_inline \
void vpn ## _ ## dir ## _loop_filter ## size ## _c(uint8_t *dst, \
ptrdiff_t stride, \
int flim_E, int flim_I, \
int hev_thresh) \
{ \
int i; \
for (i = 0; i < size; i++) \
if (vpn ## _normal_limit(dst + i * stridea, strideb, \
flim_E, flim_I)) { \
if (hev(dst + i * stridea, strideb, hev_thresh)) \
vpn ## _filter_common(dst + i * stridea, strideb, 1); \
else \
filter_mbedge(dst + i * stridea, strideb); \
} \
} \
\
static maybe_inline \
void vpn ## _ ## dir ## _loop_filter ## size ## _inner_c(uint8_t *dst, \
ptrdiff_t stride, \
int flim_E, \
int flim_I, \
int hev_thresh) \
{ \
int i; \
for (i = 0; i < size; i++) \
if (vpn ## _normal_limit(dst + i * stridea, strideb, \
flim_E, flim_I)) { \
int hv = hev(dst + i * stridea, strideb, hev_thresh); \
if (hv) \
vpn ## _filter_common(dst + i * stridea, strideb, 1); \
else \
vpn ## _filter_common(dst + i * stridea, strideb, 0); \
} \
}
#define UV_LOOP_FILTER(vpn, dir, stridea, strideb) \
LOOP_FILTER(vpn, dir, 8, stridea, strideb, av_always_inline) \
static void vpn ## _ ## dir ## _loop_filter8uv_c(uint8_t *dstU, \
uint8_t *dstV, \
ptrdiff_t stride, int fE, \
int fI, int hev_thresh) \
{ \
vpn ## _ ## dir ## _loop_filter8_c(dstU, stride, fE, fI, hev_thresh); \
vpn ## _ ## dir ## _loop_filter8_c(dstV, stride, fE, fI, hev_thresh); \
} \
\
static void vpn ## _ ## dir ## _loop_filter8uv_inner_c(uint8_t *dstU, \
uint8_t *dstV, \
ptrdiff_t stride, \
int fE, int fI, \
int hev_thresh) \
{ \
vpn ## _ ## dir ## _loop_filter8_inner_c(dstU, stride, fE, fI, \
hev_thresh); \
vpn ## _ ## dir ## _loop_filter8_inner_c(dstV, stride, fE, fI, \
hev_thresh); \
}
#define LOOP_FILTER_SIMPLE(vpn) \
static void vpn ## _v_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, \
int flim) \
{ \
int i; \
for (i = 0; i < 16; i++) \
if (vpn ## _simple_limit(dst + i, stride, flim)) \
vpn ## _filter_common(dst + i, stride, 1); \
} \
\
static void vpn ## _h_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, \
int flim) \
{ \
int i; \
for (i = 0; i < 16; i++) \
if (vpn ## _simple_limit(dst + i * stride, 1, flim)) \
vpn ## _filter_common(dst + i * stride, 1, 1); \
}
#define LOOP_FILTERS(vpn) \
LOOP_FILTER(vpn, v, 16, 1, stride, ) \
LOOP_FILTER(vpn, h, 16, stride, 1, ) \
UV_LOOP_FILTER(vpn, v, 1, stride) \
UV_LOOP_FILTER(vpn, h, stride, 1) \
LOOP_FILTER_SIMPLE(vpn) \
static const uint8_t subpel_filters[7][6] = {
{ 0, 6, 123, 12, 1, 0 },
{ 2, 11, 108, 36, 8, 1 },
{ 0, 9, 93, 50, 6, 0 },
{ 3, 16, 77, 77, 16, 3 },
{ 0, 6, 50, 93, 9, 0 },
{ 1, 8, 36, 108, 11, 2 },
{ 0, 1, 12, 123, 6, 0 },
};
#define PUT_PIXELS(WIDTH) \
static void put_vp8_pixels ## WIDTH ## _c(uint8_t *dst, ptrdiff_t dststride, \
uint8_t *src, ptrdiff_t srcstride, \
int h, int x, int y) \
{ \
int i; \
for (i = 0; i < h; i++, dst += dststride, src += srcstride) \
memcpy(dst, src, WIDTH); \
}
PUT_PIXELS(16)
PUT_PIXELS(8)
PUT_PIXELS(4)
#define FILTER_6TAP(src, F, stride) \
cm[(F[2] * src[x + 0 * stride] - F[1] * src[x - 1 * stride] + \
F[0] * src[x - 2 * stride] + F[3] * src[x + 1 * stride] - \
F[4] * src[x + 2 * stride] + F[5] * src[x + 3 * stride] + 64) >> 7]
#define FILTER_4TAP(src, F, stride) \
cm[(F[2] * src[x + 0 * stride] - F[1] * src[x - 1 * stride] + \
F[3] * src[x + 1 * stride] - F[4] * src[x + 2 * stride] + 64) >> 7]
#define VP8_EPEL_H(SIZE, TAPS) \
static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, \
ptrdiff_t dststride, \
uint8_t *src, \
ptrdiff_t srcstride, \
int h, int mx, int my) \
{ \
const uint8_t *filter = subpel_filters[mx - 1]; \
const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
int x, y; \
for (y = 0; y < h; y++) { \
for (x = 0; x < SIZE; x++) \
dst[x] = FILTER_ ## TAPS ## TAP(src, filter, 1); \
dst += dststride; \
src += srcstride; \
} \
}
#define VP8_EPEL_V(SIZE, TAPS) \
static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, \
ptrdiff_t dststride, \
uint8_t *src, \
ptrdiff_t srcstride, \
int h, int mx, int my) \
{ \
const uint8_t *filter = subpel_filters[my - 1]; \
const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
int x, y; \
for (y = 0; y < h; y++) { \
for (x = 0; x < SIZE; x++) \
dst[x] = FILTER_ ## TAPS ## TAP(src, filter, srcstride); \
dst += dststride; \
src += srcstride; \
} \
}
#define VP8_EPEL_HV(SIZE, HTAPS, VTAPS) \
static void \
put_vp8_epel ## SIZE ## _h ## HTAPS ## v ## VTAPS ## _c(uint8_t *dst, \
ptrdiff_t dststride, \
uint8_t *src, \
ptrdiff_t srcstride, \
int h, int mx, \
int my) \
{ \
const uint8_t *filter = subpel_filters[mx - 1]; \
const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
int x, y; \
uint8_t tmp_array[(2 * SIZE + VTAPS - 1) * SIZE]; \
uint8_t *tmp = tmp_array; \
src -= (2 - (VTAPS == 4)) * srcstride; \
\
for (y = 0; y < h + VTAPS - 1; y++) { \
for (x = 0; x < SIZE; x++) \
tmp[x] = FILTER_ ## HTAPS ## TAP(src, filter, 1); \
tmp += SIZE; \
src += srcstride; \
} \
tmp = tmp_array + (2 - (VTAPS == 4)) * SIZE; \
filter = subpel_filters[my - 1]; \
\
for (y = 0; y < h; y++) { \
for (x = 0; x < SIZE; x++) \
dst[x] = FILTER_ ## VTAPS ## TAP(tmp, filter, SIZE); \
dst += dststride; \
tmp += SIZE; \
} \
}
VP8_EPEL_H(16, 4)
VP8_EPEL_H(8, 4)
VP8_EPEL_H(4, 4)
VP8_EPEL_H(16, 6)
VP8_EPEL_H(8, 6)
VP8_EPEL_H(4, 6)
VP8_EPEL_V(16, 4)
VP8_EPEL_V(8, 4)
VP8_EPEL_V(4, 4)
VP8_EPEL_V(16, 6)
VP8_EPEL_V(8, 6)
VP8_EPEL_V(4, 6)
VP8_EPEL_HV(16, 4, 4)
VP8_EPEL_HV(8, 4, 4)
VP8_EPEL_HV(4, 4, 4)
VP8_EPEL_HV(16, 4, 6)
VP8_EPEL_HV(8, 4, 6)
VP8_EPEL_HV(4, 4, 6)
VP8_EPEL_HV(16, 6, 4)
VP8_EPEL_HV(8, 6, 4)
VP8_EPEL_HV(4, 6, 4)
VP8_EPEL_HV(16, 6, 6)
VP8_EPEL_HV(8, 6, 6)
VP8_EPEL_HV(4, 6, 6)
#define VP8_BILINEAR(SIZE) \
static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, ptrdiff_t dstride, \
uint8_t *src, ptrdiff_t sstride, \
int h, int mx, int my) \
{ \
int a = 8 - mx, b = mx; \
int x, y; \
for (y = 0; y < h; y++) { \
for (x = 0; x < SIZE; x++) \
dst[x] = (a * src[x] + b * src[x + 1] + 4) >> 3; \
dst += dstride; \
src += sstride; \
} \
} \
\
static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, ptrdiff_t dstride, \
uint8_t *src, ptrdiff_t sstride, \
int h, int mx, int my) \
{ \
int c = 8 - my, d = my; \
int x, y; \
for (y = 0; y < h; y++) { \
for (x = 0; x < SIZE; x++) \
dst[x] = (c * src[x] + d * src[x + sstride] + 4) >> 3; \
dst += dstride; \
src += sstride; \
} \
} \
\
static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, \
ptrdiff_t dstride, \
uint8_t *src, \
ptrdiff_t sstride, \
int h, int mx, int my) \
{ \
int a = 8 - mx, b = mx; \
int c = 8 - my, d = my; \
int x, y; \
uint8_t tmp_array[(2 * SIZE + 1) * SIZE]; \
uint8_t *tmp = tmp_array; \
for (y = 0; y < h + 1; y++) { \
for (x = 0; x < SIZE; x++) \
tmp[x] = (a * src[x] + b * src[x + 1] + 4) >> 3; \
tmp += SIZE; \
src += sstride; \
} \
tmp = tmp_array; \
for (y = 0; y < h; y++) { \
for (x = 0; x < SIZE; x++) \
dst[x] = (c * tmp[x] + d * tmp[x + SIZE] + 4) >> 3; \
dst += dstride; \
tmp += SIZE; \
} \
}
VP8_BILINEAR(16)
VP8_BILINEAR(8)
VP8_BILINEAR(4)
#define VP78_MC_FUNC(IDX, SIZE) \
dsp->put_vp8_epel_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
dsp->put_vp8_epel_pixels_tab[IDX][0][1] = put_vp8_epel ## SIZE ## _h4_c; \
dsp->put_vp8_epel_pixels_tab[IDX][0][2] = put_vp8_epel ## SIZE ## _h6_c; \
dsp->put_vp8_epel_pixels_tab[IDX][1][0] = put_vp8_epel ## SIZE ## _v4_c; \
dsp->put_vp8_epel_pixels_tab[IDX][1][1] = put_vp8_epel ## SIZE ## _h4v4_c; \
dsp->put_vp8_epel_pixels_tab[IDX][1][2] = put_vp8_epel ## SIZE ## _h6v4_c; \
dsp->put_vp8_epel_pixels_tab[IDX][2][0] = put_vp8_epel ## SIZE ## _v6_c; \
dsp->put_vp8_epel_pixels_tab[IDX][2][1] = put_vp8_epel ## SIZE ## _h4v6_c; \
dsp->put_vp8_epel_pixels_tab[IDX][2][2] = put_vp8_epel ## SIZE ## _h6v6_c
#define VP78_BILINEAR_MC_FUNC(IDX, SIZE) \
dsp->put_vp8_bilinear_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
dsp->put_vp8_bilinear_pixels_tab[IDX][0][1] = put_vp8_bilinear ## SIZE ## _h_c; \
dsp->put_vp8_bilinear_pixels_tab[IDX][0][2] = put_vp8_bilinear ## SIZE ## _h_c; \
dsp->put_vp8_bilinear_pixels_tab[IDX][1][0] = put_vp8_bilinear ## SIZE ## _v_c; \
dsp->put_vp8_bilinear_pixels_tab[IDX][1][1] = put_vp8_bilinear ## SIZE ## _hv_c; \
dsp->put_vp8_bilinear_pixels_tab[IDX][1][2] = put_vp8_bilinear ## SIZE ## _hv_c; \
dsp->put_vp8_bilinear_pixels_tab[IDX][2][0] = put_vp8_bilinear ## SIZE ## _v_c; \
dsp->put_vp8_bilinear_pixels_tab[IDX][2][1] = put_vp8_bilinear ## SIZE ## _hv_c; \
dsp->put_vp8_bilinear_pixels_tab[IDX][2][2] = put_vp8_bilinear ## SIZE ## _hv_c
av_cold void ff_vp78dsp_init(VP8DSPContext *dsp)
{
VP78_MC_FUNC(0, 16);
VP78_MC_FUNC(1, 8);
VP78_MC_FUNC(2, 4);
VP78_BILINEAR_MC_FUNC(0, 16);
VP78_BILINEAR_MC_FUNC(1, 8);
VP78_BILINEAR_MC_FUNC(2, 4);
if (ARCH_ARM)
ff_vp78dsp_init_arm(dsp);
if (ARCH_PPC)
ff_vp78dsp_init_ppc(dsp);
if (ARCH_X86)
ff_vp78dsp_init_x86(dsp);
}
#if CONFIG_VP7_DECODER
LOOP_FILTERS(vp7)
av_cold void ff_vp7dsp_init(VP8DSPContext *dsp)
{
dsp->vp8_luma_dc_wht = vp7_luma_dc_wht_c;
dsp->vp8_luma_dc_wht_dc = vp7_luma_dc_wht_dc_c;
dsp->vp8_idct_add = vp7_idct_add_c;
dsp->vp8_idct_dc_add = vp7_idct_dc_add_c;
dsp->vp8_idct_dc_add4y = vp7_idct_dc_add4y_c;
dsp->vp8_idct_dc_add4uv = vp7_idct_dc_add4uv_c;
dsp->vp8_v_loop_filter16y = vp7_v_loop_filter16_c;
dsp->vp8_h_loop_filter16y = vp7_h_loop_filter16_c;
dsp->vp8_v_loop_filter8uv = vp7_v_loop_filter8uv_c;
dsp->vp8_h_loop_filter8uv = vp7_h_loop_filter8uv_c;
dsp->vp8_v_loop_filter16y_inner = vp7_v_loop_filter16_inner_c;
dsp->vp8_h_loop_filter16y_inner = vp7_h_loop_filter16_inner_c;
dsp->vp8_v_loop_filter8uv_inner = vp7_v_loop_filter8uv_inner_c;
dsp->vp8_h_loop_filter8uv_inner = vp7_h_loop_filter8uv_inner_c;
dsp->vp8_v_loop_filter_simple = vp7_v_loop_filter_simple_c;
dsp->vp8_h_loop_filter_simple = vp7_h_loop_filter_simple_c;
}
#endif /* CONFIG_VP7_DECODER */
#if CONFIG_VP8_DECODER
LOOP_FILTERS(vp8)
av_cold void ff_vp8dsp_init(VP8DSPContext *dsp)
{
dsp->vp8_luma_dc_wht = vp8_luma_dc_wht_c;
dsp->vp8_luma_dc_wht_dc = vp8_luma_dc_wht_dc_c;
dsp->vp8_idct_add = vp8_idct_add_c;
dsp->vp8_idct_dc_add = vp8_idct_dc_add_c;
dsp->vp8_idct_dc_add4y = vp8_idct_dc_add4y_c;
dsp->vp8_idct_dc_add4uv = vp8_idct_dc_add4uv_c;
dsp->vp8_v_loop_filter16y = vp8_v_loop_filter16_c;
dsp->vp8_h_loop_filter16y = vp8_h_loop_filter16_c;
dsp->vp8_v_loop_filter8uv = vp8_v_loop_filter8uv_c;
dsp->vp8_h_loop_filter8uv = vp8_h_loop_filter8uv_c;
dsp->vp8_v_loop_filter16y_inner = vp8_v_loop_filter16_inner_c;
dsp->vp8_h_loop_filter16y_inner = vp8_h_loop_filter16_inner_c;
dsp->vp8_v_loop_filter8uv_inner = vp8_v_loop_filter8uv_inner_c;
dsp->vp8_h_loop_filter8uv_inner = vp8_h_loop_filter8uv_inner_c;
dsp->vp8_v_loop_filter_simple = vp8_v_loop_filter_simple_c;
dsp->vp8_h_loop_filter_simple = vp8_h_loop_filter_simple_c;
if (ARCH_ARM)
ff_vp8dsp_init_arm(dsp);
if (ARCH_X86)
ff_vp8dsp_init_x86(dsp);
if (ARCH_MIPS)
ff_vp8dsp_init_mips(dsp);
}
#endif /* CONFIG_VP8_DECODER */

View file

@ -0,0 +1,106 @@
/*
* Copyright (C) 2010 David Conrad
* Copyright (C) 2010 Ronald S. Bultje
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* VP8 compatible video decoder
*/
#ifndef AVCODEC_VP8DSP_H
#define AVCODEC_VP8DSP_H
#include <stddef.h>
#include <stdint.h>
typedef void (*vp8_mc_func)(uint8_t *dst /* align 8 */, ptrdiff_t dstStride,
uint8_t *src /* align 1 */, ptrdiff_t srcStride,
int h, int x, int y);
typedef struct VP8DSPContext {
void (*vp8_luma_dc_wht)(int16_t block[4][4][16], int16_t dc[16]);
void (*vp8_luma_dc_wht_dc)(int16_t block[4][4][16], int16_t dc[16]);
void (*vp8_idct_add)(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
void (*vp8_idct_dc_add)(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
void (*vp8_idct_dc_add4y)(uint8_t *dst, int16_t block[4][16],
ptrdiff_t stride);
void (*vp8_idct_dc_add4uv)(uint8_t *dst, int16_t block[4][16],
ptrdiff_t stride);
// loop filter applied to edges between macroblocks
void (*vp8_v_loop_filter16y)(uint8_t *dst, ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
void (*vp8_h_loop_filter16y)(uint8_t *dst, ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
void (*vp8_v_loop_filter8uv)(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
void (*vp8_h_loop_filter8uv)(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
// loop filter applied to inner macroblock edges
void (*vp8_v_loop_filter16y_inner)(uint8_t *dst, ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
void (*vp8_h_loop_filter16y_inner)(uint8_t *dst, ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
void (*vp8_v_loop_filter8uv_inner)(uint8_t *dstU, uint8_t *dstV,
ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
void (*vp8_h_loop_filter8uv_inner)(uint8_t *dstU, uint8_t *dstV,
ptrdiff_t stride,
int flim_E, int flim_I, int hev_thresh);
void (*vp8_v_loop_filter_simple)(uint8_t *dst, ptrdiff_t stride, int flim);
void (*vp8_h_loop_filter_simple)(uint8_t *dst, ptrdiff_t stride, int flim);
/**
* first dimension: width>>3, height is assumed equal to 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)
*/
vp8_mc_func put_vp8_epel_pixels_tab[3][3][3];
vp8_mc_func put_vp8_bilinear_pixels_tab[3][3][3];
} VP8DSPContext;
void ff_put_vp8_pixels16_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
void ff_put_vp8_pixels8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
void ff_put_vp8_pixels4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
void ff_vp7dsp_init(VP8DSPContext *c);
void ff_vp78dsp_init(VP8DSPContext *c);
void ff_vp78dsp_init_arm(VP8DSPContext *c);
void ff_vp78dsp_init_ppc(VP8DSPContext *c);
void ff_vp78dsp_init_x86(VP8DSPContext *c);
void ff_vp8dsp_init(VP8DSPContext *c);
void ff_vp8dsp_init_arm(VP8DSPContext *c);
void ff_vp8dsp_init_x86(VP8DSPContext *c);
void ff_vp8dsp_init_mips(VP8DSPContext *c);
#define IS_VP7 1
#define IS_VP8 0
#endif /* AVCODEC_VP8DSP_H */

4365
media/ffvpx/libavcodec/vp9.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,211 @@
/*
* 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_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,
TX_16X16,
TX_32X32,
N_TXFM_SIZES,
TX_SWITCHABLE = N_TXFM_SIZES,
N_TXFM_MODES
};
enum TxfmType {
DCT_DCT,
DCT_ADST,
ADST_DCT,
ADST_ADST,
N_TXFM_TYPES
};
enum IntraPredMode {
VERT_PRED,
HOR_PRED,
DC_PRED,
DIAG_DOWN_LEFT_PRED,
DIAG_DOWN_RIGHT_PRED,
VERT_RIGHT_PRED,
HOR_DOWN_PRED,
VERT_LEFT_PRED,
HOR_UP_PRED,
TM_VP8_PRED,
LEFT_DC_PRED,
TOP_DC_PRED,
DC_128_PRED,
DC_127_PRED,
DC_129_PRED,
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,
};
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 */

Some files were not shown because too many files have changed in this diff Show more