Projects
Multimedia
avidemux3
xvba_support_from_xbmc_xvba.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xvba_support_from_xbmc_xvba.patch of Package avidemux3 (Revision 4)
Currently displaying revision
4
,
Show latest
diff --git a/configure b/configure index d557cac..ba1f392 100755 --- a/configure +++ b/configure @@ -144,6 +144,7 @@ --disable-vaapi disable VAAPI code [autodetect] --enable-vda enable VDA code --disable-vdpau disable VDPAU code [autodetect] + --disable-xvba disable XVBA code Individual component options: --disable-everything disable all components listed below @@ -1216,6 +1217,7 @@ vaapi vda vdpau + xvba " LIBRARY_LIST=" @@ -1845,6 +1847,7 @@ dxva2_deps="dxva2api_h" vaapi_deps="va_va_h" vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" +xvba_deps="amd_amdxvba_h" vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore" vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" @@ -1865,6 +1868,8 @@ h264_vdpau_decoder_select="h264_decoder" h264_vdpau_hwaccel_deps="vdpau" h264_vdpau_hwaccel_select="h264_decoder" +h264_xvba_hwaccel_select="h264_decoder" +h264_xvba_hwaccel_deps="xvba" mpeg_vdpau_decoder_deps="vdpau" mpeg_vdpau_decoder_select="mpegvideo_decoder" mpeg1_vdpau_decoder_deps="vdpau" @@ -1877,6 +1882,8 @@ mpeg2_vaapi_hwaccel_deps="vaapi" mpeg2_vaapi_hwaccel_select="mpeg2video_decoder" mpeg2_vdpau_hwaccel_deps="vdpau" +mpeg2_xvba_hwaccel_select="mpeg2video_decoder" +mpeg2_xvba_hwaccel_deps="xvba" mpeg2_vdpau_hwaccel_select="mpeg2video_decoder" mpeg4_crystalhd_decoder_select="crystalhd" mpeg4_vaapi_hwaccel_deps="vaapi" @@ -1895,11 +1902,14 @@ vc1_vdpau_decoder_select="vc1_decoder" vc1_vdpau_hwaccel_deps="vdpau" vc1_vdpau_hwaccel_select="vc1_decoder" +vc1_xvba_hwaccel_select="vc1_decoder" +vc1_xvba_hwaccel_deps="xvba" wmv3_crystalhd_decoder_select="crystalhd" wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel" wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" wmv3_vdpau_decoder_select="vc1_vdpau_decoder" wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel" +wmv3_xvba_hwaccel_select="vc1_xvba_hwaccel" # parsers h264_parser_select="golomb h264chroma h264dsp h264pred h264qpel videodsp" @@ -3853,6 +3863,7 @@ check_header unistd.h check_header vdpau/vdpau.h check_header vdpau/vdpau_x11.h +check_header amd/amdxvba.h check_header VideoDecodeAcceleration/VDADecoder.h check_header windows.h check_header X11/extensions/XvMClib.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index dc065a5..c386923 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -12,6 +12,7 @@ HEADERS = avcodec.h \ vdpau.h \ version.h \ xvmc.h \ + xvba.h \ OBJS = allcodecs.o \ audioconvert.o \ @@ -73,6 +74,7 @@ OBJS-$(CONFIG_SHARED) += log2_tab.o OBJS-$(CONFIG_SINEWIN) += sinewin.o OBJS-$(CONFIG_VAAPI) += vaapi.o OBJS-$(CONFIG_VDPAU) += vdpau.o +OBJS-$(CONFIG_XVBA) += xvba.o OBJS-$(CONFIG_VIDEODSP) += videodsp.o OBJS-$(CONFIG_VP3DSP) += vp3dsp.o @@ -232,6 +234,7 @@ OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o +OBJS-$(CONFIG_H264_XVBA_HWACCEL) += xvba_h264.o OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o OBJS-$(CONFIG_IAC_DECODER) += imc.o @@ -295,6 +298,7 @@ OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o \ OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o +OBJS-$(CONFIG_MPEG2_XVBA_HWACCEL) += xvba_mpeg2.o OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12.o mpeg12data.o OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o \ timecode.o @@ -459,6 +463,7 @@ OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \ OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o +OBJS-$(CONFIG_VC1_XVBA_HWACCEL) += xvba_vc1.o OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdav.o @@ -788,6 +793,7 @@ SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h SKIPHEADERS-$(CONFIG_LIBUTVIDEO) += libutvideo.h SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h +SKIPHEADERS-$(CONFIG_XVBA) += xvba_internal.h SKIPHEADERS-$(CONFIG_VDA) += vda.h SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h SKIPHEADERS-$(HAVE_OS2THREADS) += os2threads.h diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 584446f..7a8f61c 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -79,18 +79,22 @@ void avcodec_register_all(void) REGISTER_HWACCEL(H264_VAAPI, h264_vaapi); REGISTER_HWACCEL(H264_VDA, h264_vda); REGISTER_HWACCEL(H264_VDPAU, h264_vdpau); + REGISTER_HWACCEL(H264_XVBA, h264_xvba); REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau); REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau); + REGISTER_HWACCEL(MPEG2_XVBA, mpeg2_xvba); REGISTER_HWACCEL(MPEG4_VAAPI, mpeg4_vaapi); REGISTER_HWACCEL(MPEG4_VDPAU, mpeg4_vdpau); REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2); REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); + REGISTER_HWACCEL(VC1_XVBA, vc1_xvba); REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi); REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau); + REGISTER_HWACCEL(WMV3_XVBA, wmv3_xvba); /* video codecs */ REGISTER_ENCODER(A64MULTI, a64multi); diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 3a83b4b..96b6c30 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -81,6 +81,9 @@ static const enum AVPixelFormat h264_hwaccel_pixfmt_list_420[] = { #if CONFIG_H264_VDPAU_HWACCEL AV_PIX_FMT_VDPAU, #endif +#if CONFIG_H264_XVBA_HWACCEL + AV_PIX_FMT_XVBA_VLD, +#endif AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }; diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 2130c74..4d611f9 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -5807,6 +5807,9 @@ static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = { #if CONFIG_VDPAU AV_PIX_FMT_VDPAU, #endif +#if CONFIG_XVBA + AV_PIX_FMT_XVBA_VLD, +#endif AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }; diff --git a/libavcodec/xvba.c b/libavcodec/xvba.c new file mode 100644 index 0000000..c6ff2fe --- /dev/null +++ b/libavcodec/xvba.c @@ -0,0 +1,77 @@ +/* + * HW decode acceleration for MPEG-2, H.264 and VC-1 + * + * Copyright (C) 2005-2011 Team XBMC + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +/** + * \addtogroup XVBA_Decoding + * + * @{ + */ + +#include <stdint.h> +#include "xvba.h" +#include "xvba_internal.h" +#include "avcodec.h" +#include "mpegvideo.h" + +int ff_xvba_translate_profile(int profile) { + + if (profile == 66) + return 1; + else if (profile == 77) + return 2; + else if (profile == 100) + return 3; + else if (profile == 0) + return 4; + else if (profile == 1) + return 5; + else if (profile == 3) + return 6; + else + return -1; +} + +// See page 25 of the documentation +int ff_xvba_translate_picture_structure(int picture_structure) { + if(picture_structure == PICT_BOTTOM_FIELD) + return 0; + else if (picture_structure == PICT_TOP_FIELD) + return 1; + else //PICT_FRAME by default + return 3; +} + +void ff_xvba_add_slice_data(struct xvba_render_state *render, const uint8_t *buffer, uint32_t size) { + + render->buffers = av_fast_realloc( + render->buffers, + &render->buffers_alllocated, + sizeof(struct xvba_bitstream_buffers)*(render->num_slices + 1) + ); + + render->buffers[render->num_slices].buffer = buffer; + render->buffers[render->num_slices].size = size; + + render->num_slices++; +} + diff --git a/libavcodec/xvba.h b/libavcodec/xvba.h new file mode 100644 index 0000000..e590faf --- /dev/null +++ b/libavcodec/xvba.h @@ -0,0 +1,72 @@ +/* + * HW decode acceleration for MPEG-2, H.264 and VC-1 + * + * Copyright (C) 2005-2011 Team XBMC + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General 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_XVBA_H +#define AVCODEC_XVBA_H + +#include <stdint.h> +#include <X11/Xlib.h> +#include <amd/amdxvba.h> + + +/** + * \defgroup XVBA_Decoding VA API Decoding + * \ingroup Decoder + * @{ + */ + +/** \brief The videoSurface is used for rendering. */ +#define FF_XVBA_STATE_USED_FOR_RENDER 1 + +/** + * \brief The videoSurface is needed for reference/prediction. + * The codec manipulates this. + */ +#define FF_XVBA_STATE_USED_FOR_REFERENCE 2 + +/** + * \brief The videoSurface holds a decoded frame. + * The codec manipulates this. + */ +#define FF_XVBA_STATE_DECODED 4 + +/* @} */ + +struct xvba_bitstream_buffers +{ + const void *buffer; + unsigned int size; +}; + +struct xvba_render_state { + + int state; ///< Holds FF_XVBA_STATE_* values. + void *surface; + XVBAPictureDescriptor *picture_descriptor; + XVBAQuantMatrixAvc *iq_matrix; + unsigned int num_slices; + struct xvba_bitstream_buffers *buffers; + uint32_t buffers_alllocated; + int psf; +}; + +#endif /* AVCODEC_XVBA_H */ diff --git a/libavcodec/xvba_h264.c b/libavcodec/xvba_h264.c new file mode 100644 index 0000000..20ba2f2 --- /dev/null +++ b/libavcodec/xvba_h264.c @@ -0,0 +1,194 @@ +/* + * H.264 HW decode acceleration through XVBA + * + * Copyright (C) 2005-2011 Team XBMC + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General 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 "xvba.h" +#include "xvba_internal.h" +#include "h264.h" +#include <assert.h> + +/** @file + * This file implements the glue code between FFmpeg's and XvBA API's + * structures for H.264 decoding. + */ + + +/** Initialize and start decoding a frame with XVBA. */ +static int start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + H264Context * const h = avctx->priv_data; + struct xvba_render_state *render; + XVBAPictureDescriptor *pic_descriptor; + int i; + + render = (struct xvba_render_state *)h->cur_pic_ptr->f.data[0]; + assert(render); + + if (render->picture_descriptor == 0) + return -1; + + pic_descriptor = render->picture_descriptor; + + for (i = 0; i < 2; ++i) { + int foc = h->cur_pic_ptr->field_poc[i]; + if (foc == INT_MAX) + foc = 0; + pic_descriptor->avc_curr_field_order_cnt_list[i] = foc; + } + + pic_descriptor->avc_frame_num = h->frame_num; + + render->num_slices = 0; + + return 0; +} + +/** End a hardware decoding based frame. */ +static int end_frame(AVCodecContext *avctx) +{ + H264Context * const h = avctx->priv_data; + struct xvba_render_state *render; + XVBAPictureDescriptor *pic_descriptor; + XVBAQuantMatrixAvc *iq_matrix; + + render = (struct xvba_render_state *)h->cur_pic_ptr->f.data[0]; + assert(render); + + if (render->picture_descriptor == 0 || render->iq_matrix == 0) + return -1; + + pic_descriptor = render->picture_descriptor; + iq_matrix = render->iq_matrix; + + av_dlog(avctx, "end_frame()\n"); + + /* Fill in Picture Parameters*/ + pic_descriptor->profile = ff_xvba_translate_profile(avctx->profile); + pic_descriptor->level = avctx->level; + pic_descriptor->width_in_mb = h->mb_width; + pic_descriptor->height_in_mb = h->mb_height; + + pic_descriptor->picture_structure = ff_xvba_translate_picture_structure(h->picture_structure); + + pic_descriptor->chroma_format = h->chroma_format_idc ? h->chroma_format_idc : 1; + pic_descriptor->avc_intra_flag = (h->slice_type == AV_PICTURE_TYPE_I) ? 1 : 0; + pic_descriptor->avc_reference = (h->cur_pic_ptr->f.reference & 3) ? 1 : 0; + + pic_descriptor->avc_bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8; + pic_descriptor->avc_bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8; + pic_descriptor->avc_log2_max_frame_num_minus4 = h->sps.log2_max_frame_num -4; + pic_descriptor->avc_pic_order_cnt_type = h->sps.poc_type; + pic_descriptor->avc_log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4; + pic_descriptor->avc_num_ref_frames = h->sps.ref_frame_count; + pic_descriptor->avc_reserved_8bit = 0; + + /* Set a level that can decode stuff in every case without a lookup table + xvba seems to have problems only when the number of Reframes goes beyond + the max support number of Level4.1@High. So in praxis decoding a Level 3.0 + file that in deed has level4.1@High specs does not matter. We use this fact + and check if the ref_frames stay in the range Level4.1@high can decode if + not, we set Level5.1 */ + if (pic_descriptor->avc_num_ref_frames > 4) { + const unsigned int mbw = pic_descriptor->width_in_mb; + const unsigned int mbh = pic_descriptor->height_in_mb; + // this matches Level4.1@High stats to differ between <= 4.1 and 5.1 + const unsigned int max_ref_frames = 12288 * 1024 / (mbw * mbh * 384); + const unsigned int num_ref_frames = pic_descriptor->avc_num_ref_frames; + if (max_ref_frames < num_ref_frames) + pic_descriptor->level = 51; + } + + pic_descriptor->avc_num_slice_groups_minus1 = h->pps.slice_group_count - 1; + pic_descriptor->avc_num_ref_idx_l0_active_minus1 = h->pps.ref_count[0] - 1; + pic_descriptor->avc_num_ref_idx_l1_active_minus1 = h->pps.ref_count[1] - 1; + + pic_descriptor->avc_pic_init_qp_minus26 = h->pps.init_qp - 26; + pic_descriptor->avc_pic_init_qs_minus26 = h->pps.init_qs - 26; + pic_descriptor->avc_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0]; + pic_descriptor->avc_second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1]; + pic_descriptor->avc_slice_group_change_rate_minus1 = 0; // not implemented in ffmpeg + pic_descriptor->avc_reserved_16bit = 0; // must be 0 + memset(pic_descriptor->avc_field_order_cnt_list,0,sizeof(pic_descriptor->avc_field_order_cnt_list)); // must be 0 + memset(pic_descriptor->avc_slice_group_map,0,sizeof(pic_descriptor->avc_slice_group_map)); // must be 0 + + // sps + pic_descriptor->sps_info.avc.delta_pic_always_zero_flag = h->sps.delta_pic_order_always_zero_flag; + pic_descriptor->sps_info.avc.direct_8x8_inference_flag = h->sps.direct_8x8_inference_flag; + pic_descriptor->sps_info.avc.frame_mbs_only_flag = h->sps.frame_mbs_only_flag; + pic_descriptor->sps_info.avc.gaps_in_frame_num_value_allowed_flag = h->sps.gaps_in_frame_num_allowed_flag; + pic_descriptor->sps_info.avc.mb_adaptive_frame_field_flag = h->sps.mb_aff; + pic_descriptor->sps_info.avc.residual_colour_transform_flag = h->sps.residual_color_transform_flag; + pic_descriptor->sps_info.avc.xvba_avc_sps_reserved = 0; + + // pps + pic_descriptor->pps_info.avc.entropy_coding_mode_flag = h->pps.cabac; + pic_descriptor->pps_info.avc.pic_order_present_flag = h->pps.pic_order_present; + pic_descriptor->pps_info.avc.weighted_pred_flag = h->pps.weighted_pred; + pic_descriptor->pps_info.avc.weighted_bipred_idc = h->pps.weighted_bipred_idc; + pic_descriptor->pps_info.avc.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present; + pic_descriptor->pps_info.avc.constrained_intra_pred_flag = h->pps.constrained_intra_pred; + pic_descriptor->pps_info.avc.redundant_pic_cnt_present_flag = h->pps.redundant_pic_cnt_present; + pic_descriptor->pps_info.avc.transform_8x8_mode_flag = h->pps.transform_8x8_mode; + pic_descriptor->pps_info.avc.xvba_avc_pps_reserved = 0; // must be 0 + + memcpy(iq_matrix->bScalingLists4x4, h->pps.scaling_matrix4, sizeof(iq_matrix->bScalingLists4x4)); + memcpy(iq_matrix->bScalingLists8x8[0], h->pps.scaling_matrix8[0], sizeof(iq_matrix->bScalingLists8x8[0])); + memcpy(iq_matrix->bScalingLists8x8[1], h->pps.scaling_matrix8[3], sizeof(iq_matrix->bScalingLists8x8[0])); + + // Wait for an I-frame before start decoding. Workaround for ATI UVD and UVD+ GPUs + if (!h->got_first_iframe) { + if (h->slice_type != AV_PICTURE_TYPE_I && h->slice_type != AV_PICTURE_TYPE_SI) + return -1; + h->got_first_iframe = 1; + } + + ff_h264_draw_horiz_band(h, 0, h->avctx->height); + + return 0; +} + +/** Decode the given H.264 slice with XVBA. */ +static int decode_slice(AVCodecContext *avctx, + const uint8_t *buffer, + uint32_t size) +{ + H264Context * const h = avctx->priv_data; + struct xvba_render_state *render; + + render = (struct xvba_render_state *)h->cur_pic_ptr->f.data[0]; + assert(render); + + ff_xvba_add_slice_data(render, buffer, size); + + return 0; +} + +AVHWAccel ff_h264_xvba_hwaccel = { + .name = "h264_xvba", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_H264, + .pix_fmt = AV_PIX_FMT_XVBA_VLD, + .start_frame = start_frame, + .end_frame = end_frame, + .decode_slice = decode_slice, +}; diff --git a/libavcodec/xvba_internal.h b/libavcodec/xvba_internal.h new file mode 100644 index 0000000..18faa3e --- /dev/null +++ b/libavcodec/xvba_internal.h @@ -0,0 +1,25 @@ +/* + * HW decode acceleration for MPEG-2, H.264 and VC-1 + * + * Copyright (C) 2005-2011 Team XBMC + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +int ff_xvba_translate_profile(int profile); +int ff_xvba_translate_picture_structure(int picture_structure); +void ff_xvba_add_slice_data(struct xvba_render_state *render, const uint8_t *buffer, uint32_t size); diff --git a/libavcodec/xvba_mpeg2.c b/libavcodec/xvba_mpeg2.c new file mode 100644 index 0000000..0fc7d78 --- /dev/null +++ b/libavcodec/xvba_mpeg2.c @@ -0,0 +1,52 @@ +/* + * MPEG-2 HW decode acceleration through XVBA + * + * Copyright (C) 2005-2011 Team XBMC + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General 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 "dsputil.h" + +static int start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) +{ + struct MpegEncContext * const s = avctx->priv_data; + return 0; +} + +static int end_frame(AVCodecContext *avctx) +{ + return 0; +} + +static int decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + struct MpegEncContext * const s = avctx->priv_data; + return 0; +} + +AVHWAccel ff_mpeg2_xvba_hwaccel = { + .name = "mpeg2_xvba", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG2VIDEO, + .pix_fmt = AV_PIX_FMT_XVBA_VLD, + .capabilities = 0, + .start_frame = start_frame, + .end_frame = end_frame, + .decode_slice = decode_slice, + .priv_data_size = 0, +}; diff --git a/libavcodec/xvba_vc1.c b/libavcodec/xvba_vc1.c new file mode 100644 index 0000000..e7a85a7 --- /dev/null +++ b/libavcodec/xvba_vc1.c @@ -0,0 +1,193 @@ +/* + * VC-1 HW decode acceleration through XVBA + * + * Copyright (C) 2005-2011 Team XBMC + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General 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 "xvba.h" +#include "xvba_internal.h" +#include "vc1.h" +#include "vc1data.h" +#include <assert.h> + + +/** @file + * Implement structures of ffmpeg <-> XvBA + */ + +/* Initialize and start decoding a frame with XvBA */ +static int start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + VC1Context * const v = avctx->priv_data; + MpegEncContext * const s = &v->s; + struct xvba_render_state *render; + + render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; + assert(render); + + render->num_slices = 0; + return 0; +} + +/* End a hardware decoding based frame */ +static int end_frame(AVCodecContext *avctx) +{ + VC1Context* const v = avctx->priv_data; + MpegEncContext* const s = &v->s; + struct xvba_render_state *render, *last, *next; + XVBAPictureDescriptor *pic_descriptor; + + render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; + assert(render); + + if (render->picture_descriptor == 0) + return -1; + + pic_descriptor = render->picture_descriptor; + + av_dlog(avctx, "xvba_vc1_end_frame()\n"); + + memset(pic_descriptor, 0, sizeof(*pic_descriptor)); + + /* Fill in Parameters - for reference see AMD sdk documentation */ + pic_descriptor->profile = ff_xvba_translate_profile(v->profile); + pic_descriptor->level = v->level; + //done like in va-driver and vaapi + if (v->profile == PROFILE_ADVANCED) { + pic_descriptor->width_in_mb = s->avctx->coded_width; + pic_descriptor->height_in_mb = s->avctx->coded_height; + } else { + pic_descriptor->width_in_mb = s->mb_width; + pic_descriptor->height_in_mb = s->mb_height; + } + + pic_descriptor->picture_structure = ff_xvba_translate_picture_structure(s->picture_structure); + + // xvba-video set this to 1 only 4:2:0 supported + // doc says: if not set, choose 1 - we try this + pic_descriptor->chroma_format = 1; + pic_descriptor->avc_intra_flag = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type == 1; + pic_descriptor->avc_reference = (s->current_picture_ptr->f.reference & 3) ? 1 : 0; + + // VC-1 explicit parameters see page 30 of sdk + // sps_info + pic_descriptor->sps_info.vc1.postprocflag = v->postprocflag; + + // done as in vaapi + pic_descriptor->sps_info.vc1.pulldown = v->broadcast; + pic_descriptor->sps_info.vc1.interlace = v->interlace; + pic_descriptor->sps_info.vc1.tfcntrflag = v->tfcntrflag; + pic_descriptor->sps_info.vc1.finterpflag = v->finterpflag; + pic_descriptor->sps_info.vc1.reserved = 1; + // eventually check if this makes sense together with interlace + pic_descriptor->sps_info.vc1.psf = v->psf; + // what about if it is a frame (page 31) + // looked at xvba-driver + pic_descriptor->sps_info.vc1.second_field = v->interlace && v->second_field && (v->fcm == ILACE_FIELD); + pic_descriptor->sps_info.vc1.xvba_vc1_sps_reserved = 0; + + // VC-1 explicit parameters see page 30 of sdk + // pps_info + pic_descriptor->pps_info.vc1.panscan_flag = v->panscanflag; + pic_descriptor->pps_info.vc1.refdist_flag = v->refdist_flag; + pic_descriptor->pps_info.vc1.loopfilter = s->loop_filter; + pic_descriptor->pps_info.vc1.fastuvmc = v->fastuvmc; + pic_descriptor->pps_info.vc1.extended_mv = v->extended_mv; + pic_descriptor->pps_info.vc1.dquant = v->dquant; + pic_descriptor->pps_info.vc1.vstransform = v->vstransform; + pic_descriptor->pps_info.vc1.overlap = v->overlap; + pic_descriptor->pps_info.vc1.quantizer = v->quantizer_mode; + pic_descriptor->pps_info.vc1.extended_dmv = v->extended_dmv; + pic_descriptor->pps_info.vc1.maxbframes = s->avctx->max_b_frames; + pic_descriptor->pps_info.vc1.rangered = (pic_descriptor->profile == PROFILE_SIMPLE) ? 0 : v->rangered; + pic_descriptor->pps_info.vc1.syncmarker = (pic_descriptor->profile == PROFILE_SIMPLE) ? 0 : s->resync_marker; + pic_descriptor->pps_info.vc1.multires = v->multires; + pic_descriptor->pps_info.vc1.reserved = 1; + pic_descriptor->pps_info.vc1.range_mapy_flag = v->range_mapy_flag; + pic_descriptor->pps_info.vc1.range_mapy = v->range_mapy; + pic_descriptor->pps_info.vc1.range_mapuv_flag = v->range_mapuv_flag; + pic_descriptor->pps_info.vc1.range_mapuv = v->range_mapuv; + pic_descriptor->pps_info.vc1.xvba_vc1_pps_reserved = 0; + + pic_descriptor->past_surface = 0; + pic_descriptor->future_surface = 0; + switch (s->pict_type) { + case AV_PICTURE_TYPE_B: + next = (struct xvba_render_state *)s->next_picture.f.data[0]; + assert(next); + if (next) + pic_descriptor->past_surface = next->surface; + // fall-through + case AV_PICTURE_TYPE_P: + last = (struct xvba_render_state *)s->last_picture.f.data[0]; + assert(last); + if (last) + pic_descriptor->future_surface = last->surface; + break; + } + render->psf = v->psf; + + ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); + + return 0; +} + +static int decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + VC1Context* const v = avctx->priv_data; + MpegEncContext* const s = &v->s; + struct xvba_render_state *render; + + render = (struct xvba_render_state *)s->current_picture_ptr->f.data[0]; + assert(render); + + if (avctx->codec_id == CODEC_ID_VC1 && + size >= 4 && IS_MARKER(AV_RB32(buffer))) { + buffer += 4; + size -= 4; + } + + ff_xvba_add_slice_data(render, buffer, size); + + return 0; +} + +#if CONFIG_WMV3_XVBA_HWACCEL +AVHWAccel ff_wmv3_xvba_hwaccel = { + .name = "wmv3_xvba", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_WMV3, + .pix_fmt = AV_PIX_FMT_XVBA_VLD, + .start_frame = start_frame, + .end_frame = end_frame, + .decode_slice = decode_slice, +}; +#endif + +AVHWAccel ff_vc1_xvba_hwaccel = { + .name = "vc1_xvba", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_VC1, + .pix_fmt = AV_PIX_FMT_XVBA_VLD, + .start_frame = start_frame, + .end_frame = end_frame, + .decode_slice = decode_slice, +}; diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 1016dba..53dfec1 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1141,6 +1141,12 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .log2_chroma_h = 1, .flags = PIX_FMT_HWACCEL, }, + [AV_PIX_FMT_XVBA_VLD] = { + .name = "xvba_vld", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = PIX_FMT_HWACCEL, + }, [AV_PIX_FMT_YUV420P9LE] = { .name = "yuv420p9le", .nb_components = 3, diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 1c00ac4..6437e29 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -124,6 +124,7 @@ enum AVPixelFormat { AV_PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers AV_PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers AV_PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + AV_PIX_FMT_XVBA_VLD, ///< HW decoding through xvba, Picture.data[3] contains a xvba_rander_state struct which contains the bitstream of the slices AV_PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian AV_PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.