XvMC was last relevant over 10 years ago, if ever. There is no reason to use it today.
Unified · Split
| @@ -3,6 +3,7 @@ releases are sorted from youngest to oldest. · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | version 5.1: |
| 5 | 5 | - dialogue enhance audio filter |
| 6 | +- dropped obsolete XvMC hwaccel | |
| 6 | 7 | |
| 7 | 8 | |
| 8 | 9 | version 5.0: |
| @@ -266,7 +266,6 @@ Codecs: · 265 unmodified lines | ||
| 266 | 266 | xan.c Mike Melanson |
| 267 | 267 | xbm* Paul B Mahol |
| 268 | 268 | xface Stefano Sabatini |
| 269 | − xvmc.c Ivan Kalvachev | |
| 270 | 269 | xwd* Paul B Mahol |
| 271 | 270 | |
| 272 | 271 | Hardware acceleration: |
| @@ -1900,7 +1900,6 @@ HWACCEL_AUTODETECT_LIBRARY_LIST=" · 1899 unmodified lines | ||
| 1900 | 1900 | videotoolbox |
| 1901 | 1901 | vulkan |
| 1902 | 1902 | v4l2_m2m |
| 1903 | − xvmc | |
| 1904 | 1903 | " |
| 1905 | 1904 | |
| 1906 | 1905 | # catchall list of things that require external libs to link |
| @@ -3006,7 +3005,6 @@ vaapi_x11_deps="xlib_x11" · 1099 unmodified lines | ||
| 3006 | 3005 | videotoolbox_hwaccel_deps="videotoolbox pthreads" |
| 3007 | 3006 | videotoolbox_hwaccel_extralibs="-framework QuartzCore" |
| 3008 | 3007 | vulkan_deps_any="libdl LoadLibrary" |
| 3009 | −xvmc_deps="X11_extensions_XvMClib_h" | |
| 3010 | 3008 | |
| 3011 | 3009 | av1_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_AV1" |
| 3012 | 3010 | av1_d3d11va_hwaccel_select="av1_decoder" |
| @@ -3054,16 +3052,12 @@ mjpeg_nvdec_hwaccel_deps="nvdec" · 41 unmodified lines | ||
| 3054 | 3052 | mjpeg_nvdec_hwaccel_select="mjpeg_decoder" |
| 3055 | 3053 | mjpeg_vaapi_hwaccel_deps="vaapi" |
| 3056 | 3054 | mjpeg_vaapi_hwaccel_select="mjpeg_decoder" |
| 3057 | −mpeg_xvmc_hwaccel_deps="xvmc" | |
| 3058 | −mpeg_xvmc_hwaccel_select="mpeg2video_decoder" | |
| 3059 | 3055 | mpeg1_nvdec_hwaccel_deps="nvdec" |
| 3060 | 3056 | mpeg1_nvdec_hwaccel_select="mpeg1video_decoder" |
| 3061 | 3057 | mpeg1_vdpau_hwaccel_deps="vdpau" |
| 3062 | 3058 | mpeg1_vdpau_hwaccel_select="mpeg1video_decoder" |
| 3063 | 3059 | mpeg1_videotoolbox_hwaccel_deps="videotoolbox" |
| 3064 | 3060 | mpeg1_videotoolbox_hwaccel_select="mpeg1video_decoder" |
| 3065 | −mpeg1_xvmc_hwaccel_deps="xvmc" | |
| 3066 | −mpeg1_xvmc_hwaccel_select="mpeg1video_decoder" | |
| 3067 | 3061 | mpeg2_d3d11va_hwaccel_deps="d3d11va" |
| 3068 | 3062 | mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder" |
| 3069 | 3063 | mpeg2_d3d11va2_hwaccel_deps="d3d11va" |
| @@ -3078,8 +3072,6 @@ mpeg2_vdpau_hwaccel_deps="vdpau" · 8 unmodified lines | ||
| 3078 | 3072 | mpeg2_vdpau_hwaccel_select="mpeg2video_decoder" |
| 3079 | 3073 | mpeg2_videotoolbox_hwaccel_deps="videotoolbox" |
| 3080 | 3074 | mpeg2_videotoolbox_hwaccel_select="mpeg2video_decoder" |
| 3081 | −mpeg2_xvmc_hwaccel_deps="xvmc" | |
| 3082 | −mpeg2_xvmc_hwaccel_select="mpeg2video_decoder" | |
| 3083 | 3075 | mpeg4_nvdec_hwaccel_deps="nvdec" |
| 3084 | 3076 | mpeg4_nvdec_hwaccel_select="mpeg4_decoder" |
| 3085 | 3077 | mpeg4_vaapi_hwaccel_deps="vaapi" |
| @@ -6308,7 +6300,6 @@ check_headers unistd.h · 3222 unmodified lines | ||
| 6308 | 6300 | check_headers valgrind/valgrind.h |
| 6309 | 6301 | check_func_headers VideoToolbox/VTCompressionSession.h VTCompressionSessionPrepareToEncodeFrames -framework VideoToolbox |
| 6310 | 6302 | check_headers windows.h |
| 6311 | −check_headers X11/extensions/XvMClib.h | |
| 6312 | 6303 | check_headers asm/types.h |
| 6313 | 6304 | |
| 6314 | 6305 | # it seems there are versions of clang in some distros that try to use the |
| @@ -963,7 +963,6 @@ OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL) += vaapi_mjpeg.o · 962 unmodified lines | ||
| 963 | 963 | OBJS-$(CONFIG_MPEG1_NVDEC_HWACCEL) += nvdec_mpeg12.o |
| 964 | 964 | OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.o |
| 965 | 965 | OBJS-$(CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o |
| 966 | −OBJS-$(CONFIG_MPEG1_XVMC_HWACCEL) += mpegvideo_xvmc.o | |
| 967 | 966 | OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o |
| 968 | 967 | OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o |
| 969 | 968 | OBJS-$(CONFIG_MPEG2_NVDEC_HWACCEL) += nvdec_mpeg12.o |
| @@ -971,7 +970,6 @@ OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec.o · 1 unmodified line | ||
| 971 | 970 | OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o |
| 972 | 971 | OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o |
| 973 | 972 | OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o |
| 974 | −OBJS-$(CONFIG_MPEG2_XVMC_HWACCEL) += mpegvideo_xvmc.o | |
| 975 | 973 | OBJS-$(CONFIG_MPEG4_NVDEC_HWACCEL) += nvdec_mpeg4.o |
| 976 | 974 | OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o |
| 977 | 975 | OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_mpeg4.o |
| @@ -2119,7 +2119,6 @@ typedef struct AVHWAccel { · 2118 unmodified lines | ||
| 2119 | 2119 | * |
| 2120 | 2120 | * Meaningful slice information (codec specific) is guaranteed to |
| 2121 | 2121 | * be parsed at this point. This function is mandatory. |
| 2122 | − * The only exception is XvMC, that works on MB level. | |
| 2123 | 2122 | * |
| 2124 | 2123 | * @param avctx the codec context |
| 2125 | 2124 | * @param buf the slice data buffer base |
| @@ -2148,17 +2147,6 @@ typedef struct AVHWAccel { · 22 unmodified lines | ||
| 2148 | 2147 | */ |
| 2149 | 2148 | int frame_priv_data_size; |
| 2150 | 2149 | |
| 2151 | − /** | |
| 2152 | − * Called for every Macroblock in a slice. | |
| 2153 | − * | |
| 2154 | − * XvMC uses it to replace the ff_mpv_reconstruct_mb(). | |
| 2155 | − * Instead of decoding to raw picture, MB parameters are | |
| 2156 | − * stored in an array provided by the video driver. | |
| 2157 | − * | |
| 2158 | − * @param s the mpeg context | |
| 2159 | − */ | |
| 2160 | − void (*decode_mb)(struct MpegEncContext *s); | |
| 2161 | − | |
| 2162 | 2150 | /** |
| 2163 | 2151 | * Initialize the hwaccel private data. |
| 2164 | 2152 | * |
| @@ -736,12 +736,6 @@ static int is_intra_more_likely(ERContext *s) · 735 unmodified lines | ||
| 736 | 736 | if (undamaged_count < 5) |
| 737 | 737 | return 0; // almost all MBs damaged -> use temporal prediction |
| 738 | 738 | |
| 739 | − // prevent dsp.sad() check, that requires access to the image | |
| 740 | − if (CONFIG_XVMC && | |
| 741 | − s->avctx->hwaccel && s->avctx->hwaccel->decode_mb && | |
| 742 | − s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) | |
| 743 | − return 1; | |
| 744 | − | |
| 745 | 739 | skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs |
| 746 | 740 | is_intra_likely = 0; |
| 747 | 741 | |
| @@ -1229,9 +1223,6 @@ void ff_er_frame_end(ERContext *s) · 481 unmodified lines | ||
| 1229 | 1223 | } else |
| 1230 | 1224 | guess_mv(s); |
| 1231 | 1225 | |
| 1232 | − /* the filters below manipulate raw image, skip them */ | |
| 1233 | − if (CONFIG_XVMC && s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) | |
| 1234 | − goto ec_clean; | |
| 1235 | 1226 | /* fill DC for inter blocks */ |
| 1236 | 1227 | for (mb_y = 0; mb_y < s->mb_height; mb_y++) { |
| 1237 | 1228 | for (mb_x = 0; mb_x < s->mb_width; mb_x++) { |
| @@ -47,7 +47,6 @@ extern const AVHWAccel ff_mjpeg_vaapi_hwaccel; · 46 unmodified lines | ||
| 47 | 47 | extern const AVHWAccel ff_mpeg1_nvdec_hwaccel; |
| 48 | 48 | extern const AVHWAccel ff_mpeg1_vdpau_hwaccel; |
| 49 | 49 | extern const AVHWAccel ff_mpeg1_videotoolbox_hwaccel; |
| 50 | −extern const AVHWAccel ff_mpeg1_xvmc_hwaccel; | |
| 51 | 50 | extern const AVHWAccel ff_mpeg2_d3d11va_hwaccel; |
| 52 | 51 | extern const AVHWAccel ff_mpeg2_d3d11va2_hwaccel; |
| 53 | 52 | extern const AVHWAccel ff_mpeg2_nvdec_hwaccel; |
| @@ -55,7 +54,6 @@ extern const AVHWAccel ff_mpeg2_dxva2_hwaccel; · 1 unmodified line | ||
| 55 | 54 | extern const AVHWAccel ff_mpeg2_vaapi_hwaccel; |
| 56 | 55 | extern const AVHWAccel ff_mpeg2_vdpau_hwaccel; |
| 57 | 56 | extern const AVHWAccel ff_mpeg2_videotoolbox_hwaccel; |
| 58 | −extern const AVHWAccel ff_mpeg2_xvmc_hwaccel; | |
| 59 | 57 | extern const AVHWAccel ff_mpeg4_nvdec_hwaccel; |
| 60 | 58 | extern const AVHWAccel ff_mpeg4_vaapi_hwaccel; |
| 61 | 59 | extern const AVHWAccel ff_mpeg4_vdpau_hwaccel; |
| @@ -78,8 +78,6 @@ typedef struct AVCodecHWConfigInternal { · 77 unmodified lines | ||
| 78 | 78 | HW_CONFIG_HWACCEL(1, 1, 1, VIDEOTOOLBOX, VIDEOTOOLBOX, ff_ ## codec ## _videotoolbox_hwaccel) |
| 79 | 79 | #define HWACCEL_D3D11VA(codec) \ |
| 80 | 80 | HW_CONFIG_HWACCEL(0, 0, 1, D3D11VA_VLD, NONE, ff_ ## codec ## _d3d11va_hwaccel) |
| 81 | −#define HWACCEL_XVMC(codec) \ | |
| 82 | − HW_CONFIG_HWACCEL(0, 0, 1, XVMC, NONE, ff_ ## codec ## _xvmc_hwaccel) | |
| 83 | 81 | |
| 84 | 82 | #define HW_CONFIG_ENCODER(device, frames, ad_hoc, format, device_type_) \ |
| 85 | 83 | &(const AVCodecHWConfigInternal) { \ |
| @@ -51,7 +51,6 @@ · 50 unmodified lines | ||
| 51 | 51 | #include "profiles.h" |
| 52 | 52 | #include "startcode.h" |
| 53 | 53 | #include "thread.h" |
| 54 | −#include "xvmc_internal.h" | |
| 55 | 54 | |
| 56 | 55 | #define A53_MAX_CC_COUNT 2000 |
| 57 | 56 | |
| @@ -763,9 +762,6 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) · 705 unmodified lines | ||
| 763 | 762 | memset(s->last_mv, 0, sizeof(s->last_mv)); |
| 764 | 763 | } |
| 765 | 764 | s->mb_intra = 1; |
| 766 | − // if 1, we memcpy blocks in xvmcvideo | |
| 767 | − if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks) | |
| 768 | − ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks | |
| 769 | 765 | |
| 770 | 766 | if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { |
| 771 | 767 | if (s->avctx->flags2 & AV_CODEC_FLAG2_FAST) { |
| @@ -994,10 +990,6 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) · 222 unmodified lines | ||
| 994 | 990 | return AVERROR_INVALIDDATA; |
| 995 | 991 | } |
| 996 | 992 | |
| 997 | − // if 1, we memcpy blocks in xvmcvideo | |
| 998 | − if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks) | |
| 999 | − ff_xvmc_pack_pblocks(s, cbp); | |
| 1000 | − | |
| 1001 | 993 | if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { |
| 1002 | 994 | if (s->avctx->flags2 & AV_CODEC_FLAG2_FAST) { |
| 1003 | 995 | for (i = 0; i < 6; i++) { |
| @@ -1115,9 +1107,6 @@ static const enum AVPixelFormat mpeg1_hwaccel_pixfmt_list_420[] = { · 111 unmodified lines | ||
| 1115 | 1107 | #if CONFIG_MPEG1_NVDEC_HWACCEL |
| 1116 | 1108 | AV_PIX_FMT_CUDA, |
| 1117 | 1109 | #endif |
| 1118 | −#if CONFIG_MPEG1_XVMC_HWACCEL | |
| 1119 | − AV_PIX_FMT_XVMC, | |
| 1120 | −#endif | |
| 1121 | 1110 | #if CONFIG_MPEG1_VDPAU_HWACCEL |
| 1122 | 1111 | AV_PIX_FMT_VDPAU, |
| 1123 | 1112 | #endif |
| @@ -1129,9 +1118,6 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { · 5 unmodified lines | ||
| 1129 | 1118 | #if CONFIG_MPEG2_NVDEC_HWACCEL |
| 1130 | 1119 | AV_PIX_FMT_CUDA, |
| 1131 | 1120 | #endif |
| 1132 | −#if CONFIG_MPEG2_XVMC_HWACCEL | |
| 1133 | − AV_PIX_FMT_XVMC, | |
| 1134 | −#endif | |
| 1135 | 1121 | #if CONFIG_MPEG2_VDPAU_HWACCEL |
| 1136 | 1122 | AV_PIX_FMT_VDPAU, |
| 1137 | 1123 | #endif |
| @@ -1183,21 +1169,6 @@ static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx) · 45 unmodified lines | ||
| 1183 | 1169 | return ff_thread_get_format(avctx, pix_fmts); |
| 1184 | 1170 | } |
| 1185 | 1171 | |
| 1186 | −static void setup_hwaccel_for_pixfmt(AVCodecContext *avctx) | |
| 1187 | −{ | |
| 1188 | − // until then pix_fmt may be changed right after codec init | |
| 1189 | − if (avctx->hwaccel) | |
| 1190 | − if (avctx->idct_algo == FF_IDCT_AUTO) | |
| 1191 | − avctx->idct_algo = FF_IDCT_NONE; | |
| 1192 | − | |
| 1193 | − if (avctx->hwaccel && avctx->pix_fmt == AV_PIX_FMT_XVMC) { | |
| 1194 | − Mpeg1Context *s1 = avctx->priv_data; | |
| 1195 | − MpegEncContext *s = &s1->mpeg_enc_ctx; | |
| 1196 | − | |
| 1197 | − s->pack_pblocks = 1; | |
| 1198 | − } | |
| 1199 | −} | |
| 1200 | − | |
| 1201 | 1172 | /* Call this function when we know all parameters. |
| 1202 | 1173 | * It may be called in different places for MPEG-1 and MPEG-2. */ |
| 1203 | 1174 | static int mpeg_decode_postinit(AVCodecContext *avctx) |
| @@ -1321,7 +1292,6 @@ static int mpeg_decode_postinit(AVCodecContext *avctx) · 117 unmodified lines | ||
| 1321 | 1292 | } // MPEG-2 |
| 1322 | 1293 | |
| 1323 | 1294 | avctx->pix_fmt = mpeg_get_pixelformat(avctx); |
| 1324 | − setup_hwaccel_for_pixfmt(avctx); | |
| 1325 | 1295 | |
| 1326 | 1296 | /* Quantization matrices may need reordering |
| 1327 | 1297 | * if DCT permutation is changed. */ |
| @@ -1809,10 +1779,6 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, · 481 unmodified lines | ||
| 1809 | 1779 | } |
| 1810 | 1780 | |
| 1811 | 1781 | for (;;) { |
| 1812 | − // If 1, we memcpy blocks in xvmcvideo. | |
| 1813 | − if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks) | |
| 1814 | − ff_xvmc_init_block(s); // set s->block | |
| 1815 | − | |
| 1816 | 1782 | if ((ret = mpeg_decode_mb(s, s->block)) < 0) |
| 1817 | 1783 | return ret; |
| 1818 | 1784 | |
| @@ -2166,7 +2132,6 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, · 347 unmodified lines | ||
| 2166 | 2132 | s->codec_id = |
| 2167 | 2133 | s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO; |
| 2168 | 2134 | s->out_format = FMT_MPEG1; |
| 2169 | − s->swap_uv = 0; // AFAIK VCR2 does not have SEQ_HEADER | |
| 2170 | 2135 | if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY) |
| 2171 | 2136 | s->low_delay = 1; |
| 2172 | 2137 | |
| @@ -2195,7 +2160,6 @@ static int vcr2_init_sequence(AVCodecContext *avctx) · 22 unmodified lines | ||
| 2195 | 2160 | s->low_delay = 1; |
| 2196 | 2161 | |
| 2197 | 2162 | avctx->pix_fmt = mpeg_get_pixelformat(avctx); |
| 2198 | − setup_hwaccel_for_pixfmt(avctx); | |
| 2199 | 2163 | |
| 2200 | 2164 | ff_mpv_idct_init(s); |
| 2201 | 2165 | if ((ret = ff_mpv_common_init(s)) < 0) |
| @@ -2222,7 +2186,6 @@ static int vcr2_init_sequence(AVCodecContext *avctx) · 20 unmodified lines | ||
| 2222 | 2186 | if (s->codec_tag == AV_RL32("BW10")) { |
| 2223 | 2187 | s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO; |
| 2224 | 2188 | } else { |
| 2225 | − s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB | |
| 2226 | 2189 | s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; |
| 2227 | 2190 | } |
| 2228 | 2191 | s1->save_width = s->width; |
| @@ -2924,9 +2887,6 @@ const AVCodec ff_mpeg1video_decoder = { · 695 unmodified lines | ||
| 2924 | 2887 | #endif |
| 2925 | 2888 | #if CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL |
| 2926 | 2889 | HWACCEL_VIDEOTOOLBOX(mpeg1), |
| 2927 | −#endif | |
| 2928 | −#if CONFIG_MPEG1_XVMC_HWACCEL | |
| 2929 | − HWACCEL_XVMC(mpeg1), | |
| 2930 | 2890 | #endif |
| 2931 | 2891 | NULL |
| 2932 | 2892 | }, |
| @@ -2972,9 +2932,6 @@ const AVCodec ff_mpeg2video_decoder = { · 39 unmodified lines | ||
| 2972 | 2932 | #endif |
| 2973 | 2933 | #if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL |
| 2974 | 2934 | HWACCEL_VIDEOTOOLBOX(mpeg2), |
| 2975 | −#endif | |
| 2976 | −#if CONFIG_MPEG2_XVMC_HWACCEL | |
| 2977 | − HWACCEL_XVMC(mpeg2), | |
| 2978 | 2935 | #endif |
| 2979 | 2936 | NULL |
| 2980 | 2937 | }, |
| @@ -1644,12 +1644,6 @@ skip_idct: · 1643 unmodified lines | ||
| 1644 | 1644 | |
| 1645 | 1645 | void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]) |
| 1646 | 1646 | { |
| 1647 | − if (CONFIG_XVMC && | |
| 1648 | − s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) { | |
| 1649 | − s->avctx->hwaccel->decode_mb(s); //xvmc uses pblocks | |
| 1650 | − return; | |
| 1651 | − } | |
| 1652 | − | |
| 1653 | 1647 | if (s->avctx->debug & FF_DEBUG_DCT_COEFF) { |
| 1654 | 1648 | /* print DCT coefficients */ |
| 1655 | 1649 | av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y); |
| @@ -467,8 +467,6 @@ typedef struct MpegEncContext { · 466 unmodified lines | ||
| 467 | 467 | int rtp_payload_size; |
| 468 | 468 | |
| 469 | 469 | uint8_t *ptr_lastgob; |
| 470 | − int swap_uv; //vcr2 codec is an MPEG-2 variant with U and V swapped | |
| 471 | − int pack_pblocks; //xvmc needs to keep blocks without gaps. | |
| 472 | 470 | int16_t (*pblocks[12])[64]; |
| 473 | 471 | |
| 474 | 472 | int16_t (*block)[64]; ///< points to one of the following blocks |
| @@ -1,377 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * XVideo Motion Compensation | |
| 3 | − * Copyright (c) 2003 Ivan Kalvachev | |
| 4 | − * | |
| 5 | − * This file is part of FFmpeg. | |
| 6 | − * | |
| 7 | − * FFmpeg is free software; you can redistribute it and/or | |
| 8 | − * modify it under the terms of the GNU Lesser General Public | |
| 9 | − * License as published by the Free Software Foundation; either | |
| 10 | − * version 2.1 of the License, or (at your option) any later version. | |
| 11 | − * | |
| 12 | − * FFmpeg is distributed in the hope that it will be useful, | |
| 13 | − * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | − * Lesser General Public License for more details. | |
| 16 | − * | |
| 17 | − * You should have received a copy of the GNU Lesser General Public | |
| 18 | − * License along with FFmpeg; if not, write to the Free Software | |
| 19 | − * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 20 | − */ | |
| 21 | − | |
| 22 | −#include <limits.h> | |
| 23 | −#include <X11/extensions/XvMC.h> | |
| 24 | − | |
| 25 | −#include "avcodec.h" | |
| 26 | −#include "mpegutils.h" | |
| 27 | −#include "mpegvideo.h" | |
| 28 | −#include "mpegvideodec.h" | |
| 29 | − | |
| 30 | −#undef NDEBUG | |
| 31 | −#include <assert.h> | |
| 32 | − | |
| 33 | −#include "xvmc.h" | |
| 34 | −#include "xvmc_internal.h" | |
| 35 | −#include "version.h" | |
| 36 | − | |
| 37 | −/** | |
| 38 | − * Initialize the block field of the MpegEncContext pointer passed as | |
| 39 | − * parameter after making sure that the data is not corrupted. | |
| 40 | − * In order to implement something like direct rendering instead of decoding | |
| 41 | − * coefficients in s->blocks and then copying them, copy them directly | |
| 42 | − * into the data_blocks array provided by xvmc. | |
| 43 | − */ | |
| 44 | −void ff_xvmc_init_block(MpegEncContext *s) | |
| 45 | −{ | |
| 46 | − struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2]; | |
| 47 | − assert(render && render->xvmc_id == AV_XVMC_ID); | |
| 48 | − | |
| 49 | − s->block = (int16_t (*)[64])(render->data_blocks + render->next_free_data_block_num * 64); | |
| 50 | −} | |
| 51 | − | |
| 52 | −static void exchange_uv(MpegEncContext *s) | |
| 53 | −{ | |
| 54 | − int16_t (*tmp)[64]; | |
| 55 | − | |
| 56 | − tmp = s->pblocks[4]; | |
| 57 | − s->pblocks[4] = s->pblocks[5]; | |
| 58 | − s->pblocks[5] = tmp; | |
| 59 | −} | |
| 60 | − | |
| 61 | −/** | |
| 62 | − * Fill individual block pointers, so there are no gaps in the data_block array | |
| 63 | − * in case not all blocks in the macroblock are coded. | |
| 64 | − */ | |
| 65 | −void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp) | |
| 66 | −{ | |
| 67 | − int i, j = 0; | |
| 68 | − const int mb_block_count = 4 + (1 << s->chroma_format); | |
| 69 | − | |
| 70 | − cbp <<= 12-mb_block_count; | |
| 71 | − for (i = 0; i < mb_block_count; i++) { | |
| 72 | − if (cbp & (1 << 11)) | |
| 73 | − s->pblocks[i] = &s->block[j++]; | |
| 74 | − else | |
| 75 | − s->pblocks[i] = NULL; | |
| 76 | − cbp += cbp; | |
| 77 | − } | |
| 78 | − if (s->swap_uv) { | |
| 79 | − exchange_uv(s); | |
| 80 | − } | |
| 81 | −} | |
| 82 | − | |
| 83 | −/** | |
| 84 | − * Find and store the surfaces that are used as reference frames. | |
| 85 | − * This function should be called for every new field and/or frame. | |
| 86 | − * It should be safe to call the function a few times for the same field. | |
| 87 | − */ | |
| 88 | −static int ff_xvmc_field_start(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size) | |
| 89 | −{ | |
| 90 | − struct MpegEncContext *s = avctx->priv_data; | |
| 91 | − struct xvmc_pix_fmt *last, *next, *render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2]; | |
| 92 | − const int mb_block_count = 4 + (1 << s->chroma_format); | |
| 93 | − | |
| 94 | − assert(avctx); | |
| 95 | − if (!render || render->xvmc_id != AV_XVMC_ID || | |
| 96 | − !render->data_blocks || !render->mv_blocks || | |
| 97 | − (unsigned int)render->allocated_mv_blocks > INT_MAX/(64*6) || | |
| 98 | − (unsigned int)render->allocated_data_blocks > INT_MAX/64 || | |
| 99 | − !render->p_surface) { | |
| 100 | − av_log(avctx, AV_LOG_ERROR, | |
| 101 | − "Render token doesn't look as expected.\n"); | |
| 102 | − return -1; // make sure that this is a render packet | |
| 103 | − } | |
| 104 | − | |
| 105 | − if (render->filled_mv_blocks_num) { | |
| 106 | − av_log(avctx, AV_LOG_ERROR, | |
| 107 | − "Rendering surface contains %i unprocessed blocks.\n", | |
| 108 | − render->filled_mv_blocks_num); | |
| 109 | − return -1; | |
| 110 | − } | |
| 111 | − if (render->allocated_mv_blocks < 1 || | |
| 112 | − render->allocated_data_blocks < render->allocated_mv_blocks*mb_block_count || | |
| 113 | − render->start_mv_blocks_num >= render->allocated_mv_blocks || | |
| 114 | − render->next_free_data_block_num > | |
| 115 | − render->allocated_data_blocks - | |
| 116 | − mb_block_count*(render->allocated_mv_blocks-render->start_mv_blocks_num)) { | |
| 117 | − av_log(avctx, AV_LOG_ERROR, | |
| 118 | − "Rendering surface doesn't provide enough block structures to work with.\n"); | |
| 119 | − return -1; | |
| 120 | − } | |
| 121 | − | |
| 122 | − render->picture_structure = s->picture_structure; | |
| 123 | − render->flags = s->first_field ? 0 : XVMC_SECOND_FIELD; | |
| 124 | − render->p_future_surface = NULL; | |
| 125 | − render->p_past_surface = NULL; | |
| 126 | − | |
| 127 | − switch(s->pict_type) { | |
| 128 | − case AV_PICTURE_TYPE_I: | |
| 129 | − return 0; // no prediction from other frames | |
| 130 | − case AV_PICTURE_TYPE_B: | |
| 131 | − next = (struct xvmc_pix_fmt*)s->next_picture.f->data[2]; | |
| 132 | − if (!next) | |
| 133 | − return -1; | |
| 134 | − if (next->xvmc_id != AV_XVMC_ID) | |
| 135 | − return -1; | |
| 136 | − render->p_future_surface = next->p_surface; | |
| 137 | − // no return here, going to set forward prediction | |
| 138 | − case AV_PICTURE_TYPE_P: | |
| 139 | − last = (struct xvmc_pix_fmt*)s->last_picture.f->data[2]; | |
| 140 | − if (!last) | |
| 141 | − last = render; // predict second field from the first | |
| 142 | − if (last->xvmc_id != AV_XVMC_ID) | |
| 143 | − return -1; | |
| 144 | − render->p_past_surface = last->p_surface; | |
| 145 | − return 0; | |
| 146 | − } | |
| 147 | − | |
| 148 | −return -1; | |
| 149 | −} | |
| 150 | − | |
| 151 | −/** | |
| 152 | − * Complete frame/field rendering by passing any remaining blocks. | |
| 153 | − * Normally ff_draw_horiz_band() is called for each slice, however, | |
| 154 | − * some leftover blocks, for example from error_resilience(), may remain. | |
| 155 | − * It should be safe to call the function a few times for the same field. | |
| 156 | − */ | |
| 157 | −static int ff_xvmc_field_end(AVCodecContext *avctx) | |
| 158 | −{ | |
| 159 | − struct MpegEncContext *s = avctx->priv_data; | |
| 160 | − struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2]; | |
| 161 | − assert(render); | |
| 162 | − | |
| 163 | − if (render->filled_mv_blocks_num > 0) | |
| 164 | − ff_mpeg_draw_horiz_band(s, 0, 0); | |
| 165 | − return 0; | |
| 166 | −} | |
| 167 | − | |
| 168 | −/** | |
| 169 | − * Synthesize the data needed by XvMC to render one macroblock of data. | |
| 170 | − * Fill all relevant fields, if necessary do IDCT. | |
| 171 | − */ | |
| 172 | −static void ff_xvmc_decode_mb(struct MpegEncContext *s) | |
| 173 | −{ | |
| 174 | − XvMCMacroBlock *mv_block; | |
| 175 | − struct xvmc_pix_fmt *render; | |
| 176 | − int i, cbp, blocks_per_mb; | |
| 177 | − | |
| 178 | − const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; | |
| 179 | − | |
| 180 | − | |
| 181 | − if (s->encoding) { | |
| 182 | − av_log(s->avctx, AV_LOG_ERROR, "XVMC doesn't support encoding!!!\n"); | |
| 183 | − return; | |
| 184 | − } | |
| 185 | − | |
| 186 | − // from ff_mpv_reconstruct_mb(), update DC predictors for P macroblocks | |
| 187 | − if (!s->mb_intra) { | |
| 188 | − s->last_dc[0] = | |
| 189 | − s->last_dc[1] = | |
| 190 | − s->last_dc[2] = 128 << s->intra_dc_precision; | |
| 191 | − } | |
| 192 | − | |
| 193 | − // MC doesn't skip blocks | |
| 194 | − s->mb_skipped = 0; | |
| 195 | − | |
| 196 | − | |
| 197 | − // Do I need to export quant when I could not perform postprocessing? | |
| 198 | − // Anyway, it doesn't hurt. | |
| 199 | − s->current_picture.qscale_table[mb_xy] = s->qscale; | |
| 200 | − | |
| 201 | − // start of XVMC-specific code | |
| 202 | − render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2]; | |
| 203 | − assert(render); | |
| 204 | − assert(render->xvmc_id == AV_XVMC_ID); | |
| 205 | − assert(render->mv_blocks); | |
| 206 | − | |
| 207 | − // take the next free macroblock | |
| 208 | − mv_block = &render->mv_blocks[render->start_mv_blocks_num + | |
| 209 | − render->filled_mv_blocks_num]; | |
| 210 | − | |
| 211 | − mv_block->x = s->mb_x; | |
| 212 | − mv_block->y = s->mb_y; | |
| 213 | − mv_block->dct_type = s->interlaced_dct; // XVMC_DCT_TYPE_FRAME/FIELD; | |
| 214 | − if (s->mb_intra) { | |
| 215 | − mv_block->macroblock_type = XVMC_MB_TYPE_INTRA; // no MC, all done | |
| 216 | − } else { | |
| 217 | − mv_block->macroblock_type = XVMC_MB_TYPE_PATTERN; | |
| 218 | − | |
| 219 | − if (s->mv_dir & MV_DIR_FORWARD) { | |
| 220 | − mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD; | |
| 221 | − // PMV[n][dir][xy] = mv[dir][n][xy] | |
| 222 | − mv_block->PMV[0][0][0] = s->mv[0][0][0]; | |
| 223 | − mv_block->PMV[0][0][1] = s->mv[0][0][1]; | |
| 224 | − mv_block->PMV[1][0][0] = s->mv[0][1][0]; | |
| 225 | − mv_block->PMV[1][0][1] = s->mv[0][1][1]; | |
| 226 | − } | |
| 227 | − if (s->mv_dir & MV_DIR_BACKWARD) { | |
| 228 | − mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD; | |
| 229 | − mv_block->PMV[0][1][0] = s->mv[1][0][0]; | |
| 230 | − mv_block->PMV[0][1][1] = s->mv[1][0][1]; | |
| 231 | − mv_block->PMV[1][1][0] = s->mv[1][1][0]; | |
| 232 | − mv_block->PMV[1][1][1] = s->mv[1][1][1]; | |
| 233 | − } | |
| 234 | − | |
| 235 | − switch(s->mv_type) { | |
| 236 | − case MV_TYPE_16X16: | |
| 237 | − mv_block->motion_type = XVMC_PREDICTION_FRAME; | |
| 238 | − break; | |
| 239 | − case MV_TYPE_16X8: | |
| 240 | − mv_block->motion_type = XVMC_PREDICTION_16x8; | |
| 241 | − break; | |
| 242 | − case MV_TYPE_FIELD: | |
| 243 | − mv_block->motion_type = XVMC_PREDICTION_FIELD; | |
| 244 | − if (s->picture_structure == PICT_FRAME) { | |
| 245 | − mv_block->PMV[0][0][1] <<= 1; | |
| 246 | − mv_block->PMV[1][0][1] <<= 1; | |
| 247 | − mv_block->PMV[0][1][1] <<= 1; | |
| 248 | − mv_block->PMV[1][1][1] <<= 1; | |
| 249 | − } | |
| 250 | − break; | |
| 251 | − case MV_TYPE_DMV: | |
| 252 | − mv_block->motion_type = XVMC_PREDICTION_DUAL_PRIME; | |
| 253 | − if (s->picture_structure == PICT_FRAME) { | |
| 254 | − | |
| 255 | − mv_block->PMV[0][0][0] = s->mv[0][0][0]; // top from top | |
| 256 | − mv_block->PMV[0][0][1] = s->mv[0][0][1] << 1; | |
| 257 | − | |
| 258 | − mv_block->PMV[0][1][0] = s->mv[0][0][0]; // bottom from bottom | |
| 259 | − mv_block->PMV[0][1][1] = s->mv[0][0][1] << 1; | |
| 260 | − | |
| 261 | − mv_block->PMV[1][0][0] = s->mv[0][2][0]; // dmv00, top from bottom | |
| 262 | − mv_block->PMV[1][0][1] = s->mv[0][2][1] << 1; // dmv01 | |
| 263 | − | |
| 264 | − mv_block->PMV[1][1][0] = s->mv[0][3][0]; // dmv10, bottom from top | |
| 265 | − mv_block->PMV[1][1][1] = s->mv[0][3][1] << 1; // dmv11 | |
| 266 | − | |
| 267 | − } else { | |
| 268 | − mv_block->PMV[0][1][0] = s->mv[0][2][0]; // dmv00 | |
| 269 | − mv_block->PMV[0][1][1] = s->mv[0][2][1]; // dmv01 | |
| 270 | − } | |
| 271 | − break; | |
| 272 | − default: | |
| 273 | − assert(0); | |
| 274 | − } | |
| 275 | − | |
| 276 | − mv_block->motion_vertical_field_select = 0; | |
| 277 | − | |
| 278 | − // set correct field references | |
| 279 | − if (s->mv_type == MV_TYPE_FIELD || s->mv_type == MV_TYPE_16X8) { | |
| 280 | − mv_block->motion_vertical_field_select |= s->field_select[0][0]; | |
| 281 | − mv_block->motion_vertical_field_select |= s->field_select[1][0] << 1; | |
| 282 | − mv_block->motion_vertical_field_select |= s->field_select[0][1] << 2; | |
| 283 | − mv_block->motion_vertical_field_select |= s->field_select[1][1] << 3; | |
| 284 | − } | |
| 285 | − } // !intra | |
| 286 | − // time to handle data blocks | |
| 287 | − mv_block->index = render->next_free_data_block_num; | |
| 288 | − | |
| 289 | − blocks_per_mb = 6; | |
| 290 | − if (s->chroma_format >= 2) { | |
| 291 | − blocks_per_mb = 4 + (1 << s->chroma_format); | |
| 292 | − } | |
| 293 | − | |
| 294 | − // calculate cbp | |
| 295 | − cbp = 0; | |
| 296 | − for (i = 0; i < blocks_per_mb; i++) { | |
| 297 | − cbp += cbp; | |
| 298 | − if (s->block_last_index[i] >= 0) | |
| 299 | − cbp++; | |
| 300 | − } | |
| 301 | − | |
| 302 | − if (s->avctx->flags & AV_CODEC_FLAG_GRAY) { | |
| 303 | − if (s->mb_intra) { // intra frames are always full chroma blocks | |
| 304 | − for (i = 4; i < blocks_per_mb; i++) { | |
| 305 | − memset(s->pblocks[i], 0, sizeof(*s->pblocks[i])); // so we need to clear them | |
| 306 | − if (!render->unsigned_intra) | |
| 307 | − *s->pblocks[i][0] = 1 << 10; | |
| 308 | − } | |
| 309 | − } else { | |
| 310 | − cbp &= 0xf << (blocks_per_mb - 4); | |
| 311 | − blocks_per_mb = 4; // luminance blocks only | |
| 312 | − } | |
| 313 | − } | |
| 314 | − mv_block->coded_block_pattern = cbp; | |
| 315 | − if (cbp == 0) | |
| 316 | − mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN; | |
| 317 | − | |
| 318 | − for (i = 0; i < blocks_per_mb; i++) { | |
| 319 | − if (s->block_last_index[i] >= 0) { | |
| 320 | − // I do not have unsigned_intra MOCO to test, hope it is OK. | |
| 321 | − if (s->mb_intra && (render->idct || !render->unsigned_intra)) | |
| 322 | − *s->pblocks[i][0] -= 1 << 10; | |
| 323 | − if (!render->idct) { | |
| 324 | − s->idsp.idct(*s->pblocks[i]); | |
| 325 | − /* It is unclear if MC hardware requires pixel diff values to be | |
| 326 | − * in the range [-255;255]. TODO: Clipping if such hardware is | |
| 327 | − * ever found. As of now it would only be an unnecessary | |
| 328 | − * slowdown. */ | |
| 329 | − } | |
| 330 | − // copy blocks only if the codec doesn't support pblocks reordering | |
| 331 | − if (!s->pack_pblocks) { | |
| 332 | − memcpy(&render->data_blocks[render->next_free_data_block_num*64], | |
| 333 | − s->pblocks[i], sizeof(*s->pblocks[i])); | |
| 334 | − } | |
| 335 | − render->next_free_data_block_num++; | |
| 336 | − } | |
| 337 | − } | |
| 338 | − render->filled_mv_blocks_num++; | |
| 339 | − | |
| 340 | − assert(render->filled_mv_blocks_num <= render->allocated_mv_blocks); | |
| 341 | − assert(render->next_free_data_block_num <= render->allocated_data_blocks); | |
| 342 | − /* The above conditions should not be able to fail as long as this function | |
| 343 | − * is used and the following 'if ()' automatically calls a callback to free | |
| 344 | − * blocks. */ | |
| 345 | − | |
| 346 | − | |
| 347 | − if (render->filled_mv_blocks_num == render->allocated_mv_blocks) | |
| 348 | − ff_mpeg_draw_horiz_band(s, 0, 0); | |
| 349 | −} | |
| 350 | − | |
| 351 | −#if CONFIG_MPEG1_XVMC_HWACCEL | |
| 352 | −const AVHWAccel ff_mpeg1_xvmc_hwaccel = { | |
| 353 | − .name = "mpeg1_xvmc", | |
| 354 | − .type = AVMEDIA_TYPE_VIDEO, | |
| 355 | − .id = AV_CODEC_ID_MPEG1VIDEO, | |
| 356 | − .pix_fmt = AV_PIX_FMT_XVMC, | |
| 357 | − .start_frame = ff_xvmc_field_start, | |
| 358 | − .end_frame = ff_xvmc_field_end, | |
| 359 | − .decode_slice = NULL, | |
| 360 | − .decode_mb = ff_xvmc_decode_mb, | |
| 361 | − .priv_data_size = 0, | |
| 362 | −}; | |
| 363 | −#endif | |
| 364 | − | |
| 365 | −#if CONFIG_MPEG2_XVMC_HWACCEL | |
| 366 | −const AVHWAccel ff_mpeg2_xvmc_hwaccel = { | |
| 367 | − .name = "mpeg2_xvmc", | |
| 368 | − .type = AVMEDIA_TYPE_VIDEO, | |
| 369 | − .id = AV_CODEC_ID_MPEG2VIDEO, | |
| 370 | − .pix_fmt = AV_PIX_FMT_XVMC, | |
| 371 | − .start_frame = ff_xvmc_field_start, | |
| 372 | − .end_frame = ff_xvmc_field_end, | |
| 373 | − .decode_slice = NULL, | |
| 374 | − .decode_mb = ff_xvmc_decode_mb, | |
| 375 | − .priv_data_size = 0, | |
| 376 | −}; | |
| 377 | −#endif | |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include "libavutil/version.h" |
| 29 | 29 | |
| 30 | 30 | #define LIBAVCODEC_VERSION_MAJOR 59 |
| 31 | −#define LIBAVCODEC_VERSION_MINOR 20 | |
| 31 | +#define LIBAVCODEC_VERSION_MINOR 21 | |
| 32 | 32 | #define LIBAVCODEC_VERSION_MICRO 100 |
| 33 | 33 | |
| 34 | 34 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |
| @@ -44,10 +44,6 @@ av_cold void ff_blockdsp_init_x86(BlockDSPContext *c, · 43 unmodified lines | ||
| 44 | 44 | c->clear_blocks = ff_clear_blocks_mmx; |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | − /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */ | |
| 48 | − if (CONFIG_XVMC && avctx->hwaccel && avctx->hwaccel->decode_mb) | |
| 49 | − return; | |
| 50 | − | |
| 51 | 47 | if (EXTERNAL_SSE(cpu_flags)) { |
| 52 | 48 | c->clear_block = ff_clear_block_sse; |
| 53 | 49 | c->clear_blocks = ff_clear_blocks_sse; |
| @@ -1,31 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * XVideo Motion Compensation internal functions | |
| 3 | − * | |
| 4 | − * This file is part of FFmpeg. | |
| 5 | − * | |
| 6 | − * FFmpeg is free software; you can redistribute it and/or | |
| 7 | − * modify it under the terms of the GNU Lesser General Public | |
| 8 | − * License as published by the Free Software Foundation; either | |
| 9 | − * version 2.1 of the License, or (at your option) any later version. | |
| 10 | − * | |
| 11 | − * FFmpeg is distributed in the hope that it will be useful, | |
| 12 | − * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 | − * Lesser General Public License for more details. | |
| 15 | − * | |
| 16 | − * You should have received a copy of the GNU Lesser General Public | |
| 17 | − * License along with FFmpeg; if not, write to the Free Software | |
| 18 | − * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 19 | − */ | |
| 20 | − | |
| 21 | −#ifndef AVCODEC_XVMC_INTERNAL_H | |
| 22 | −#define AVCODEC_XVMC_INTERNAL_H | |
| 23 | − | |
| 24 | −#include "avcodec.h" | |
| 25 | −#include "mpegvideo.h" | |
| 26 | −#include "version.h" | |
| 27 | − | |
| 28 | −void ff_xvmc_init_block(MpegEncContext *s); | |
| 29 | −void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp); | |
| 30 | − | |
| 31 | −#endif /* AVCODEC_XVMC_INTERNAL_H */ | |