Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
  }
}