rendered paste bodydiff --git a/mythtv/configure b/mythtv/configure
index facea94..37c3942 100755
--- a/mythtv/configure
+++ b/mythtv/configure
@@ -1000,6 +1000,7 @@ HAVE_LIST="
termios_h
threads
winsock2_h
+ vdpau
yasm
"
@@ -1121,13 +1122,17 @@ dxa_decoder_deps="zlib"
eac3_decoder_deps="gpl"
flashsv_decoder_deps="zlib"
flashsv_encoder_deps="zlib"
+h264_vdpau_decoder_deps="vdpau"
mlp_decoder_deps="mlp_parser"
mpeg_dvdv_decoder_deps="dvdv"
+mpeg_vdpau_decoder_deps="vdpau"
mpeg_xvmc_decoder_deps="xvmc"
mpeg_xvmc_vld_decoder_deps="xvmc_vld"
png_decoder_deps="zlib"
png_encoder_deps="zlib"
snow_decoder_deps="disabled_in_mythtv"
+vc1_vdpau_decoder_deps="vdpau"
+wmv3_vdpau_decoder_deps="vdpau"
zmbv_decoder_deps="zlib"
zmbv_encoder_deps="zlib"
@@ -1214,6 +1219,7 @@ opengl_video_deps="opengl xv"
opengl_vsync_deps="opengl"
qtwebkit_deps="QtWebKit_QWebView"
v4l_deps="backend"
+vdpau_deps="vdpau_vdpau_h"
xrandr_deps="x11"
xv_deps="x11"
xvmc_deps="xv X11_extensions_XvMClib_h"
@@ -1327,6 +1333,7 @@ enable mheg
enable opengl
enable qtwebkit
enable v4l
+enable vdpau
enable x11
enable xrandr
enable xv
@@ -3011,6 +3018,7 @@ fi
enabled xvmc_pro && enable xvmc_vld
+check_header vdpau/vdpau.h
# Can only do Mac accel on Mac platform
enabled dvdv && test $target_os = darwin || disable dvdv
diff --git a/mythtv/libs/libavcodec/allcodecs.c b/mythtv/libs/libavcodec/allcodecs.c
index 393646b..45c59f7 100644
--- a/mythtv/libs/libavcodec/allcodecs.c
+++ b/mythtv/libs/libavcodec/allcodecs.c
@@ -97,6 +97,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (H263I, h263i);
REGISTER_ENCODER (H263P, h263p);
REGISTER_DECODER (H264, h264);
+ REGISTER_DECODER (H264_VDPAU, h264_vdpau);
REGISTER_ENCDEC (HUFFYUV, huffyuv);
REGISTER_DECODER (IDCIN, idcin);
REGISTER_DECODER (INDEO2, indeo2);
@@ -113,6 +114,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (MMVIDEO, mmvideo);
REGISTER_DECODER (MOTIONPIXELS, motionpixels);
REGISTER_DECODER (MPEG_DVDV, mpeg_dvdv);
+ REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau);
REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc);
REGISTER_DECODER (MPEG_XVMC_VLD, mpeg_xvmc_vld);
REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video);
@@ -163,6 +165,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (ULTI, ulti);
REGISTER_DECODER (VB, vb);
REGISTER_DECODER (VC1, vc1);
+ REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
REGISTER_DECODER (VCR1, vcr1);
REGISTER_DECODER (VMDVIDEO, vmdvideo);
REGISTER_DECODER (VMNC, vmnc);
@@ -175,6 +178,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (WMV1, wmv1);
REGISTER_ENCDEC (WMV2, wmv2);
REGISTER_DECODER (WMV3, wmv3);
+ REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);
REGISTER_DECODER (WNV1, wnv1);
REGISTER_DECODER (XAN_WC3, xan_wc3);
REGISTER_DECODER (XL, xl);
diff --git a/mythtv/libs/libavcodec/avcodec.h b/mythtv/libs/libavcodec/avcodec.h
index 673c3fe..c37e544 100644
--- a/mythtv/libs/libavcodec/avcodec.h
+++ b/mythtv/libs/libavcodec/avcodec.h
@@ -191,6 +191,10 @@ enum CodecID {
CODEC_ID_CMV,
CODEC_ID_MOTIONPIXELS,
CODEC_ID_TGV,
+ CODEC_ID_MPEGVIDEO_VDPAU,
+ CODEC_ID_H264_VDPAU,
+ CODEC_ID_VC1_VDPAU,
+ CODEC_ID_WMV3_VDPAU,
/* various PCM "codecs" */
CODEC_ID_PCM_S16LE= 0x10000,
@@ -514,6 +518,8 @@ typedef struct RcOverride{
* This can be used to prevent truncation of the last audio samples.
*/
#define CODEC_CAP_SMALL_LAST_FRAME 0x0040
+/* Codec can export data for HW decoding (VDPAU). */
+#define CODEC_CAP_HWACCEL_VDPAU 0x0080
//The following defines may change, don't expect compatibility if you use them.
#define MB_TYPE_INTRA4x4 0x0001
@@ -1761,6 +1767,13 @@ typedef struct AVCodecContext {
int xvmc_acceleration;
/**
+ * VDPAU Acceleration
+ * - encoding: forbidden
+ * - decoding: set by decoder
+ */
+ int vdpau_acceleration;
+
+ /**
* macroblock decision mode
* - encoding: Set by user.
* - decoding: unused
diff --git a/mythtv/libs/libavcodec/h263dec.c b/mythtv/libs/libavcodec/h263dec.c
index de1f146..f5c496c 100644
--- a/mythtv/libs/libavcodec/h263dec.c
+++ b/mythtv/libs/libavcodec/h263dec.c
@@ -92,6 +92,8 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
break;
case CODEC_ID_VC1:
case CODEC_ID_WMV3:
+ case CODEC_ID_VC1_VDPAU:
+ case CODEC_ID_WMV3_VDPAU:
s->h263_msmpeg4 = 1;
s->h263_pred = 1;
s->msmpeg4_version=6;
diff --git a/mythtv/libs/libavcodec/h264.c b/mythtv/libs/libavcodec/h264.c
index 9777851..d49ca5b 100644
--- a/mythtv/libs/libavcodec/h264.c
+++ b/mythtv/libs/libavcodec/h264.c
@@ -72,6 +72,10 @@ static VLC run7_vlc;
static VLC_TYPE run7_vlc_table[96][2];
static const int run7_vlc_table_size = 96;
+extern int VDPAU_h264_set_reference_frames(H264Context *h);
+extern int VDPAU_h264_picture_complete(H264Context *h, const uint8_t *buf, int buf_size);
+extern void VDPAU_h264_set_reference_frames_count(H264Context *h);
+
static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp);
static void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc);
static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize);
@@ -101,6 +105,16 @@ static const int left_block_options[4][8]={
{0,2,0,2,7,10,7,10}
};
+static const enum PixelFormat pixfmt_vdpau_h264_baseline_420[] = {
+ PIX_FMT_VDPAU_H264_BASELINE,
+ PIX_FMT_NONE};
+static const enum PixelFormat pixfmt_vdpau_h264_main_420[] = {
+ PIX_FMT_VDPAU_H264_MAIN,
+ PIX_FMT_NONE};
+static const enum PixelFormat pixfmt_vdpau_h264_high_420[] = {
+ PIX_FMT_VDPAU_H264_HIGH,
+ PIX_FMT_NONE};
+
static void fill_caches(H264Context *h, int mb_type, int for_deblock){
MpegEncContext * const s = &h->s;
const int mb_xy= h->mb_xy;
@@ -2198,10 +2212,8 @@ static av_cold int decode_init(AVCodecContext *avctx){
s->quarter_sample = 1;
s->low_delay= 1;
- if(avctx->codec_id == CODEC_ID_SVQ3)
- avctx->pix_fmt= PIX_FMT_YUVJ420P;
- else
- avctx->pix_fmt= PIX_FMT_YUV420P;
+ // Set in decode_postinit() once initial parsing is complete
+ avctx->pix_fmt = PIX_FMT_NONE;
decode_init_vlc();
@@ -2219,10 +2231,43 @@ static av_cold int decode_init(AVCodecContext *avctx){
return 0;
}
+static int decode_postinit(H264Context *h, SPS *sps){
+ AVCodecContext * const avctx= h->s.avctx;
+
+ if (avctx->pix_fmt != PIX_FMT_NONE){
+ return 0;
+ }
+
+ if (avctx->vdpau_acceleration) {
+ if(h->s.chroma_format >= 2) {
+ return -2;
+ }
+ if (sps->profile_idc == 66) {
+ avctx->pix_fmt = avctx->get_format(avctx, pixfmt_vdpau_h264_baseline_420);
+ } else if (sps->profile_idc == 77) {
+ avctx->pix_fmt = avctx->get_format(avctx, pixfmt_vdpau_h264_main_420);
+ } else if (sps->profile_idc == 100) {
+ avctx->pix_fmt = avctx->get_format(avctx, pixfmt_vdpau_h264_high_420);
+ } else {
+ return -2;
+ }
+ } else if (avctx->codec_id == CODEC_ID_SVQ3) {
+ avctx->pix_fmt= PIX_FMT_YUVJ420P;
+ } else {
+ avctx->pix_fmt= PIX_FMT_YUV420P;
+ }
+
+ return 0;
+}
+
static int frame_start(H264Context *h){
MpegEncContext * const s = &h->s;
int i;
+#ifdef HAVE_VDPAU
+ VDPAU_h264_set_reference_frames_count(h);
+#endif
+
if(MPV_frame_start(s, s->avctx) < 0)
return -1;
ff_er_frame_start(s);
@@ -7102,6 +7147,10 @@ static inline int decode_seq_parameter_set(H264Context *h){
((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc]
);
}
+
+ if (decode_postinit(h, sps) < 0)
+ return -1;
+
return 0;
}
@@ -7234,7 +7283,9 @@ static void execute_decode_slices(H264Context *h, int context_count){
H264Context *hx;
int i;
- if(context_count == 1) {
+ if(avctx->vdpau_acceleration) {
+ return;
+ } else if(context_count == 1) {
decode_slice(avctx, h);
} else {
for(i = 1; i < context_count; i++) {
@@ -7558,12 +7609,25 @@ static int decode_frame(AVCodecContext *avctx,
h->prev_frame_num_offset= h->frame_num_offset;
h->prev_frame_num= h->frame_num;
+
+#ifdef HAVE_VDPAU
+ if (avctx->vdpau_acceleration) {
+ VDPAU_h264_set_reference_frames(h);
+ }
+#endif
+
if(!s->dropable) {
h->prev_poc_msb= h->poc_msb;
h->prev_poc_lsb= h->poc_lsb;
execute_ref_pic_marking(h, h->mmco, h->mmco_index);
}
+#ifdef HAVE_VDPAU
+ if (avctx->vdpau_acceleration) {
+ VDPAU_h264_picture_complete(h, buf, buf_size);
+ }
+#endif
+
/*
* FIXME: Error handling code does not seem to support interlaced
* when slices span multiple rows
@@ -7576,8 +7640,11 @@ static int decode_frame(AVCodecContext *avctx,
* past end by one (callers fault) and resync_mb_y != 0
* causes problems for the first MB line, too.
*/
- if (!FIELD_PICTURE)
- ff_er_frame_end(s);
+#ifdef HAVE_VDPAU
+ if (!avctx->vdpau_acceleration)
+#endif
+ if (!FIELD_PICTURE)
+ ff_er_frame_end(s);
MPV_frame_end(s);
@@ -7890,4 +7957,35 @@ AVCodec h264_decoder = {
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
};
+#ifdef HAVE_VDPAU
+static av_cold int h264_vdpau_decode_init(AVCodecContext *avctx){
+ if( avctx->thread_count > 1)
+ return -1;
+ if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) )
+ return -1;
+ if( !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD) ){
+ dprintf(avctx, "h264.c: VDPAU decoder does not set SLICE_FLAG_ALLOW_FIELD\n");
+ }
+ decode_init(avctx);
+
+ avctx->vdpau_acceleration = 1;
+
+ return 0;
+}
+
+AVCodec h264_vdpau_decoder = {
+ "h264_vdpau",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_H264_VDPAU,
+ sizeof(H264Context),
+ h264_vdpau_decode_init,
+ NULL,
+ decode_end,
+ decode_frame,
+ CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
+ .flush= flush_dpb,
+ .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"),
+};
+#endif
+
#include "svq3.c"
diff --git a/mythtv/libs/libavcodec/imgconvert.c b/mythtv/libs/libavcodec/imgconvert.c
index 63c59d4..80df7f6 100644
--- a/mythtv/libs/libavcodec/imgconvert.c
+++ b/mythtv/libs/libavcodec/imgconvert.c
@@ -266,6 +266,33 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
[PIX_FMT_XVMC_MPEG2_IDCT] = {
.name = "xvmcidct",
},
+ [PIX_FMT_VDPAU_MPEG1] = {
+ .name = "vdpau_mpeg1",
+ },
+ [PIX_FMT_VDPAU_MPEG2_SIMPLE] = {
+ .name = "vdpau_mpeg2_simple",
+ },
+ [PIX_FMT_VDPAU_MPEG2_MAIN] = {
+ .name = "vdpau_mpeg2_main",
+ },
+ [PIX_FMT_VDPAU_H264_BASELINE] = {
+ .name = "vdpau_h264_baseline",
+ },
+ [PIX_FMT_VDPAU_H264_MAIN] = {
+ .name = "vdpau_h264_main",
+ },
+ [PIX_FMT_VDPAU_H264_HIGH] = {
+ .name = "vdpau_h264_high",
+ },
+ [PIX_FMT_VDPAU_VC1_SIMPLE] = {
+ .name = "vdpau_vc1_simple",
+ },
+ [PIX_FMT_VDPAU_VC1_MAIN] = {
+ .name = "vdpau_vc1_main",
+ },
+ [PIX_FMT_VDPAU_VC1_ADVANCED] = {
+ .name = "vdpau_vc1_advanced",
+ },
[PIX_FMT_UYYVYY411] = {
.name = "uyyvyy411",
.nb_channels = 1,
diff --git a/mythtv/libs/libavcodec/libavcodec.pro b/mythtv/libs/libavcodec/libavcodec.pro
index 13d1e2b..55222ce 100644
--- a/mythtv/libs/libavcodec/libavcodec.pro
+++ b/mythtv/libs/libavcodec/libavcodec.pro
@@ -421,6 +421,8 @@ using_dvdv {
DEFINES += HAVE_DVDV
}
+contains( HAVE_VDPAU, yes ) { SOURCES *= vdpauvideo.c }
+
!contains( CONFIG_SWSCALER, yes ) { SOURCES *= imgresample.c }
contains( HAVE_GPROF, yes ) {
diff --git a/mythtv/libs/libavcodec/mpeg12.c b/mythtv/libs/libavcodec/mpeg12.c
index 19ee213..d55bd21 100644
--- a/mythtv/libs/libavcodec/mpeg12.c
+++ b/mythtv/libs/libavcodec/mpeg12.c
@@ -84,10 +84,22 @@ extern void DVDV_init_block(MpegEncContext *s);
extern void DVDV_decode_mb(MpegEncContext *s);
#endif
+extern int VDPAU_mpeg_field_start(MpegEncContext *s);
+extern void VDPAU_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, int buf_size, int slice_count);
+
static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = {
PIX_FMT_XVMC_MPEG2_IDCT,
PIX_FMT_XVMC_MPEG2_MC,
PIX_FMT_NONE};
+static const enum PixelFormat pixfmt_vdpau_mpg1_420[] = {
+ PIX_FMT_VDPAU_MPEG1,
+ PIX_FMT_NONE};
+static const enum PixelFormat pixfmt_vdpau_mpg2simple_420[] = {
+ PIX_FMT_VDPAU_MPEG2_SIMPLE,
+ PIX_FMT_NONE};
+static const enum PixelFormat pixfmt_vdpau_mpg2main_420[] = {
+ PIX_FMT_VDPAU_MPEG2_MAIN,
+ PIX_FMT_NONE};
uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
@@ -1431,7 +1443,23 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){
}
}//MPEG-2
- if(avctx->xvmc_acceleration){
+ if(avctx->vdpau_acceleration){
+ if(s->chroma_format >= 2){
+ return -2;
+ }
+ if(avctx->sub_id == 1){
+ avctx->pix_fmt = avctx->get_format(avctx,pixfmt_vdpau_mpg1_420);
+ }else{
+ if(avctx->profile == 5){
+ avctx->pix_fmt = avctx->get_format(avctx,pixfmt_vdpau_mpg2simple_420);
+ }else
+ if(avctx->profile == 4){
+ avctx->pix_fmt = avctx->get_format(avctx,pixfmt_vdpau_mpg2main_420);
+ }else{
+ return -2;
+ }
+ }
+ }else if(avctx->xvmc_acceleration){
avctx->pix_fmt = avctx->get_format(avctx,pixfmt_xvmc_mpg2_420);
}else{
if(s->chroma_format < 2){
@@ -1788,6 +1816,11 @@ static int mpeg_field_start(MpegEncContext *s){
XVMC_VLD_field_start(s, avctx);
#endif
+#ifdef HAVE_VDPAU
+ if(s->avctx->vdpau_acceleration)
+ VDPAU_mpeg_field_start(s);
+#endif
+
return 0;
}
@@ -2090,7 +2123,10 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_MPEG2;
- ff_er_frame_end(s);
+#ifdef HAVE_VDPAU
+ if(!s->avctx->vdpau_acceleration)
+#endif
+ ff_er_frame_end(s);
MPV_frame_end(s);
@@ -2237,7 +2273,23 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
avctx->has_b_frames= 0; //true?
s->low_delay= 1;
- if(avctx->xvmc_acceleration){
+ if(avctx->vdpau_acceleration){
+ if(s->chroma_format >= 2){
+ return -2;
+ }
+ if(avctx->sub_id == 1){
+ avctx->pix_fmt = avctx->get_format(avctx,pixfmt_vdpau_mpg1_420);
+ }else{
+ if(avctx->profile == 5){
+ avctx->pix_fmt = avctx->get_format(avctx,pixfmt_vdpau_mpg2simple_420);
+ }else
+ if(avctx->profile == 4){
+ avctx->pix_fmt = avctx->get_format(avctx,pixfmt_vdpau_mpg2main_420);
+ }else{
+ return -2;
+ }
+ }
+ }else if(avctx->xvmc_acceleration){
avctx->pix_fmt = avctx->get_format(avctx,pixfmt_xvmc_mpg2_420);
}else{
avctx->pix_fmt = PIX_FMT_YUV420P;
@@ -2562,6 +2614,14 @@ static int decode_chunks(AVCodecContext *avctx,
for(i=0; i<s->slice_count; i++)
s2->error_count += s2->thread_context[i]->error_count;
}
+
+#ifdef HAVE_VDPAU
+ if (avctx->vdpau_acceleration) {
+ /* Fills mpeg12 picture informations before returing from libavcodec. */
+ VDPAU_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
+ }
+#endif
+
if (slice_end(avctx, picture)) {
if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
*data_size = sizeof(AVPicture);
@@ -2640,6 +2700,11 @@ static int decode_chunks(AVCodecContext *avctx,
return -1;
}
+ if (avctx->vdpau_acceleration) {
+ s->slice_count++;
+ break;
+ }
+
if(avctx->thread_count > 1){
int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count;
if(threshold <= mb_y){
@@ -2830,3 +2895,35 @@ AVCodec mpeg_dvdv_decoder = {
#endif
+#ifdef HAVE_VDPAU
+static av_cold int mpeg_vdpau_decode_init(AVCodecContext *avctx){
+ if( avctx->thread_count > 1)
+ return -1;
+ if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) )
+ return -1;
+ if( !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD) ){
+ dprintf(avctx, "mpeg12.c: VDPAU decoder does not set SLICE_FLAG_ALLOW_FIELD\n");
+ }
+ mpeg_decode_init(avctx);
+
+ // Set in mpeg_decode_postinit() once initial parsing is complete
+ avctx->pix_fmt = PIX_FMT_NONE;
+ avctx->vdpau_acceleration = 1;
+
+ return 0;
+}
+
+AVCodec mpeg_vdpau_decoder = {
+ "mpegvideo_vdpau",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MPEGVIDEO_VDPAU,
+ sizeof(Mpeg1Context),
+ mpeg_vdpau_decode_init,
+ NULL,
+ mpeg_decode_end,
+ mpeg_decode_frame,
+ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
+ .flush= ff_mpeg_flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
+};
+#endif
diff --git a/mythtv/libs/libavcodec/mpegvideo.c b/mythtv/libs/libavcodec/mpegvideo.c
index 97cc79b..98d2ebb 100644
--- a/mythtv/libs/libavcodec/mpegvideo.c
+++ b/mythtv/libs/libavcodec/mpegvideo.c
@@ -58,6 +58,7 @@ extern int XVMC_field_start(MpegEncContext*s, AVCodecContext *avctx);
extern void XVMC_field_end(MpegEncContext *s);
extern void XVMC_decode_mb(MpegEncContext *s);
+extern int VDPAU_mpeg_field_start(MpegEncContext *s);
/* enable all paranoid tests for rounding, overflows, etc... */
//#define PARANOID
@@ -969,6 +970,10 @@ void MPV_frame_end(MpegEncContext *s)
XVMC_field_end(s);
}else
#endif
+#ifdef HAVE_VDPAU
+ if(s->avctx->vdpau_acceleration){
+ }else
+#endif
if(s->unrestricted_mv && s->current_picture.reference && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
s->dsp.draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH );
s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
diff --git a/mythtv/libs/libavcodec/utils.c b/mythtv/libs/libavcodec/utils.c
index 475414d..967afc7 100644
--- a/mythtv/libs/libavcodec/utils.c
+++ b/mythtv/libs/libavcodec/utils.c
@@ -647,6 +647,7 @@ static const AVOption options[]={
{"context", "context model", OFFSET(context_model), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E},
{"slice_flags", NULL, OFFSET(slice_flags), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
+{"vdpau_acceleration", NULL, OFFSET(vdpau_acceleration), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX},
{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "mbd"},
{"simple", "use mbcmp (default)", 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_SIMPLE, INT_MIN, INT_MAX, V|E, "mbd"},
{"bits", "use fewest bits", 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_BITS, INT_MIN, INT_MAX, V|E, "mbd"},
diff --git a/mythtv/libs/libavcodec/vc1.c b/mythtv/libs/libavcodec/vc1.c
index 9dd6ba8..276ed63 100644
--- a/mythtv/libs/libavcodec/vc1.c
+++ b/mythtv/libs/libavcodec/vc1.c
@@ -41,8 +41,22 @@
#define MB_INTRA_VLC_BITS 9
#define DC_VLC_BITS 9
#define AC_VLC_BITS 9
+
+extern int VDPAU_vc1_decode_picture(MpegEncContext *s, AVCodecContext *avctx, VC1Context *v, const uint8_t *buf, int buf_size);
+
static const uint16_t table_mb_intra[64][2];
+#ifdef HAVE_VDPAU
+static const enum PixelFormat pixfmt_vdpau_vc1_simple_420[] = {
+ PIX_FMT_VDPAU_VC1_SIMPLE,
+ PIX_FMT_NONE};
+static const enum PixelFormat pixfmt_vdpau_vc1_main_420[] = {
+ PIX_FMT_VDPAU_VC1_MAIN,
+ PIX_FMT_NONE};
+static const enum PixelFormat pixfmt_vdpau_vc1_advanced_420[] = {
+ PIX_FMT_VDPAU_VC1_ADVANCED,
+ PIX_FMT_NONE};
+#endif
/**
* Init VC-1 specific tables and VC1Context members
@@ -828,6 +842,29 @@ static void vc1_mc_4mv_chroma(VC1Context *v)
}
}
+#ifdef HAVE_VDPAU
+static int decode_postinit(VC1Context *v, AVCodecContext *avctx)
+{
+ if (avctx->pix_fmt != PIX_FMT_NONE){
+ return 0;
+ }
+
+ if (avctx->vdpau_acceleration) { // VC1
+ if (v->profile == 0) {
+ avctx->pix_fmt = avctx->get_format(avctx, pixfmt_vdpau_vc1_simple_420);
+ } else if (v->profile == 1) {
+ avctx->pix_fmt = avctx->get_format(avctx, pixfmt_vdpau_vc1_main_420);
+ } else if (v->profile == 3) {
+ avctx->pix_fmt = avctx->get_format(avctx, pixfmt_vdpau_vc1_advanced_420);
+ } else {
+ return -2;
+ }
+ }
+
+ return 0;
+}
+#endif
+
static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb);
/**
@@ -1005,8 +1042,24 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
if(get_bits1(gb)) { //Display Info - decoding is not affected by it
int w, h, ar = 0;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n");
- v->s.avctx->width = v->s.width = w = get_bits(gb, 14) + 1;
- v->s.avctx->height = v->s.height = h = get_bits(gb, 14) + 1;
+ // FIXME: The w/h parsed here are the *display* width/height, not the
+ // coded width/height. Ideally, we should make the commented
+ // assignments below, but that causes problems:
+ // * The SW decoder in this file experiences errors, because it
+ // assumes these assigned values are the coded size:
+ // [vc1 @ 0x86f2130]concealing 150 DC, 150 AC, 150 MV errors
+ // * VDPAU also assumes these are the coded size, since this is the
+ // only size passed to vo_vdpau.c:config(). This causes errors
+ // during the decode process.
+ // However, simply removing these assignments is not the complete fix,
+ // because without them, the stream is displayed at its coded size,
+ // not this requested display size. Ideally, setting:
+ // sample_aspect_ratio = (AVRational){w, h}
+ // in the case when ar is not present/set would persuade other modules
+ // to scale to this requested size. However, sample_aspect_ratio
+ // appears to be completely ignored elsewhere.
+ /*v->s.avctx->width = v->s.width =*/ w = get_bits(gb, 14) + 1;
+ /*v->s.avctx->height = v->s.height =*/ h = get_bits(gb, 14) + 1;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h);
if(get_bits1(gb))
ar = get_bits(gb, 4);
@@ -1057,13 +1110,13 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
static int decode_entry_point(AVCodecContext *avctx, GetBitContext *gb)
{
VC1Context *v = avctx->priv_data;
- int i, blink, clentry, refdist;
+ int i, blink, clentry;
av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
blink = get_bits1(gb); // broken link
clentry = get_bits1(gb); // closed entry
v->panscanflag = get_bits1(gb);
- refdist = get_bits1(gb); // refdist flag
+ v->refdist_flag = get_bits1(gb);
v->s.loop_filter = get_bits1(gb);
v->fastuvmc = get_bits1(gb);
v->extended_mv = get_bits1(gb);
@@ -1084,20 +1137,22 @@ static int decode_entry_point(AVCodecContext *avctx, GetBitContext *gb)
}
if(v->extended_mv)
v->extended_dmv = get_bits1(gb);
- if(get_bits1(gb)) {
+ v->range_mapy_flag = get_bits1(gb);
+ if(v->range_mapy_flag) {
av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n");
- skip_bits(gb, 3); // Y range, ignored for now
+ v->range_mapy = get_bits(gb, 3);
}
- if(get_bits1(gb)) {
+ v->range_mapuv_flag = get_bits1(gb);
+ if(v->range_mapuv_flag) {
av_log(avctx, AV_LOG_ERROR, "Chroma scaling is not supported, expect wrong picture\n");
- skip_bits(gb, 3); // UV range, ignored for now
+ v->range_mapuv = get_bits(gb, 3);
}
av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n"
"BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
"RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
"DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
- blink, clentry, v->panscanflag, refdist, v->s.loop_filter,
+ blink, clentry, v->panscanflag, v->refdist_flag, v->s.loop_filter,
v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
return 0;
@@ -1395,6 +1450,9 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
if(v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_P_TYPE) v->use_ic = 0;
+ if(v->postprocflag)
+ v->postproc = get_bits(gb, 2);
+
switch(v->s.pict_type) {
case FF_I_TYPE:
case FF_BI_TYPE:
@@ -1414,8 +1472,6 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
}
break;
case FF_P_TYPE:
- if(v->postprocflag)
- v->postproc = get_bits1(gb);
if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3);
else v->mvrange = 0;
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
@@ -1505,8 +1561,6 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
}
break;
case FF_B_TYPE:
- if(v->postprocflag)
- v->postproc = get_bits1(gb);
if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3);
else v->mvrange = 0;
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
@@ -3994,7 +4048,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
avctx->coded_width = avctx->width;
avctx->coded_height = avctx->height;
- if (avctx->codec_id == CODEC_ID_WMV3)
+ if ((avctx->codec_id == CODEC_ID_WMV3) || (avctx->codec_id == CODEC_ID_WMV3_VDPAU))
{
int count = 0;
@@ -4109,6 +4163,9 @@ static int vc1_decode_frame(AVCodecContext *avctx,
MpegEncContext *s = &v->s;
AVFrame *pict = data;
uint8_t *buf2 = NULL;
+#ifdef HAVE_VDPAU
+ const uint8_t *buf_vdpau = buf;
+#endif
/* no supplementary picture */
if (buf_size == 0) {
@@ -4130,8 +4187,14 @@ static int vc1_decode_frame(AVCodecContext *avctx,
s->current_picture_ptr= &s->picture[i];
}
+#ifdef HAVE_VDPAU
+ // pxt_fmt calculation for VDPAU.
+ if (decode_postinit(v, avctx) < 0)
+ return -1;
+#endif
+
//for advanced profile we may need to parse and unescape data
- if (avctx->codec_id == CODEC_ID_VC1) {
+ if ((avctx->codec_id == CODEC_ID_VC1) || (avctx->codec_id == CODEC_ID_VC1_VDPAU)) {
int buf_size2 = 0;
buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -4146,6 +4209,9 @@ static int vc1_decode_frame(AVCodecContext *avctx,
if(size <= 0) continue;
switch(AV_RB32(start)){
case VC1_CODE_FRAME:
+#ifdef HAVE_VDPAU
+ buf_vdpau = start;
+#endif
buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
break;
case VC1_CODE_ENTRYPOINT: /* it should be before frame data */
@@ -4231,17 +4297,36 @@ static int vc1_decode_frame(AVCodecContext *avctx,
return -1;
}
+#ifdef HAVE_VDPAU
+ // MPV_frame_start() calls to get_buffer/videoSurfaces. Now we call
+ // VDPAU_vc1_field_start where picture-parameters are filled.
+ // VDPAU_vc1_picture_complete calls to vdpau_decoder_render.
+
+ if (avctx->vdpau_acceleration) {
+ if (VDPAU_vc1_decode_picture(s, avctx, v, buf_vdpau, (buf + buf_size) - buf_vdpau) < 0) {
+ av_free(buf2);
+ return -1;
+ }
+ }
+#endif
+
s->me.qpel_put= s->dsp.put_qpel_pixels_tab;
s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
- ff_er_frame_start(s);
+#ifdef HAVE_VDPAU
+ if (!avctx->vdpau_acceleration) {
+#endif
+ ff_er_frame_start(s);
- v->bits = buf_size * 8;
- vc1_decode_blocks(v);
+ v->bits = buf_size * 8;
+ vc1_decode_blocks(v);
//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), buf_size*8);
// if(get_bits_count(&s->gb) > buf_size * 8)
// return -1;
- ff_er_frame_end(s);
+ ff_er_frame_end(s);
+#ifdef HAVE_VDPAU
+ }
+#endif
MPV_frame_end(s);
@@ -4315,3 +4400,48 @@ AVCodec wmv3_decoder = {
NULL,
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
};
+
+#ifdef HAVE_VDPAU
+static av_cold int vc1_vdpau_decode_init(AVCodecContext *avctx){
+ if( avctx->thread_count > 1)
+ return -1;
+ if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) )
+ return -1;
+ if( !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD) ){
+ dprintf(avctx, "vc1.c: VDPAU decoder does not set SLICE_FLAG_ALLOW_FIELD\n");
+ }
+ avctx->vdpau_acceleration = 1;
+ vc1_decode_init(avctx);
+ avctx->pix_fmt = PIX_FMT_NONE;
+
+ return 0;
+}
+
+AVCodec wmv3_vdpau_decoder = {
+ "wmv3_vdpau",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_WMV3_VDPAU,
+ sizeof(VC1Context),
+ vc1_vdpau_decode_init,
+ NULL,
+ vc1_decode_end,
+ vc1_decode_frame,
+ CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
+ NULL,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"),
+};
+
+AVCodec vc1_vdpau_decoder = {
+ "vc1_vdpau",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_VC1_VDPAU,
+ sizeof(VC1Context),
+ vc1_vdpau_decode_init,
+ NULL,
+ vc1_decode_end,
+ vc1_decode_frame,
+ CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
+ NULL,
+ .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"),
+};
+#endif
diff --git a/mythtv/libs/libavcodec/vc1.h b/mythtv/libs/libavcodec/vc1.h
index 4cd7bb1..e99d1a7 100644
--- a/mythtv/libs/libavcodec/vc1.h
+++ b/mythtv/libs/libavcodec/vc1.h
@@ -180,6 +180,7 @@ typedef struct VC1Context{
int interlace; ///< Progressive/interlaced (RPTFTM syntax element)
int tfcntrflag; ///< TFCNTR present
int panscanflag; ///< NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present
+ int refdist_flag; ///<
int extended_dmv; ///< Additional extended dmv range at P/B frame-level
int color_prim; ///< 8bits, chroma coordinates of the color primaries
int transfer_char; ///< 8bits, Opto-electronic transfer characteristics
diff --git a/mythtv/libs/libavcodec/vdpau_render.h b/mythtv/libs/libavcodec/vdpau_render.h
new file mode 100644
index 0000000..d6296cb
--- /dev/null
+++ b/mythtv/libs/libavcodec/vdpau_render.h
@@ -0,0 +1,30 @@
+#ifndef FFMPEG_VDPAU_RENDER_H
+#define FFMPEG_VDPAU_RENDER_H
+
+#include "vdpau/vdpau.h"
+#include "vdpau/vdpau_x11.h"
+
+//the surface is used for render.
+#define MP_VDPAU_STATE_USED_FOR_RENDER 1
+//the surface is needed for reference/prediction, codec manipulates this.
+#define MP_VDPAU_STATE_USED_FOR_REFERENCE 2
+
+#define MP_VDPAU_RENDER_MAGIC 0x1DC8E14B
+
+typedef struct {
+ int magic;
+
+ VdpVideoSurface surface; //used as rendered surface, never changed.
+
+ int state; // Holds MP_VDPAU_STATE_* values
+
+ union _VdpPictureInfo {
+ VdpPictureInfoMPEG1Or2 mpeg;
+ VdpPictureInfoH264 h264;
+ VdpPictureInfoVC1 vc1;
+ } info;
+
+ VdpBitstreamBuffer bitstreamBuffer;
+} vdpau_render_state_t;
+
+#endif /* FFMPEG_VDPAU_RENDER_H */
diff --git a/mythtv/libs/libavcodec/vdpauvideo.c b/mythtv/libs/libavcodec/vdpauvideo.c
new file mode 100644
index 0000000..6009068
--- /dev/null
+++ b/mythtv/libs/libavcodec/vdpauvideo.c
@@ -0,0 +1,346 @@
+#include <limits.h>
+
+//avcodec include
+#include "avcodec.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+#include "h264.h"
+#include "vc1.h"
+
+#undef NDEBUG
+#include <assert.h>
+
+#include "vdpau_render.h"
+
+#define ARSIZE(_x_) (sizeof(_x_) / sizeof((_x_)[0]))
+
+uint32_t num_reference_surfaces;
+
+int VDPAU_mpeg_field_start(MpegEncContext *s)
+{
+ vdpau_render_state_t * render,* last, * next;
+ int i;
+
+ render = (vdpau_render_state_t*)s->current_picture.data[2];
+ assert(render != NULL);
+ if (render == NULL) {
+ return -1; //make sure that this is render packet
+ }
+
+ /* fill VdpPictureInfoMPEG1Or2 struct */
+ render->info.mpeg.picture_structure = s->picture_structure;
+ render->info.mpeg.picture_coding_type = s->pict_type;
+ render->info.mpeg.intra_dc_precision = s->intra_dc_precision;
+ render->info.mpeg.frame_pred_frame_dct = s->frame_pred_frame_dct;
+ render->info.mpeg.concealment_motion_vectors = s->concealment_motion_vectors;
+ render->info.mpeg.intra_vlc_format = s->intra_vlc_format;
+ render->info.mpeg.alternate_scan = s->alternate_scan;
+ render->info.mpeg.q_scale_type = s->q_scale_type;
+ render->info.mpeg.top_field_first = s->top_field_first;
+ render->info.mpeg.full_pel_forward_vector = s->full_pel[0]; // MPEG-1 only. Set 0 for MPEG-2
+ render->info.mpeg.full_pel_backward_vector = s->full_pel[1]; // MPEG-1 only. Set 0 for MPEG-2
+ render->info.mpeg.f_code[0][0] = s->mpeg_f_code[0][0]; // For MPEG-1 fill both horiz. & vert.
+ render->info.mpeg.f_code[0][1] = s->mpeg_f_code[0][1];
+ render->info.mpeg.f_code[1][0] = s->mpeg_f_code[1][0];
+ render->info.mpeg.f_code[1][1] = s->mpeg_f_code[1][1];
+ for (i = 0; i < 64; ++i) {
+ render->info.mpeg.intra_quantizer_matrix[i] = s->intra_matrix[i];
+ render->info.mpeg.non_intra_quantizer_matrix[i] = s->inter_matrix[i];
+ }
+
+ render->info.mpeg.forward_reference = VDP_INVALID_HANDLE;
+ render->info.mpeg.backward_reference = VDP_INVALID_HANDLE;
+
+ switch(s->pict_type){
+ case FF_I_TYPE:
+ return 0; // no prediction from other frames
+ case FF_B_TYPE:
+ next = (vdpau_render_state_t*)s->next_picture.data[2];
+ assert(next!=NULL);
+ if (next == NULL) {
+ return -1;
+ }
+ render->info.mpeg.backward_reference = next->surface;
+ // no return here, going to set forward prediction
+ case FF_P_TYPE:
+ last = (vdpau_render_state_t*)s->last_picture.data[2];
+ if (last == NULL) { // FIXME: Does this test make sense?
+ last = render; // predict second field from the first
+ }
+ render->info.mpeg.forward_reference = last->surface;
+ return 0;
+ }
+
+ return -1;
+}
+
+int VDPAU_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, int buf_size, int slice_count)
+{
+ vdpau_render_state_t * render;
+
+ render = (vdpau_render_state_t*)s->current_picture_ptr->data[2];
+ assert(render != NULL);
+ if (render == NULL) {
+ return -1; // make sure that this is render packet
+ }
+
+ render->bitstreamBuffer.struct_version = VDP_BITSTREAM_BUFFER_VERSION;
+ render->bitstreamBuffer.bitstream_bytes = buf_size;
+ render->bitstreamBuffer.bitstream = buf;
+ render->info.mpeg.slice_count = slice_count;
+
+ if (slice_count > 0) {
+ ff_draw_horiz_band(s, 0, s->avctx->height);
+ }
+
+ return 0;
+}
+
+int VDPAU_h264_set_reference_frames(H264Context *h)
+{
+ MpegEncContext * s = &h->s;
+ vdpau_render_state_t * render, * render_ref;
+ VdpReferenceFrameH264 * rf, * rf2;
+ Picture * pic;
+ int i, list;
+
+ render = (vdpau_render_state_t*)s->current_picture_ptr->data[2];
+ assert(render != NULL);
+ if (render == NULL)
+ return -1; //make sure that this is render packet
+
+ rf = &render->info.h264.referenceFrames[0];
+#define H264_RF_COUNT ARSIZE(render->info.h264.referenceFrames)
+
+ for (list = 0; list < 2; ++list) {
+ Picture **lp = list ? h->long_ref : h->short_ref;
+ int ls = list ? h->long_ref_count : h->short_ref_count;
+
+ for (i = 0; i < ls; ++i) {
+ pic = lp[i];
+ if (!pic || !pic->reference) {
+ continue;
+ }
+
+ render_ref = (vdpau_render_state_t*)pic->data[2];
+ assert(render_ref != NULL);
+ if (render_ref == NULL)
+ return -1; //make sure that this is render packet
+
+ rf2 = &render->info.h264.referenceFrames[0];
+ while (rf2 != rf) {
+ if (
+ (rf2->surface == render_ref->surface)
+ && (rf2->is_long_term == pic->long_ref)
+ && (rf2->frame_idx == pic->frame_num)
+ ) {
+ break;
+ }
+ ++rf2;
+ }
+ if (rf2 != rf) {
+ rf2->top_is_reference |= (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE;
+ rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+ continue;
+ }
+
+ if (rf >= &render->info.h264.referenceFrames[H264_RF_COUNT]) {
+ continue;
+ }
+
+ rf->surface = render_ref->surface;
+ rf->is_long_term = pic->long_ref;
+ rf->top_is_reference = (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE;
+ rf->bottom_is_reference = (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+ rf->field_order_cnt[0] = pic->field_poc[0];
+ rf->field_order_cnt[1] = pic->field_poc[1];
+ rf->frame_idx = pic->frame_num;
+
+ ++rf;
+ }
+ }
+
+ for (; rf < &render->info.h264.referenceFrames[H264_RF_COUNT]; ++rf) {
+ rf->surface = VDP_INVALID_HANDLE;
+ rf->is_long_term = 0;
+ rf->top_is_reference = 0;
+ rf->bottom_is_reference = 0;
+ rf->field_order_cnt[0] = 0;
+ rf->field_order_cnt[1] = 0;
+ rf->frame_idx = 0;
+ }
+
+ return 0;
+}
+
+int VDPAU_h264_picture_complete(H264Context *h, const uint8_t *buf, int buf_size)
+{
+ MpegEncContext * s = &h->s;
+ vdpau_render_state_t * render;
+ int i;
+
+ render = (vdpau_render_state_t*)s->current_picture_ptr->data[2];
+ assert(render != NULL);
+ if (render == NULL)
+ return -1; //make sure that this is render packet
+
+ render->info.h264.slice_count = h->slice_num;
+
+ if (render->info.h264.slice_count < 1)
+ return 0;
+
+ for (int i = 0; i < 2; ++i) {
+ int foc = s->current_picture_ptr->field_poc[i];
+ if (foc == INT_MAX) {
+ foc = 0;
+ }
+ render->info.h264.field_order_cnt[i] = foc;
+ }
+
+ render->info.h264.is_reference = s->current_picture_ptr->reference ? VDP_TRUE : VDP_FALSE;
+ render->info.h264.frame_num = h->frame_num;
+ render->info.h264.field_pic_flag = (s->picture_structure != PICT_FRAME) ? 1 : 0;
+ render->info.h264.bottom_field_flag = (s->picture_structure == PICT_BOTTOM_FIELD) ? 1 : 0;
+ render->info.h264.num_ref_frames = h->sps.ref_frame_count;
+ render->info.h264.mb_adaptive_frame_field_flag = h->sps.mb_aff;
+ render->info.h264.constrained_intra_pred_flag = h->pps.constrained_intra_pred;
+ render->info.h264.weighted_pred_flag = h->pps.weighted_pred;
+ render->info.h264.weighted_bipred_idc = h->pps.weighted_bipred_idc;
+ render->info.h264.frame_mbs_only_flag = h->sps.frame_mbs_only_flag;
+ render->info.h264.transform_8x8_mode_flag = h->pps.transform_8x8_mode;
+ render->info.h264.chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0];
+ render->info.h264.second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1];
+ render->info.h264.pic_init_qp_minus26 = h->pps.init_qp - 26;
+ render->info.h264.num_ref_idx_l0_active_minus1 = h->pps.ref_count[0] - 1;
+ render->info.h264.num_ref_idx_l1_active_minus1 = h->pps.ref_count[1] - 1;
+ render->info.h264.log2_max_frame_num_minus4 = h->sps.log2_max_frame_num - 4;
+ render->info.h264.pic_order_cnt_type = h->sps.poc_type;
+ render->info.h264.log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4;
+ render->info.h264.delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag;
+ render->info.h264.direct_8x8_inference_flag = h->sps.direct_8x8_inference_flag;
+ render->info.h264.entropy_coding_mode_flag = h->pps.cabac;
+ render->info.h264.pic_order_present_flag = h->pps.pic_order_present;
+ render->info.h264.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
+ render->info.h264.redundant_pic_cnt_present_flag = h->pps.redundant_pic_cnt_present;
+ memcpy(render->info.h264.scaling_lists_4x4, h->pps.scaling_matrix4, sizeof(render->info.h264.scaling_lists_4x4));
+ memcpy(render->info.h264.scaling_lists_8x8, h->pps.scaling_matrix8, sizeof(render->info.h264.scaling_lists_8x8));
+
+ render->bitstreamBuffer.struct_version = VDP_BITSTREAM_BUFFER_VERSION;
+ render->bitstreamBuffer.bitstream_bytes = buf_size;
+ render->bitstreamBuffer.bitstream = buf;
+
+ ff_draw_horiz_band(s, 0, s->avctx->height);
+
+ return 0;
+}
+
+void VDPAU_h264_set_reference_frames_count(H264Context *h)
+{
+ num_reference_surfaces = h->sps.ref_frame_count;
+}
+
+#undef printf
+
+int VDPAU_vc1_decode_picture(MpegEncContext *s, AVCodecContext *avctx, VC1Context *v, const uint8_t *buf, int buf_size)
+{
+ // VC1Context *v = avctx->priv_data;
+ vdpau_render_state_t * render,* last, * next;
+
+ render = (vdpau_render_state_t*)s->current_picture.data[2];
+ assert(render != NULL);
+ if (render == NULL) {
+ return -1; //make sure that this is render packet
+ }
+ memset(&(render->info), 0 , sizeof(VdpPictureInfoVC1));
+ memset(&(render->bitstreamBuffer), 0, sizeof(VdpBitstreamBuffer));
+
+ /* fill LvPictureInfoVC1 struct */
+ render->info.vc1.frame_coding_mode = v->fcm;
+ render->info.vc1.postprocflag = v->postprocflag;
+ render->info.vc1.pulldown = v->broadcast;
+ render->info.vc1.interlace = v->interlace;
+ render->info.vc1.tfcntrflag = v->tfcntrflag;
+ render->info.vc1.finterpflag = v->finterpflag;
+ render->info.vc1.psf = v->psf;
+ render->info.vc1.dquant = v->dquant;
+ render->info.vc1.panscan_flag = v->panscanflag;
+ render->info.vc1.refdist_flag = v->refdist_flag;
+ render->info.vc1.quantizer = v->quantizer_mode;
+ render->info.vc1.extended_mv = v->extended_mv;
+ render->info.vc1.extended_dmv = v->extended_dmv;
+ render->info.vc1.overlap = v->overlap;
+ render->info.vc1.vstransform = v->vstransform;
+ render->info.vc1.loopfilter = v->s.loop_filter;
+ render->info.vc1.fastuvmc = v->fastuvmc;
+ render->info.vc1.range_mapy_flag = v->range_mapy_flag;
+ render->info.vc1.range_mapy = v->range_mapy;
+ render->info.vc1.range_mapuv_flag = v->range_mapuv_flag;
+ render->info.vc1.range_mapuv = v->range_mapuv;
+ /* Specific to simple/main profile only */
+ render->info.vc1.multires = v->multires;
+ render->info.vc1.syncmarker = v->s.resync_marker;
+ render->info.vc1.rangered = v->rangered;
+ render->info.vc1.maxbframes = v->s.max_b_frames;
+ /* Presently, making these as 0 */
+ render->info.vc1.deblockEnable = 0;
+ render->info.vc1.pquant = 0;
+
+ render->info.vc1.forward_reference = VDP_INVALID_HANDLE;
+ render->info.vc1.backward_reference = VDP_INVALID_HANDLE;
+
+ switch(s->pict_type){
+ case FF_I_TYPE:
+ render->info.vc1.picture_type = 0;
+ break;
+ case FF_B_TYPE:
+ if (v->bi_type) {
+ render->info.vc1.picture_type = 4;
+ }
+ else {
+ render->info.vc1.picture_type = 3;
+ }
+ break;
+ case FF_P_TYPE:
+ render->info.vc1.picture_type = 1;
+ break;
+ case FF_BI_TYPE:
+ render->info.vc1.picture_type = 4;
+ break;
+ default:
+ return -1;
+ }
+
+ switch(s->pict_type){
+ case FF_I_TYPE:
+ case FF_BI_TYPE:
+ break;
+ case FF_B_TYPE:
+ next = (vdpau_render_state_t*)s->next_picture.data[2];
+ assert(next!=NULL);
+ if (next == NULL) {
+ return -1;
+ }
+ render->info.vc1.backward_reference = next->surface;
+ // no break here, going to set forward prediction
+ case FF_P_TYPE:
+ last = (vdpau_render_state_t*)s->last_picture.data[2];
+ if (last == NULL) { // FIXME: Does this test make sense?
+ last = render; // predict second field from the first
+ }
+ render->info.vc1.forward_reference = last->surface;
+ break;
+ default:
+ return -1;
+ }
+
+ render->bitstreamBuffer.struct_version = VDP_BITSTREAM_BUFFER_VERSION;
+ render->bitstreamBuffer.bitstream_bytes = buf_size;
+ render->bitstreamBuffer.bitstream = buf;
+ // FIXME: I am not sure about how MPlayer calculates slice number.
+ render->info.vc1.slice_count = 1;
+
+ ff_draw_horiz_band(s, 0, s->avctx->height);
+
+ return 0;
+}
+
diff --git a/mythtv/libs/libavutil/avutil.h b/mythtv/libs/libavutil/avutil.h
index 03c5520..65ea42b 100644
--- a/mythtv/libs/libavutil/avutil.h
+++ b/mythtv/libs/libavutil/avutil.h
@@ -121,6 +121,15 @@ enum PixelFormat {
PIX_FMT_YUV440P, ///< Planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
PIX_FMT_YUVJ440P, ///< Planar YUV 4:4:0 full scale (jpeg)
PIX_FMT_YUVA420P, ///< Planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+ PIX_FMT_VDPAU_MPEG1, ///< VDPAU acceleration via common packet passing(vdpau_remder.h)
+ PIX_FMT_VDPAU_MPEG2_SIMPLE, ///< VDPAU acceleration via common packet passing(vdpau_remder.h)
+ PIX_FMT_VDPAU_MPEG2_MAIN, ///< VDPAU acceleration via common packet passing(vdpau_remder.h)
+ PIX_FMT_VDPAU_H264_BASELINE,///< VDPAU acceleration via common packet passing(vdpau_remder.h)
+ PIX_FMT_VDPAU_H264_MAIN, ///< VDPAU acceleration via common packet passing(vdpau_remder.h)
+ PIX_FMT_VDPAU_H264_HIGH, ///< VDPAU acceleration via common packet passing(vdpau_remder.h)
+ PIX_FMT_VDPAU_VC1_SIMPLE, ///< VDPAU acceleration via common packet passing(vdpau_remder.h)
+ PIX_FMT_VDPAU_VC1_MAIN, ///< VDPAU acceleration via common packet passing(vdpau_remder.h)
+ PIX_FMT_VDPAU_VC1_ADVANCED, ///< VDPAU acceleration via common packet passing(vdpau_remder.h)
PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
};