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