static VdpPictureInfoMPEG4Part2 gst_vdp_mpeg4_dec_fill_info (GstVdpMpeg4Dec * mpeg4_dec, GstMpeg4Frame * mpeg4_frame, Mpeg4VideoObjectPlane * vop) { Mpeg4VideoObjectLayer *vol; VdpPictureInfoMPEG4Part2 info; vol = &mpeg4_dec->vol; info.forward_reference = VDP_INVALID_HANDLE; info.backward_reference = VDP_INVALID_HANDLE; /* forward reference */ if (vop->coding_type != I_VOP && mpeg4_dec->f_frame) { info.forward_reference = GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME (mpeg4_dec-> f_frame)->src_buffer)->surface; } if (vop->coding_type == B_VOP) { guint32 trd_time, trb_time; trd_time = mpeg4_dec->b_frame->vop_time - mpeg4_dec->f_frame->vop_time; trb_time = mpeg4_frame->vop_time - mpeg4_dec->f_frame->vop_time; info.trd[0] = trd_time; info.trb[0] = trb_time; info.trd[1] = round ((double) trd_time / (double) mpeg4_dec->tframe); info.trb[1] = round ((double) trb_time / (double) mpeg4_dec->tframe); /* backward reference */ if (mpeg4_dec->b_frame) { info.backward_reference = GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME (mpeg4_dec-> b_frame)->src_buffer)->surface; } } memcpy (info.intra_quantizer_matrix, vol->intra_quant_mat, 64); memcpy (info.non_intra_quantizer_matrix, vol->non_intra_quant_mat, 64); info.vop_time_increment_resolution = vol->vop_time_increment_resolution; info.resync_marker_disable = vol->resync_marker_disable; info.interlaced = vol->interlaced; info.quant_type = vol->quant_type; info.quarter_sample = vol->quarter_sample; /* FIXME: support short video header */ info.short_video_header = FALSE; info.vop_coding_type = vop->coding_type; info.vop_fcode_forward = vop->fcode_forward; info.vop_fcode_backward = vop->fcode_backward; info.rounding_control = vop->rounding_type; info.alternate_vertical_scan_flag = vop->alternate_vertical_scan_flag; info.top_field_first = vop->top_field_first; return info; }
static GstVideoFrame * gst_vdp_mpeg_dec_create_frame (GstBaseVideoDecoder * base_video_decoder) { return GST_VIDEO_FRAME (gst_vdp_mpeg_frame_new ()); }
static gboolean gst_vdp_mpeg4_dec_handle_configuration (GstVdpMpeg4Dec * mpeg4_dec, GstMpeg4Frame * mpeg4_frame) { Mpeg4VisualObjectSequence vos; Mpeg4VisualObject vo; Mpeg4VideoObjectLayer vol; GstVideoState state; guint8 profile_indication; VdpDecoderProfile profile; GstFlowReturn ret; if (mpeg4_dec->is_configured) return GST_FLOW_OK; if (!mpeg4_frame->vos_buf || !mpeg4_frame->vo_buf || !mpeg4_frame->vol_buf) goto skip_frame; if (!mpeg4_util_parse_VOS (mpeg4_frame->vos_buf, &vos)) goto skip_frame; if (!mpeg4_util_parse_VO (mpeg4_frame->vo_buf, &vo)) goto skip_frame; if (!mpeg4_util_parse_VOL (mpeg4_frame->vol_buf, &vo, &vol)) goto skip_frame; state = gst_base_video_decoder_get_state (GST_BASE_VIDEO_DECODER (mpeg4_dec)); state.width = vol.width; state.height = vol.height; if (vol.fixed_vop_rate) { state.fps_n = vol.vop_time_increment_resolution; state.fps_d = vol.fixed_vop_time_increment; } state.par_n = vol.par_n; state.par_d = vol.par_d; gst_base_video_decoder_set_state (GST_BASE_VIDEO_DECODER (mpeg4_dec), state); profile_indication = vos.profile_and_level_indication >> 4; switch (profile_indication) { case 0x0: profile = VDP_DECODER_PROFILE_MPEG4_PART2_SP; break; case 0xf: profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; break; default: goto unsupported_profile; } ret = gst_vdp_decoder_init_decoder (GST_VDP_DECODER (mpeg4_dec), profile, 2); if (ret != GST_FLOW_OK) return ret; mpeg4_dec->vol = vol; mpeg4_dec->is_configured = TRUE; return GST_FLOW_OK; skip_frame: GST_WARNING ("Skipping frame since we're not configured yet"); gst_base_video_decoder_skip_frame (GST_BASE_VIDEO_DECODER (mpeg4_dec), GST_VIDEO_FRAME (mpeg4_frame)); return GST_FLOW_CUSTOM_ERROR; unsupported_profile: GST_ELEMENT_ERROR (mpeg4_dec, STREAM, WRONG_TYPE, ("vdpaumpeg4dec doesn't support this streams profile"), ("profile_and_level_indication: %d", vos.profile_and_level_indication)); return GST_FLOW_ERROR; }