コード例 #1
0
ファイル: gstvdpmpegdec.c プロジェクト: zsx/ossbuild
static GstStateChangeReturn
gst_vdp_mpeg_dec_change_state (GstElement * element, GstStateChange transition)
{
    GstVdpMpegDec *mpeg_dec;
    GstStateChangeReturn ret;

    mpeg_dec = GST_VDP_MPEG_DEC (element);

    switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
        gst_vdp_mpeg_dec_start (mpeg_dec);
        break;
    default:
        break;
    }

    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

    switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
        gst_vdp_mpeg_dec_stop (mpeg_dec);
        break;
    default:
        break;
    }

    return ret;
}
コード例 #2
0
ファイル: gstvdpmpegdec.c プロジェクト: zsx/ossbuild
static gboolean
gst_vdp_mpeg_dec_src_event (GstPad * pad, GstEvent * event)
{
    GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad));
    gboolean res;

    switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
    {
        if ((res = gst_pad_event_default (pad, event)))
            goto done;

        res = normal_seek (mpeg_dec, event);

        break;
    }
    default:
        res = gst_pad_event_default (pad, event);
    }

done:
    gst_object_unref (mpeg_dec);

    return res;
}
コード例 #3
0
ファイル: gstvdpmpegdec.c プロジェクト: zsx/ossbuild
static gboolean
gst_vdp_mpeg_dec_src_query (GstPad * pad, GstQuery * query)
{
    GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad));
    gboolean res;

    switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
        GstFormat format;

        if ((res = gst_pad_query_default (pad, query)))
            goto done;

        gst_query_parse_position (query, &format, NULL);
        if (format == GST_FORMAT_TIME &&
                GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) {
            gst_query_set_position (query, GST_FORMAT_TIME,
                                    mpeg_dec->next_timestamp);
            res = TRUE;
        }
        break;
    }

    case GST_QUERY_DURATION:
    {
        GstFormat format;

        if ((res = gst_pad_query_default (pad, query)))
            goto done;

        gst_query_parse_duration (query, &format, NULL);
        if (format == GST_FORMAT_TIME) {
            gint64 bytes;

            format = GST_FORMAT_BYTES;
            if (gst_pad_query_duration (pad, &format, &bytes)
                    && format == GST_FORMAT_BYTES) {
                gint64 duration;

                if (gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_BYTES,
                                              bytes, GST_FORMAT_TIME, &duration)) {
                    GST_DEBUG ("duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (duration));
                    gst_query_set_duration (query, GST_FORMAT_TIME, duration);
                    res = TRUE;
                }
            }
        }
        break;
    }

    default:
        res = gst_pad_query_default (pad, query);
    }

done:
    gst_object_unref (mpeg_dec);

    return res;
}
コード例 #4
0
static gboolean
gst_vdp_mpeg_dec_stop (GstBaseVideoDecoder * base_video_decoder)
{
  GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);

  if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE)
    mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE;
  if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE)
    mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE;

  mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE;

  return GST_BASE_VIDEO_DECODER_CLASS (parent_class)->stop (base_video_decoder);
}
コード例 #5
0
static gboolean
gst_vdp_mpeg_dec_start (GstBaseVideoDecoder * base_video_decoder)
{
  GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);

  gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info);

  mpeg_dec->decoder = VDP_INVALID_HANDLE;
  mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE;

  memset (&mpeg_dec->stream_info, 0, sizeof (GstVdpMpegStreamInfo));

  return GST_BASE_VIDEO_DECODER_CLASS
      (parent_class)->start (base_video_decoder);
}
コード例 #6
0
static gboolean
gst_vdp_mpeg_dec_flush (GstBaseVideoDecoder * base_video_decoder)
{
  GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);

  if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE)
    gst_video_frame_unref (mpeg_dec->f_frame);
  if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE)
    gst_video_frame_unref (mpeg_dec->b_frame);

  gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info);

  mpeg_dec->prev_packet = -1;

  return TRUE;
}
コード例 #7
0
static GstFlowReturn
gst_vdp_mpeg_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
    GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame)
{
  GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);

  GstVdpMpegFrame *mpeg_frame;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);
  guint8 start_code;

  if (gst_bit_reader_get_remaining (&b_reader) < 8 * 3 + 8)
    return GST_FLOW_ERROR;

  /* skip sync_code */
  gst_bit_reader_skip_unchecked (&b_reader, 8 * 3);

  /* start_code */
  start_code = gst_bit_reader_get_bits_uint8_unchecked (&b_reader, 8);

  mpeg_frame = GST_VDP_MPEG_FRAME_CAST (frame);

  if (start_code >= MPEG_PACKET_SLICE_MIN
      && start_code <= MPEG_PACKET_SLICE_MAX) {
    GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE");

    gst_vdp_mpeg_frame_add_slice (mpeg_frame, buf);
    goto done;
  }

  switch (start_code) {
    case MPEG_PACKET_SEQUENCE:
      GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE");

      if (mpeg_dec->prev_packet != -1)
        ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
            (GstVideoFrame **) & mpeg_frame);

      mpeg_frame->seq = buf;
      break;

    case MPEG_PACKET_PICTURE:
      GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE");

      if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE &&
          mpeg_dec->prev_packet != MPEG_PACKET_GOP)
        ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
            (GstVideoFrame **) & mpeg_frame);

      mpeg_frame->pic = buf;
      break;

    case MPEG_PACKET_GOP:
      GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP");

      if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE)
        ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
            (GstVideoFrame **) & mpeg_frame);

      mpeg_frame->gop = buf;
      break;

    case MPEG_PACKET_EXTENSION:
    {
      guint8 ext_code;

      /* ext_code */
      if (!gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4)) {
        ret = GST_FLOW_ERROR;
        gst_buffer_unref (buf);
        goto done;
      }

      GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION: %d", ext_code);

      switch (ext_code) {
        case MPEG_PACKET_EXT_SEQUENCE:
          GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE");


          mpeg_frame->seq_ext = buf;

          /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE
           * or MPEG_PACKET_GOP after this */
          start_code = MPEG_PACKET_SEQUENCE;
          break;

        case MPEG_PACKET_EXT_SEQUENCE_DISPLAY:
          GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE_DISPLAY");

          /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE
           * or MPEG_PACKET_GOP after this */
          start_code = MPEG_PACKET_SEQUENCE;
          break;

        case MPEG_PACKET_EXT_PICTURE_CODING:
          GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING");

          mpeg_frame->pic_ext = buf;
          break;

        case MPEG_PACKET_EXT_QUANT_MATRIX:
          GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX");

          mpeg_frame->qm_ext = buf;
          break;

        default:
          gst_buffer_unref (buf);
      }
      break;
    }

    default:
      gst_buffer_unref (buf);
  }

  if (at_eos && mpeg_frame->slices)
    ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE, NULL);

done:
  mpeg_dec->prev_packet = start_code;

  return ret;
}
コード例 #8
0
static GstFlowReturn
gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
    GstVideoFrame * frame, GstClockTimeDiff deadline)
{
  GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);

  VdpPictureInfoMPEG1Or2 *info;
  GstVdpMpegFrame *mpeg_frame;

  GstFlowReturn ret = GST_FLOW_OK;
  VdpBitstreamBuffer vbit[1];
  GstVdpVideoBuffer *outbuf;

  /* MPEG_PACKET_SEQUENCE */
  mpeg_frame = GST_VDP_MPEG_FRAME (frame);
  if (mpeg_frame->seq) {
    ret = gst_vdp_mpeg_dec_handle_sequence (mpeg_dec, mpeg_frame->seq,
        mpeg_frame->seq_ext);
    if (ret != GST_FLOW_OK) {
      gst_base_video_decoder_skip_frame (base_video_decoder, frame);
      return ret;
    }
  }

  if (mpeg_dec->state == GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE) {
    GST_DEBUG_OBJECT (mpeg_dec, "Drop frame since we haven't found a "
        "MPEG_PACKET_SEQUENCE yet");

    gst_base_video_decoder_skip_frame (base_video_decoder, frame);
    return GST_FLOW_OK;
  }

  /* MPEG_PACKET_PICTURE */
  if (mpeg_frame->pic)
    gst_vdp_mpeg_dec_handle_picture (mpeg_dec, mpeg_frame->pic);

  /* MPEG_PACKET_EXT_PICTURE_CODING */
  if (mpeg_frame->pic_ext)
    gst_vdp_mpeg_dec_handle_picture_coding (mpeg_dec, mpeg_frame->pic_ext,
        frame);

  /* MPEG_PACKET_GOP */
  if (mpeg_frame->gop)
    gst_vdp_mpeg_dec_handle_gop (mpeg_dec, mpeg_frame->gop);

  /* MPEG_PACKET_EXT_QUANT_MATRIX */
  if (mpeg_frame->qm_ext)
    gst_vdp_mpeg_dec_handle_quant_matrix (mpeg_dec, mpeg_frame->qm_ext);


  info = &mpeg_dec->vdp_info;

  info->slice_count = mpeg_frame->n_slices;

  /* check if we can decode the frame */
  if (info->picture_coding_type != I_FRAME
      && info->backward_reference == VDP_INVALID_HANDLE) {
    GST_DEBUG_OBJECT (mpeg_dec,
        "Drop frame since we haven't got an I_FRAME yet");

    gst_base_video_decoder_skip_frame (base_video_decoder, frame);
    return GST_FLOW_OK;
  }
  if (info->picture_coding_type == B_FRAME
      && info->forward_reference == VDP_INVALID_HANDLE) {
    GST_DEBUG_OBJECT (mpeg_dec,
        "Drop frame since we haven't got two non B_FRAMES yet");

    gst_base_video_decoder_skip_frame (base_video_decoder, frame);
    return GST_FLOW_OK;
  }


  if (info->picture_coding_type != B_FRAME) {
    if (info->backward_reference != VDP_INVALID_HANDLE) {
      ret = gst_base_video_decoder_finish_frame (base_video_decoder,
          mpeg_dec->b_frame);
    }

    if (info->forward_reference != VDP_INVALID_HANDLE) {
      gst_video_frame_unref (mpeg_dec->f_frame);
      info->forward_reference = VDP_INVALID_HANDLE;
    }

    info->forward_reference = info->backward_reference;
    mpeg_dec->f_frame = mpeg_dec->b_frame;

    info->backward_reference = VDP_INVALID_HANDLE;
  }

  if (ret != GST_FLOW_OK) {
    gst_base_video_decoder_skip_frame (base_video_decoder, frame);
    return ret;
  }

  /* decode */
  vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION;
  vbit[0].bitstream = GST_BUFFER_DATA (mpeg_frame->slices);
  vbit[0].bitstream_bytes = GST_BUFFER_SIZE (mpeg_frame->slices);

  ret = gst_vdp_decoder_render (GST_VDP_DECODER (mpeg_dec),
      (VdpPictureInfo *) info, 1, vbit, &outbuf);
  if (ret != GST_FLOW_OK)
    return ret;

  frame->src_buffer = GST_BUFFER_CAST (outbuf);

  if (info->picture_coding_type == B_FRAME) {
    ret = gst_base_video_decoder_finish_frame (base_video_decoder, frame);
  } else {
    info->backward_reference = GST_VDP_VIDEO_BUFFER (outbuf)->surface;
    mpeg_dec->b_frame = gst_video_frame_ref (frame);
  }

  return ret;
}
コード例 #9
0
ファイル: gstvdpmpegdec.c プロジェクト: zsx/ossbuild
static gboolean
gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event)
{
    GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad));
    gboolean res;

    switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
    {
        GST_DEBUG_OBJECT (mpeg_dec, "flush stop");

        gst_vdp_mpeg_dec_flush (mpeg_dec);
        res = gst_pad_push_event (mpeg_dec->src, event);

        break;
    }
    case GST_EVENT_NEWSEGMENT:
    {
        gboolean update;
        gdouble rate;
        GstFormat format;
        gint64 start;
        gint64 stop;
        gint64 position;

        gst_event_parse_new_segment (event, &update, &rate, &format,
                                     &start, &stop, &position);

        if (format != GST_FORMAT_TIME) {
            if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, start,
                                           GST_FORMAT_TIME, &start))
                goto convert_error;
            if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, stop,
                                           GST_FORMAT_TIME, &stop))
                goto convert_error;
            if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, position,
                                           GST_FORMAT_TIME, &position))
                goto convert_error;

            gst_event_unref (event);
            event = gst_event_new_new_segment (update, rate, GST_FORMAT_TIME, start,
                                               stop, position);
        }

        g_mutex_lock (mpeg_dec->mutex);
        /* if we seek ourselves we don't push out a newsegment now since we
         * use the calculated timestamp of the first frame for this */
        if (mpeg_dec->seeking) {
            gst_event_unref (event);
            res = TRUE;
            g_mutex_unlock (mpeg_dec->mutex);
            goto done;
        }
        g_mutex_unlock (mpeg_dec->mutex);

        GST_DEBUG_OBJECT (mpeg_dec,
                          "Pushing new segment update %d format %d start %"
                          GST_TIME_FORMAT " stop %" GST_TIME_FORMAT " position %"
                          GST_TIME_FORMAT, update, format, GST_TIME_ARGS (start),
                          GST_TIME_ARGS (stop), GST_TIME_ARGS (position));
convert_error:
        res = gst_pad_push_event (mpeg_dec->src, event);

        break;
    }
    default:
        res = gst_pad_event_default (pad, event);
    }

done:
    gst_object_unref (mpeg_dec);

    return res;
}
コード例 #10
0
ファイル: gstvdpmpegdec.c プロジェクト: zsx/ossbuild
static GstFlowReturn
gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer)
{
    GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad));
    GstVdpMpegPacketizer packetizer;
    GstBuffer *buf;
    GstFlowReturn ret = GST_FLOW_OK;

    if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) {
        GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer");
        gst_vdp_mpeg_dec_flush (mpeg_dec);
    }


    gst_vdp_mpeg_packetizer_init (&packetizer, buffer);
    while ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) {
        GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);
        guint32 sync_code;
        guint8 start_code;

        /* skip sync_code */
        gst_bit_reader_get_bits_uint32 (&b_reader, &sync_code, 8 * 3);

        /* start_code */
        gst_bit_reader_get_bits_uint8 (&b_reader, &start_code, 8);

        if (start_code >= MPEG_PACKET_SLICE_MIN
                && start_code <= MPEG_PACKET_SLICE_MAX) {
            GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE");

            gst_buffer_ref (buf);
            gst_adapter_push (mpeg_dec->adapter, buf);
            mpeg_dec->vdp_info.slice_count++;
        }

        switch (start_code) {
        case MPEG_PACKET_PICTURE:
            GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE");

            if (!gst_vdp_mpeg_dec_parse_picture (mpeg_dec, buf))
                goto done;

            break;
        case MPEG_PACKET_SEQUENCE:
            GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE");
            gst_vdp_mpeg_dec_parse_sequence (mpeg_dec, buf);
            break;
        case MPEG_PACKET_EXTENSION:
        {
            guint8 ext_code;

            GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION");

            /* ext_code */
            gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4);
            switch (ext_code) {
            case MPEG_PACKET_EXT_PICTURE_CODING:
                GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING");
                gst_vdp_mpeg_dec_parse_picture_coding (mpeg_dec, buf);
                break;
            case MPEG_PACKET_EXT_QUANT_MATRIX:
                GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX");
                gst_vdp_mpeg_dec_parse_quant_matrix (mpeg_dec, buf);
                break;
            default:
                break;
            }
            break;
        }
        case MPEG_PACKET_GOP:
            GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP");
            gst_vdp_mpeg_dec_parse_gop (mpeg_dec, buf);
            break;
        default:
            break;
        }

        gst_buffer_unref (buf);
    }

    if (mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_SEQUENCE ||
            mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_GOP) {
        gst_adapter_clear (mpeg_dec->adapter);
        goto done;
    }

    if (mpeg_dec->vdp_info.slice_count > 0)
        ret = gst_vdp_mpeg_dec_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer),
                                       GST_BUFFER_SIZE (buffer));

done:
    gst_object_unref (mpeg_dec);

    return ret;
}
コード例 #11
0
ファイル: gstvdpmpegdec.c プロジェクト: zsx/ossbuild
static gboolean
gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps)
{
    GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad));
    GstStructure *structure;

    gint width, height;
    gint fps_n, fps_d;
    gint par_n, par_d;
    gboolean interlaced = FALSE;

    GstCaps *src_caps;
    gboolean res;

    const GValue *value;

    structure = gst_caps_get_structure (caps, 0);

    /* create src_pad caps */
    gst_structure_get_int (structure, "width", &width);
    gst_structure_get_int (structure, "height", &height);
    gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d);
    gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n, &par_d);
    gst_structure_get_boolean (structure, "interlaced", &interlaced);

    src_caps = gst_caps_new_simple ("video/x-vdpau-video",
                                    "chroma-type", G_TYPE_INT, VDP_CHROMA_TYPE_420,
                                    "width", G_TYPE_INT, width,
                                    "height", G_TYPE_INT, height,
                                    "framerate", GST_TYPE_FRACTION, fps_n, fps_d,
                                    "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d,
                                    "interlaced", G_TYPE_BOOLEAN, interlaced, NULL);

    GST_DEBUG_OBJECT (mpeg_dec, "Setting source caps to %" GST_PTR_FORMAT,
                      src_caps);

    res = gst_pad_set_caps (mpeg_dec->src, src_caps);
    gst_caps_unref (src_caps);
    if (!res)
        goto done;

    mpeg_dec->width = width;
    mpeg_dec->height = height;
    mpeg_dec->fps_n = fps_n;
    mpeg_dec->fps_d = fps_d;
    mpeg_dec->interlaced = interlaced;

    /* parse caps to setup decoder */
    gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version);

    /* Default to MPEG1 until we find otherwise */
    mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG1;

    value = gst_structure_get_value (structure, "codec_data");
    if (value) {
        GstBuffer *codec_data, *buf;
        GstVdpMpegPacketizer packetizer;

        codec_data = gst_value_get_buffer (value);
        gst_vdp_mpeg_packetizer_init (&packetizer, codec_data);
        if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) {
            MPEGSeqHdr hdr;
            guint32 bitrate;

            mpeg_util_parse_sequence_hdr (&hdr, buf);

            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);

            bitrate = hdr.bitrate;
            gst_buffer_unref (buf);

            if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) {
                MPEGSeqExtHdr ext;

                mpeg_util_parse_sequence_extension (&ext, buf);
                if (mpeg_dec->version != 1) {
                    switch (ext.profile) {
                    case 5:
                        mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE;
                        break;
                    default:
                        mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
                        break;
                    }
                }

                bitrate += (ext.bitrate_ext << 18);
                gst_buffer_unref (buf);
            }

            mpeg_dec->duration =
                gst_util_uint64_scale (1, GST_SECOND * mpeg_dec->fps_d,
                                       mpeg_dec->fps_n);

            mpeg_dec->byterate = bitrate * 50;
            GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate);
        }
    }

    res = TRUE;

done:
    gst_object_unref (mpeg_dec);

    return res;
}