00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "vaapi_internal.h"
00024
00026 static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext *s)
00027 {
00028 switch (s->intra_dc_threshold) {
00029 case 99: return 0;
00030 case 13: return 1;
00031 case 15: return 2;
00032 case 17: return 3;
00033 case 19: return 4;
00034 case 21: return 5;
00035 case 23: return 6;
00036 case 0: return 7;
00037 }
00038 return 0;
00039 }
00040
00041 static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
00042 {
00043 MpegEncContext * const s = avctx->priv_data;
00044 struct vaapi_context * const vactx = avctx->hwaccel_context;
00045 VAPictureParameterBufferMPEG4 *pic_param;
00046 VAIQMatrixBufferMPEG4 *iq_matrix;
00047 int i;
00048
00049 dprintf(avctx, "vaapi_mpeg4_start_frame()\n");
00050
00051 vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG4);
00052
00053
00054 pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG4));
00055 if (!pic_param)
00056 return -1;
00057 pic_param->vop_width = s->width;
00058 pic_param->vop_height = s->height;
00059 pic_param->forward_reference_picture = VA_INVALID_ID;
00060 pic_param->backward_reference_picture = VA_INVALID_ID;
00061 pic_param->vol_fields.value = 0;
00062 pic_param->vol_fields.bits.short_video_header = avctx->codec->id == CODEC_ID_H263;
00063 pic_param->vol_fields.bits.chroma_format = CHROMA_420;
00064 pic_param->vol_fields.bits.interlaced = !s->progressive_sequence;
00065 pic_param->vol_fields.bits.obmc_disable = 1;
00066 pic_param->vol_fields.bits.sprite_enable = s->vol_sprite_usage;
00067 pic_param->vol_fields.bits.sprite_warping_accuracy = s->sprite_warping_accuracy;
00068 pic_param->vol_fields.bits.quant_type = s->mpeg_quant;
00069 pic_param->vol_fields.bits.quarter_sample = s->quarter_sample;
00070 pic_param->vol_fields.bits.data_partitioned = s->data_partitioning;
00071 pic_param->vol_fields.bits.reversible_vlc = s->rvlc;
00072 pic_param->vol_fields.bits.resync_marker_disable = !s->resync_marker;
00073 pic_param->no_of_sprite_warping_points = s->num_sprite_warping_points;
00074 for (i = 0; i < s->num_sprite_warping_points && i < 3; i++) {
00075 pic_param->sprite_trajectory_du[i] = s->sprite_traj[i][0];
00076 pic_param->sprite_trajectory_dv[i] = s->sprite_traj[i][1];
00077 }
00078 pic_param->quant_precision = s->quant_precision;
00079 pic_param->vop_fields.value = 0;
00080 pic_param->vop_fields.bits.vop_coding_type = s->pict_type - FF_I_TYPE;
00081 pic_param->vop_fields.bits.backward_reference_vop_coding_type = s->pict_type == FF_B_TYPE ? s->next_picture.pict_type - FF_I_TYPE : 0;
00082 pic_param->vop_fields.bits.vop_rounding_type = s->no_rounding;
00083 pic_param->vop_fields.bits.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(s);
00084 pic_param->vop_fields.bits.top_field_first = s->top_field_first;
00085 pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan;
00086 pic_param->vop_fcode_forward = s->f_code;
00087 pic_param->vop_fcode_backward = s->b_code;
00088 pic_param->vop_time_increment_resolution = avctx->time_base.den;
00089 pic_param->num_macroblocks_in_gob = s->mb_width * ff_h263_get_gob_height(s);
00090 pic_param->num_gobs_in_vop = (s->mb_width * s->mb_height) / pic_param->num_macroblocks_in_gob;
00091 pic_param->TRB = s->pb_time;
00092 pic_param->TRD = s->pp_time;
00093
00094 if (s->pict_type == FF_B_TYPE)
00095 pic_param->backward_reference_picture = ff_vaapi_get_surface_id(&s->next_picture);
00096 if (s->pict_type != FF_I_TYPE)
00097 pic_param->forward_reference_picture = ff_vaapi_get_surface_id(&s->last_picture);
00098
00099
00100
00101 if (pic_param->vol_fields.bits.quant_type) {
00102 iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG4));
00103 if (!iq_matrix)
00104 return -1;
00105 iq_matrix->load_intra_quant_mat = 1;
00106 iq_matrix->load_non_intra_quant_mat = 1;
00107
00108 for (i = 0; i < 64; i++) {
00109 int n = s->dsp.idct_permutation[ff_zigzag_direct[i]];
00110 iq_matrix->intra_quant_mat[i] = s->intra_matrix[n];
00111 iq_matrix->non_intra_quant_mat[i] = s->inter_matrix[n];
00112 }
00113 }
00114 return 0;
00115 }
00116
00117 static int vaapi_mpeg4_end_frame(AVCodecContext *avctx)
00118 {
00119 return ff_vaapi_common_end_frame(avctx->priv_data);
00120 }
00121
00122 static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
00123 {
00124 MpegEncContext * const s = avctx->priv_data;
00125 VASliceParameterBufferMPEG4 *slice_param;
00126
00127 dprintf(avctx, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer, size);
00128
00129
00130
00131
00132
00133
00134 if (avctx->codec->id == CODEC_ID_H263)
00135 size = s->gb.buffer_end - buffer;
00136
00137
00138 slice_param = (VASliceParameterBufferMPEG4 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size);
00139 if (!slice_param)
00140 return -1;
00141 slice_param->macroblock_offset = get_bits_count(&s->gb) % 8;
00142 slice_param->macroblock_number = s->mb_y * s->mb_width + s->mb_x;
00143 slice_param->quant_scale = s->qscale;
00144
00145 if (avctx->codec->id == CODEC_ID_H263)
00146 s->mb_y = s->mb_height;
00147
00148 return 0;
00149 }
00150
00151 #if CONFIG_MPEG4_VAAPI_HWACCEL
00152 AVHWAccel mpeg4_vaapi_hwaccel = {
00153 .name = "mpeg4_vaapi",
00154 .type = AVMEDIA_TYPE_VIDEO,
00155 .id = CODEC_ID_MPEG4,
00156 .pix_fmt = PIX_FMT_VAAPI_VLD,
00157 .capabilities = 0,
00158 .start_frame = vaapi_mpeg4_start_frame,
00159 .end_frame = vaapi_mpeg4_end_frame,
00160 .decode_slice = vaapi_mpeg4_decode_slice,
00161 .priv_data_size = 0,
00162 };
00163 #endif
00164
00165 #if CONFIG_H263_VAAPI_HWACCEL
00166 AVHWAccel h263_vaapi_hwaccel = {
00167 .name = "h263_vaapi",
00168 .type = AVMEDIA_TYPE_VIDEO,
00169 .id = CODEC_ID_H263,
00170 .pix_fmt = PIX_FMT_VAAPI_VLD,
00171 .capabilities = 0,
00172 .start_frame = vaapi_mpeg4_start_frame,
00173 .end_frame = vaapi_mpeg4_end_frame,
00174 .decode_slice = vaapi_mpeg4_decode_slice,
00175 .priv_data_size = 0,
00176 };
00177 #endif