예제 #1
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;
}
예제 #2
0
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;
}