static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { MpegEncContext * const s = avctx->priv_data; struct vaapi_context * const vactx = avctx->hwaccel_context; VAPictureParameterBufferMPEG4 *pic_param; VAIQMatrixBufferMPEG4 *iq_matrix; int i; av_dlog(avctx, "vaapi_mpeg4_start_frame()\n"); vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG4); /* Fill in VAPictureParameterBufferMPEG4 */ pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG4)); if (!pic_param) return -1; pic_param->vop_width = s->width; pic_param->vop_height = s->height; pic_param->forward_reference_picture = VA_INVALID_ID; pic_param->backward_reference_picture = VA_INVALID_ID; pic_param->vol_fields.value = 0; /* reset all bits */ pic_param->vol_fields.bits.short_video_header = avctx->codec->id == AV_CODEC_ID_H263; pic_param->vol_fields.bits.chroma_format = CHROMA_420; pic_param->vol_fields.bits.interlaced = !s->progressive_sequence; pic_param->vol_fields.bits.obmc_disable = 1; pic_param->vol_fields.bits.sprite_enable = s->vol_sprite_usage; pic_param->vol_fields.bits.sprite_warping_accuracy = s->sprite_warping_accuracy; pic_param->vol_fields.bits.quant_type = s->mpeg_quant; pic_param->vol_fields.bits.quarter_sample = s->quarter_sample; pic_param->vol_fields.bits.data_partitioned = s->data_partitioning; pic_param->vol_fields.bits.reversible_vlc = s->rvlc; pic_param->vol_fields.bits.resync_marker_disable = !s->resync_marker; pic_param->no_of_sprite_warping_points = s->num_sprite_warping_points; for (i = 0; i < s->num_sprite_warping_points && i < 3; i++) { pic_param->sprite_trajectory_du[i] = s->sprite_traj[i][0]; pic_param->sprite_trajectory_dv[i] = s->sprite_traj[i][1]; } pic_param->quant_precision = s->quant_precision; pic_param->vop_fields.value = 0; /* reset all bits */ pic_param->vop_fields.bits.vop_coding_type = s->pict_type - AV_PICTURE_TYPE_I; 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; pic_param->vop_fields.bits.vop_rounding_type = s->no_rounding; pic_param->vop_fields.bits.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(s); pic_param->vop_fields.bits.top_field_first = s->top_field_first; pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan; pic_param->vop_fcode_forward = s->f_code; pic_param->vop_fcode_backward = s->b_code; pic_param->vop_time_increment_resolution = avctx->time_base.den; pic_param->num_macroblocks_in_gob = s->mb_width * ff_h263_get_gob_height(s); pic_param->num_gobs_in_vop = (s->mb_width * s->mb_height) / pic_param->num_macroblocks_in_gob; pic_param->TRB = s->pb_time; pic_param->TRD = s->pp_time; if (s->pict_type == AV_PICTURE_TYPE_B) pic_param->backward_reference_picture = ff_vaapi_get_surface_id(&s->next_picture); if (s->pict_type != AV_PICTURE_TYPE_I) pic_param->forward_reference_picture = ff_vaapi_get_surface_id(&s->last_picture); /* Fill in VAIQMatrixBufferMPEG4 */ /* Only the first inverse quantisation method uses the weighting matrices */ if (pic_param->vol_fields.bits.quant_type) { iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG4)); if (!iq_matrix) return -1; iq_matrix->load_intra_quant_mat = 1; iq_matrix->load_non_intra_quant_mat = 1; for (i = 0; i < 64; i++) { int n = s->dsp.idct_permutation[ff_zigzag_direct[i]]; iq_matrix->intra_quant_mat[i] = s->intra_matrix[n]; iq_matrix->non_intra_quant_mat[i] = s->inter_matrix[n]; } } return 0; }
int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { MpegEncContext *s = avctx->priv_data; int ret; AVFrame *pict = data; #ifdef PRINT_FRAME_TIME uint64_t time= rdtsc(); #endif #ifdef DEBUG av_log(avctx, AV_LOG_DEBUG, "*****frame %d size=%d\n", avctx->frame_number, buf_size); if(buf_size>0) av_log(avctx, AV_LOG_DEBUG, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); #endif s->flags= avctx->flags; s->flags2= avctx->flags2; /* no supplementary picture */ if (buf_size == 0) { /* special case for last picture */ if (s->low_delay==0 && s->next_picture_ptr) { *pict= *(AVFrame*)s->next_picture_ptr; s->next_picture_ptr= NULL; *data_size = sizeof(AVFrame); } return 0; } retry: init_get_bits(&s->gb, buf, buf_size*8); s->bitstream_buffer_size=0; if (!s->context_initialized) { if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix return -1; } /* We need to set current_picture_ptr before reading the header, * otherwise we cannot store anyting in there */ if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ int i= ff_find_unused_picture(s, 0); s->current_picture_ptr= &s->picture[i]; } ret = flv_h263_decode_picture_header(s); if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size); /* skip if the header was thrashed */ if (ret < 0){ av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); return -1; } avctx->has_b_frames= !s->low_delay; /* After H263 & mpeg4 header decode we have the height, width,*/ /* and other parameters. So then we could init the picture */ /* FIXME: By the way H263 decoder is evolving it should have */ /* an H263EncContext */ if ( s->width != avctx->coded_width || s->height != avctx->coded_height) { /* H.263 could change picture size any time */ ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat s->parse_context.buffer=0; MPV_common_end(s); s->parse_context= pc; } if (!s->context_initialized) { avcodec_set_dimensions(avctx, s->width, s->height); goto retry; } if((s->codec_id==CODEC_ID_H263 || s->codec_id==CODEC_ID_H263P)) s->gob_index = ff_h263_get_gob_height(s); // for hurry_up==5 s->current_picture.pict_type= s->pict_type; s->current_picture.key_frame= s->pict_type == FF_I_TYPE; /* skip B-frames if we don't have reference frames */ if(s->last_picture_ptr==NULL && (s->pict_type==FF_B_TYPE || s->dropable)) return get_consumed_bytes(s, buf_size); /* skip b frames if we are in a hurry */ if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return get_consumed_bytes(s, buf_size); if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE) || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE) || avctx->skip_frame >= AVDISCARD_ALL) return get_consumed_bytes(s, buf_size); /* skip everything if we are in a hurry>=5 */ if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); if(s->next_p_frame_damaged){ if(s->pict_type==FF_B_TYPE) return get_consumed_bytes(s, buf_size); else s->next_p_frame_damaged=0; } if((s->avctx->flags2 & CODEC_FLAG2_FAST) && s->pict_type==FF_B_TYPE){ s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab; s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab; }else if((!s->no_rounding) || s->pict_type==FF_B_TYPE){ s->me.qpel_put= s->dsp.put_qpel_pixels_tab; s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; }else{ s->me.qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab; s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; } if(MPV_frame_start(s, avctx) < 0) return -1; /* decode each macroblock */ s->mb_x=0; s->mb_y=0; decode_slice(s); while(s->mb_y<s->mb_height){ if(ff_h263_resync(s)<0) break; decode_slice(s); } intrax8_decoded: MPV_frame_end(s); assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type); assert(s->current_picture.pict_type == s->pict_type); if (s->pict_type == FF_B_TYPE || s->low_delay) { *pict= *(AVFrame*)s->current_picture_ptr; } else if (s->last_picture_ptr != NULL) { *pict= *(AVFrame*)s->last_picture_ptr; } if(s->last_picture_ptr || s->low_delay){ *data_size = sizeof(AVFrame); ff_print_debug_info(s, pict); } /* Return the Picture timestamp as the frame number */ /* we subtract 1 because it is added on utils.c */ avctx->frame_number = s->picture_number - 1; #ifdef PRINT_FRAME_TIME av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time); #endif return get_consumed_bytes(s, buf_size); }