diff options
-rw-r--r-- | sys/vdpau/gstvdpmpegdecoder.c | 110 | ||||
-rw-r--r-- | sys/vdpau/gstvdpmpegdecoder.h | 2 | ||||
-rw-r--r-- | sys/vdpau/mpegutil.c | 5 | ||||
-rw-r--r-- | sys/vdpau/mpegutil.h | 1 |
4 files changed, 117 insertions, 1 deletions
diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 008a2428..19c096f6 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -220,6 +220,7 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) 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); @@ -228,6 +229,7 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) 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))) { @@ -245,8 +247,12 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) } } + bitrate += (ext.bitrate_ext << 18);; gst_buffer_unref (buf); } + + mpeg_dec->byterate = bitrate * 50; + GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate); } } @@ -526,6 +532,8 @@ gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); gst_adapter_clear (mpeg_dec->adapter); + + //mpeg_dec->byterate = -1; } static GstFlowReturn @@ -617,6 +625,105 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) } static gboolean +gst_vdp_mpeg_decoder_convert (GstVdpMpegDecoder * mpeg_dec, + GstFormat src_format, gint64 src_value, + GstFormat dest_format, gint64 * dest_value) +{ + + if (src_format == dest_format) { + *dest_value = src_value; + return TRUE; + } + + if (mpeg_dec->byterate == -1) + return FALSE; + + if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_TIME) { + *dest_value = gst_util_uint64_scale (GST_SECOND, src_value, + mpeg_dec->byterate); + return TRUE; + } + + if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) { + *dest_value = + gst_util_uint64_scale_int (src_value, mpeg_dec->byterate, GST_SECOND); + return TRUE; + } + + return FALSE; +} + +static const GstQueryType * +gst_mpeg_decoder_get_querytypes (GstPad * pad) +{ + static const GstQueryType list[] = { + GST_QUERY_POSITION, + GST_QUERY_DURATION, + 0 + }; + + return list; +} + +static gboolean +gst_vdp_mpeg_decoder_src_query (GstPad * pad, GstQuery * query) +{ + GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + gboolean res = FALSE; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + { + GstFormat format; + + if (gst_pad_query_default (pad, query)) + return TRUE; + + 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 (gst_pad_query_default (pad, query)) + return TRUE; + + 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_decoder_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); + } + + return res; +} + +static gboolean gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) { GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); @@ -737,6 +844,9 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, GstVdpMpegDecoderClass * gclass) { mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_set_query_function (mpeg_dec->src, gst_vdp_mpeg_decoder_src_query); + gst_pad_set_query_type_function (mpeg_dec->src, + gst_mpeg_decoder_get_querytypes); gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->src); mpeg_dec->sink = gst_pad_new_from_static_template (&sink_template, "sink"); diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index facc791b..597101f8 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -62,6 +62,8 @@ struct _GstVdpMpegDecoder gboolean broken_gop; GstClockTime duration; GstClockTime next_timestamp; + + gint64 byterate; GstAdapter *adapter; }; diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index bba84f2b..5348bd6a 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -135,8 +135,11 @@ mpeg_util_parse_sequence_extension (MPEGSeqExtHdr * hdr, GstBuffer * buffer) if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->vert_size_ext, 2)) return FALSE; + if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->bitrate_ext, 12)) + return FALSE; + /* skip to framerate extension */ - if (!gst_bit_reader_skip (&reader, 22)) + if (!gst_bit_reader_skip (&reader, 9)) return FALSE; /* framerate extension */ diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h index 08f6cc2f..aaaa15f8 100644 --- a/sys/vdpau/mpegutil.h +++ b/sys/vdpau/mpegutil.h @@ -83,6 +83,7 @@ struct MPEGSeqExtHdr guint8 horiz_size_ext, vert_size_ext; + guint16 bitrate_ext; guint8 fps_n_ext, fps_d_ext; }; |