# HG changeset patch # User cehoyos # Date 1257879159 0 # Node ID cdf5b1ed3500ff38f91cfb280778bb1feb0845c2 # Parent f33404f82b9e410142ed0137429c164bb81e4dfe Add VDPAU hardware accelerated decoding for MPEG-4 ASP which can be used by video players. Original patch by NVIDIA corporation. diff -r f33404f82b9e -r cdf5b1ed3500 allcodecs.c --- a/allcodecs.c Tue Nov 10 14:48:32 2009 +0000 +++ b/allcodecs.c Tue Nov 10 18:52:39 2009 +0000 @@ -123,6 +123,7 @@ REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); + REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau); REGISTER_DECODER (MPEGVIDEO, mpegvideo); REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau); REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau); diff -r f33404f82b9e -r cdf5b1ed3500 h263dec.c --- a/h263dec.c Tue Nov 10 14:48:32 2009 +0000 +++ b/h263dec.c Tue Nov 10 18:52:39 2009 +0000 @@ -32,6 +32,7 @@ #include "h263_parser.h" #include "mpeg4video_parser.h" #include "msmpeg4.h" +#include "vdpau_internal.h" //#define DEBUG //#define PRINT_FRAME_TIME @@ -621,6 +622,11 @@ if(MPV_frame_start(s, avctx) < 0) return -1; + if (CONFIG_MPEG4_VDPAU_DECODER && (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)) { + ff_vdpau_mpeg4_decode_picture(s, buf, buf_size); + goto frame_end; + } + if (avctx->hwaccel) { if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0) return -1; @@ -695,6 +701,7 @@ intrax8_decoded: ff_er_frame_end(s); +frame_end: if (avctx->hwaccel) { if (avctx->hwaccel->end_frame(avctx) < 0) return -1; @@ -835,3 +842,19 @@ .long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"), .pix_fmts= ff_pixfmt_list_420, }; + +#if CONFIG_MPEG4_VDPAU_DECODER +AVCodec mpeg4_vdpau_decoder = { + "mpeg4_vdpau", + CODEC_TYPE_VIDEO, + CODEC_ID_MPEG4, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, + .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"), + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_VDPAU_MPEG4, PIX_FMT_NONE}, +}; +#endif diff -r f33404f82b9e -r cdf5b1ed3500 imgconvert.c --- a/imgconvert.c Tue Nov 10 14:48:32 2009 +0000 +++ b/imgconvert.c Tue Nov 10 18:52:39 2009 +0000 @@ -376,6 +376,11 @@ .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, + [PIX_FMT_VDPAU_MPEG4] = { + .name = "vdpau_mpeg4", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, [PIX_FMT_UYYVYY411] = { .name = "uyyvyy411", .nb_channels = 1, diff -r f33404f82b9e -r cdf5b1ed3500 vdpau.c --- a/vdpau.c Tue Nov 10 14:48:32 2009 +0000 +++ b/vdpau.c Tue Nov 10 18:52:39 2009 +0000 @@ -305,4 +305,54 @@ render->bitstream_buffers_used = 0; } +void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, + int buf_size) +{ + struct vdpau_render_state *render, *last, *next; + int i; + + if (!s->current_picture_ptr) return; + + render = (struct vdpau_render_state *)s->current_picture_ptr->data[0]; + assert(render); + + /* fill VdpPictureInfoMPEG4Part2 struct */ + render->info.mpeg4.vop_time_increment_resolution = s->avctx->time_base.den; + render->info.mpeg4.vop_coding_type = 0; + render->info.mpeg4.vop_fcode_forward = s->f_code; + render->info.mpeg4.vop_fcode_backward = s->b_code; + render->info.mpeg4.resync_marker_disable = !s->resync_marker; + render->info.mpeg4.interlaced = !s->progressive_sequence; + render->info.mpeg4.quant_type = s->mpeg_quant; + render->info.mpeg4.quarter_sample = s->quarter_sample; + render->info.mpeg4.short_video_header = s->avctx->codec->id == CODEC_ID_H263; + render->info.mpeg4.rounding_control = s->no_rounding; + render->info.mpeg4.alternate_vertical_scan_flag = s->alternate_scan; + render->info.mpeg4.top_field_first = s->top_field_first; + for (i = 0; i < 64; ++i) { + render->info.mpeg4.intra_quantizer_matrix[i] = s->intra_matrix[i]; + render->info.mpeg4.non_intra_quantizer_matrix[i] = s->inter_matrix[i]; + } + render->info.mpeg4.forward_reference = VDP_INVALID_HANDLE; + render->info.mpeg4.backward_reference = VDP_INVALID_HANDLE; + + switch (s->pict_type) { + case FF_B_TYPE: + next = (struct vdpau_render_state *)s->next_picture.data[0]; + assert(next); + render->info.mpeg4.backward_reference = next->surface; + render->info.mpeg4.vop_coding_type = 2; + // no break here, going to set forward prediction + case FF_P_TYPE: + last = (struct vdpau_render_state *)s->last_picture.data[0]; + assert(last); + render->info.mpeg4.forward_reference = last->surface; + } + + ff_vdpau_add_data_chunk(s, buf, buf_size); + + ff_draw_horiz_band(s, 0, s->avctx->height); + render->bitstream_buffers_used = 0; +} + /* @}*/ diff -r f33404f82b9e -r cdf5b1ed3500 vdpau.h --- a/vdpau.h Tue Nov 10 14:48:32 2009 +0000 +++ b/vdpau.h Tue Nov 10 18:52:39 2009 +0000 @@ -73,6 +73,7 @@ VdpPictureInfoH264 h264; VdpPictureInfoMPEG1Or2 mpeg; VdpPictureInfoVC1 vc1; + VdpPictureInfoMPEG4Part2 mpeg4; } info; /** Describe size/location of the compressed video data. diff -r f33404f82b9e -r cdf5b1ed3500 vdpau_internal.h --- a/vdpau_internal.h Tue Nov 10 14:48:32 2009 +0000 +++ b/vdpau_internal.h Tue Nov 10 18:52:39 2009 +0000 @@ -39,4 +39,7 @@ void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, int buf_size); +void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, + int buf_size); + #endif /* AVCODEC_VDPAU_INTERNAL_H */