static gboolean gst_vdp_h264_dec_flush (GstBaseVideoDecoder * base_video_decoder) { GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); h264_dec->got_idr = FALSE; gst_h264_dpb_flush (h264_dec->dpb, FALSE); return TRUE; }
static GstFlowReturn 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; guint16 par_n, par_d; vui = &seq->vui_parameters; if (gst_vdp_h264_dec_calculate_par (vui, &par_n, &par_d)) { state.par_n = par_n; state.par_d = par_d; } 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 GstFlowReturn gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstVideoCodecFrame * frame, GstH264SliceHdr * slice) { GstH264SPS *seq; GST_DEBUG_OBJECT (h264_dec, "Handling IDR slice"); h264_dec->poc_msb = 0; h264_dec->prev_poc_lsb = 0; 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->pps->sequence; if (seq->id != h264_dec->current_sps) { GstVideoCodecState *state; VdpDecoderProfile profile; GstFlowReturn ret; GST_DEBUG_OBJECT (h264_dec, "Sequence changed !"); state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (h264_dec), GST_VIDEO_FORMAT_YV12, seq->width, seq->height, h264_dec->input_state); /* calculate framerate if we haven't got one */ if (state->info.fps_n == 0) { state->info.fps_n = seq->fps_num; state->info.fps_d = seq->fps_den; } if (state->info.par_n == 0 && seq->vui_parameters_present_flag) { state->info.par_n = seq->vui_parameters.par_n; state->info.par_d = seq->vui_parameters.par_d; } if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (h264_dec))) goto nego_fail; 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: goto profile_not_suported; } ret = gst_vdp_decoder_init_decoder (GST_VDP_DECODER (h264_dec), profile, seq->num_ref_frames, h264_dec->input_state); if (ret != GST_FLOW_OK) return ret; g_object_set (h264_dec->dpb, "num-ref-frames", seq->num_ref_frames, NULL); h264_dec->current_sps = seq->id; } return GST_FLOW_OK; profile_not_suported: { 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; } nego_fail: { GST_ERROR_OBJECT (h264_dec, "Negotiation failed"); return GST_FLOW_NOT_NEGOTIATED; } }