static gboolean gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstH264Frame * h264_frame) { GstH264Slice *slice; GstH264Sequence *seq; h264_dec->poc_msb = 0; h264_dec->prev_poc_lsb = 0; slice = &h264_frame->slice_hdr; if (slice->dec_ref_pic_marking.no_output_of_prior_pics_flag) gst_h264_dpb_flush (h264_dec->dpb, FALSE); else gst_h264_dpb_flush (h264_dec->dpb, TRUE); if (slice->dec_ref_pic_marking.long_term_reference_flag) g_object_set (h264_dec->dpb, "max-longterm-frame-idx", 0, NULL); else g_object_set (h264_dec->dpb, "max-longterm-frame-idx", -1, NULL); seq = slice->picture->sequence; if (seq != h264_dec->sequence) { GstVideoState state; VdpDecoderProfile profile; GstFlowReturn ret; state = gst_base_video_decoder_get_state (GST_BASE_VIDEO_DECODER (h264_dec)); state.width = (seq->pic_width_in_mbs_minus1 + 1) * 16 - 2 * seq->frame_crop_right_offset; state.height = (2 - seq->frame_mbs_only_flag) * (seq->pic_height_in_map_units_minus1 + 1) * 16; if (seq->frame_mbs_only_flag) state.height -= 2 * seq->frame_crop_bottom_offset; else state.height -= 4 * seq->frame_crop_bottom_offset; /* calculate framerate if we haven't got one */ if (state.fps_n == 0 && seq->vui_parameters_present_flag) { GstH264VUIParameters *vui; vui = &seq->vui_parameters; if (vui->timing_info_present_flag && vui->fixed_frame_rate_flag) { state.fps_n = vui->time_scale; state.fps_d = vui->num_units_in_tick; if (seq->frame_mbs_only_flag) state.fps_d *= 2; } } gst_base_video_decoder_set_state (GST_BASE_VIDEO_DECODER (h264_dec), state); switch (seq->profile_idc) { case 66: profile = VDP_DECODER_PROFILE_H264_BASELINE; break; case 77: profile = VDP_DECODER_PROFILE_H264_MAIN; break; case 100: profile = VDP_DECODER_PROFILE_H264_HIGH; break; default: GST_ELEMENT_ERROR (h264_dec, STREAM, WRONG_TYPE, ("vdpauh264dec doesn't support this streams profile"), ("profile_idc: %d", seq->profile_idc)); return GST_FLOW_ERROR; } ret = gst_vdp_decoder_init_decoder (GST_VDP_DECODER (h264_dec), profile, seq->num_ref_frames); if (ret != GST_FLOW_OK) return ret; g_object_set (h264_dec->dpb, "num-ref-frames", seq->num_ref_frames, NULL); h264_dec->sequence = seq; } return GST_FLOW_OK; }
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; }
static GstFlowReturn gst_vdp_mpeg_dec_handle_sequence (GstVdpMpegDec * mpeg_dec, GstBuffer * seq, GstBuffer * seq_ext) { GstBaseVideoDecoder *base_video_decoder = GST_BASE_VIDEO_DECODER (mpeg_dec); MPEGSeqHdr hdr; GstVdpMpegStreamInfo stream_info; if (!mpeg_util_parse_sequence_hdr (&hdr, seq)) return GST_FLOW_CUSTOM_ERROR; memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, &hdr.intra_quantizer_matrix, 64); memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, &hdr.non_intra_quantizer_matrix, 64); stream_info.width = hdr.width; stream_info.height = hdr.height; stream_info.fps_n = hdr.fps_n; stream_info.fps_d = hdr.fps_d; stream_info.par_n = hdr.par_w; stream_info.par_d = hdr.par_h; stream_info.interlaced = FALSE; stream_info.version = 1; stream_info.profile = VDP_DECODER_PROFILE_MPEG1; if (seq_ext) { MPEGSeqExtHdr ext; if (!mpeg_util_parse_sequence_extension (&ext, seq_ext)) return GST_FLOW_CUSTOM_ERROR; stream_info.fps_n *= (ext.fps_n_ext + 1); stream_info.fps_d *= (ext.fps_d_ext + 1); stream_info.width += (ext.horiz_size_ext << 12); stream_info.height += (ext.vert_size_ext << 12); stream_info.interlaced = !ext.progressive; stream_info.version = 2; stream_info.profile = gst_vdp_mpeg_dec_get_profile (&ext); } if (memcmp (&mpeg_dec->stream_info, &stream_info, sizeof (GstVdpMpegStreamInfo)) != 0) { GstVideoState state; GstFlowReturn ret; state = gst_base_video_decoder_get_state (base_video_decoder); state.width = stream_info.width; state.height = stream_info.height; state.fps_n = stream_info.fps_n; state.fps_d = stream_info.fps_d; state.par_n = stream_info.par_n; state.par_d = stream_info.par_d; state.interlaced = stream_info.interlaced; gst_base_video_decoder_set_state (base_video_decoder, state); ret = gst_vdp_decoder_init_decoder (GST_VDP_DECODER (mpeg_dec), stream_info.profile, 2); if (ret != GST_FLOW_OK) return ret; memcpy (&mpeg_dec->stream_info, &stream_info, sizeof (GstVdpMpegStreamInfo)); } mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_DATA; return GST_FLOW_OK; }