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