1/* 2 * MPEG-4 Part 2 / H.263 decode acceleration through VDPAU 3 * 4 * Copyright (c) 2008 NVIDIA 5 * Copyright (c) 2013 Rémi Denis-Courmont 6 * 7 * This file is part of FFmpeg. 8 * 9 * FFmpeg is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * FFmpeg is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with FFmpeg; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24#include <vdpau/vdpau.h> 25 26#include "avcodec.h" 27#include "hwconfig.h" 28#include "mpeg4videodec.h" 29#include "vdpau.h" 30#include "vdpau_internal.h" 31 32static int vdpau_mpeg4_start_frame(AVCodecContext *avctx, 33 const uint8_t *buffer, uint32_t size) 34{ 35 Mpeg4DecContext *ctx = avctx->priv_data; 36 MpegEncContext * const s = &ctx->m; 37 Picture *pic = s->current_picture_ptr; 38 struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; 39 VdpPictureInfoMPEG4Part2 *info = &pic_ctx->info.mpeg4; 40 VdpVideoSurface ref; 41 int i; 42 43 /* fill VdpPictureInfoMPEG4Part2 struct */ 44 info->forward_reference = VDP_INVALID_HANDLE; 45 info->backward_reference = VDP_INVALID_HANDLE; 46 info->vop_coding_type = 0; 47 48 switch (s->pict_type) { 49 case AV_PICTURE_TYPE_B: 50 ref = ff_vdpau_get_surface_id(s->next_picture.f); 51 assert(ref != VDP_INVALID_HANDLE); 52 info->backward_reference = ref; 53 info->vop_coding_type = 2; 54 /* fall-through */ 55 case AV_PICTURE_TYPE_P: 56 ref = ff_vdpau_get_surface_id(s->last_picture.f); 57 assert(ref != VDP_INVALID_HANDLE); 58 info->forward_reference = ref; 59 } 60 61 info->trd[0] = s->pp_time; 62 info->trb[0] = s->pb_time; 63 info->trd[1] = s->pp_field_time >> 1; 64 info->trb[1] = s->pb_field_time >> 1; 65 info->vop_time_increment_resolution = s->avctx->framerate.num; 66 info->vop_fcode_forward = s->f_code; 67 info->vop_fcode_backward = s->b_code; 68 info->resync_marker_disable = !ctx->resync_marker; 69 info->interlaced = !s->progressive_sequence; 70 info->quant_type = s->mpeg_quant; 71 info->quarter_sample = s->quarter_sample; 72 info->short_video_header = avctx->codec->id == AV_CODEC_ID_H263; 73 info->rounding_control = s->no_rounding; 74 info->alternate_vertical_scan_flag = s->alternate_scan; 75 info->top_field_first = s->top_field_first; 76 for (i = 0; i < 64; ++i) { 77 int n = s->idsp.idct_permutation[i]; 78 info->intra_quantizer_matrix[i] = s->intra_matrix[n]; 79 info->non_intra_quantizer_matrix[i] = s->inter_matrix[n]; 80 } 81 82 ff_vdpau_common_start_frame(pic_ctx, buffer, size); 83 return ff_vdpau_add_buffer(pic_ctx, buffer, size); 84} 85 86static int vdpau_mpeg4_decode_slice(av_unused AVCodecContext *avctx, 87 av_unused const uint8_t *buffer, 88 av_unused uint32_t size) 89{ 90 return 0; 91} 92 93static int vdpau_mpeg4_init(AVCodecContext *avctx) 94{ 95 VdpDecoderProfile profile; 96 97 switch (avctx->profile) { 98 case FF_PROFILE_MPEG4_SIMPLE: 99 profile = VDP_DECODER_PROFILE_MPEG4_PART2_SP; 100 break; 101 // As any ASP decoder must be able to decode SP, this 102 // should be a safe fallback if profile is unknown/unspecified. 103 case FF_PROFILE_UNKNOWN: 104 case FF_PROFILE_MPEG4_ADVANCED_SIMPLE: 105 profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; 106 break; 107 default: 108 return AVERROR(ENOTSUP); 109 } 110 111 return ff_vdpau_common_init(avctx, profile, avctx->level); 112} 113 114const AVHWAccel ff_mpeg4_vdpau_hwaccel = { 115 .name = "mpeg4_vdpau", 116 .type = AVMEDIA_TYPE_VIDEO, 117 .id = AV_CODEC_ID_MPEG4, 118 .pix_fmt = AV_PIX_FMT_VDPAU, 119 .start_frame = vdpau_mpeg4_start_frame, 120 .end_frame = ff_vdpau_mpeg_end_frame, 121 .decode_slice = vdpau_mpeg4_decode_slice, 122 .frame_priv_data_size = sizeof(struct vdpau_picture_context), 123 .init = vdpau_mpeg4_init, 124 .uninit = ff_vdpau_common_uninit, 125 .frame_params = ff_vdpau_common_frame_params, 126 .priv_data_size = sizeof(VDPAUContext), 127 .caps_internal = HWACCEL_CAP_ASYNC_SAFE, 128}; 129