Example #1
0
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;
}
Example #3
0
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;
}