ext/mpeg2dec/gstmpeg2dec.c: Don't send things to NULL PAD_PEERs

Original commit message from CVS:
* ext/mpeg2dec/gstmpeg2dec.c:
Don't send things to NULL PAD_PEERs

* gst/deinterlace/gstdeinterlace.c: (gst_deinterlace_chain):
Copy-on-write the incoming buffer.

* gst/mpegstream/gstdvddemux.h:
* gst/mpegstream/gstmpegclock.h:
* gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_parse_syshead),
(normal_seek), (gst_mpeg_demux_handle_src_event):
* gst/mpegstream/gstmpegdemux.h:
* gst/mpegstream/gstmpegpacketize.h:
* gst/mpegstream/gstmpegparse.c:
(gst_mpeg_parse_update_streaminfo), (gst_mpeg_parse_reset),
(gst_mpeg_parse_handle_discont), (gst_mpeg_parse_parse_packhead),
(gst_mpeg_parse_loop), (gst_mpeg_parse_get_rate),
(gst_mpeg_parse_convert_src), (gst_mpeg_parse_handle_src_query),
(gst_mpeg_parse_handle_src_event), (gst_mpeg_parse_change_state):
* gst/mpegstream/gstmpegparse.h:
* gst/mpegstream/gstrfc2250enc.h:
Various changes to the way time is computed that make seeking and
total time estimation much better here.
Use G_BEGIN/END_DECLS instead of __cplusplus

* gst/videocrop/gstvideocrop.c: (gst_video_crop_chain):
Use gst_buffer_stamp instead of only copying the TIMESTAMP
This commit is contained in:
Jan Schmidt 2005-02-01 16:40:10 +00:00
parent 501290be01
commit 3ef22c4774
10 changed files with 322 additions and 167 deletions

View file

@ -1,3 +1,32 @@
2005-02-02 Jan Schmidt <thaytan@mad.scientist.com>
* ext/mpeg2dec/gstmpeg2dec.c:
Don't send things to NULL PAD_PEERs
* gst/deinterlace/gstdeinterlace.c: (gst_deinterlace_chain):
Copy-on-write the incoming buffer.
* gst/mpegstream/gstdvddemux.h:
* gst/mpegstream/gstmpegclock.h:
* gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_parse_syshead),
(normal_seek), (gst_mpeg_demux_handle_src_event):
* gst/mpegstream/gstmpegdemux.h:
* gst/mpegstream/gstmpegpacketize.h:
* gst/mpegstream/gstmpegparse.c:
(gst_mpeg_parse_update_streaminfo), (gst_mpeg_parse_reset),
(gst_mpeg_parse_handle_discont), (gst_mpeg_parse_parse_packhead),
(gst_mpeg_parse_loop), (gst_mpeg_parse_get_rate),
(gst_mpeg_parse_convert_src), (gst_mpeg_parse_handle_src_query),
(gst_mpeg_parse_handle_src_event), (gst_mpeg_parse_change_state):
* gst/mpegstream/gstmpegparse.h:
* gst/mpegstream/gstrfc2250enc.h:
Various changes to the way time is computed that make seeking and
total time estimation much better here.
Use G_BEGIN/END_DECLS instead of __cplusplus
* gst/videocrop/gstvideocrop.c: (gst_video_crop_chain):
Use gst_buffer_stamp instead of only copying the TIMESTAMP
2005-02-01 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* gst/subparse/gstsubparse.c:

View file

@ -1062,7 +1062,7 @@ gst_mpeg2dec_src_query (GstPad * pad, GstQueryType type,
{
gboolean res = TRUE;
GstMpeg2dec *mpeg2dec;
static const GstFormat *formats;
static const GstFormat *formats = NULL;
mpeg2dec = GST_MPEG2DEC (gst_pad_get_parent (pad));
@ -1077,10 +1077,11 @@ gst_mpeg2dec_src_query (GstPad * pad, GstQueryType type,
res = FALSE;
/* get our peer formats */
formats = gst_pad_get_formats (GST_PAD_PEER (mpeg2dec->sinkpad));
if (GST_PAD_PEER (mpeg2dec->sinkpad))
formats = gst_pad_get_formats (GST_PAD_PEER (mpeg2dec->sinkpad));
/* while we did not exhaust our seek formats without result */
while (formats && *formats) {
while (formats && *formats && !res) {
GstFormat peer_format;
gint64 peer_value;
@ -1152,7 +1153,7 @@ index_seek (GstPad * pad, GstEvent * event)
GST_INDEX_LOOKUP_BEFORE, GST_ASSOCIATION_FLAG_KEY_UNIT,
GST_EVENT_SEEK_FORMAT (event), GST_EVENT_SEEK_OFFSET (event));
if (entry) {
if ((entry) && GST_PAD_PEER (mpeg2dec->sinkpad)) {
const GstFormat *peer_formats, *try_formats;
/* since we know the exact byteoffset of the frame, make sure to seek on bytes first */
@ -1202,7 +1203,7 @@ normal_seek (GstPad * pad, GstEvent * event)
gint64 src_offset;
gboolean flush;
GstFormat format;
const GstFormat *peer_formats;
const GstFormat *peer_formats = NULL;
gboolean res = FALSE;
GstMpeg2dec *mpeg2dec;
@ -1222,7 +1223,8 @@ normal_seek (GstPad * pad, GstEvent * event)
flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH;
/* get our peer formats */
peer_formats = gst_pad_get_formats (GST_PAD_PEER (mpeg2dec->sinkpad));
if (GST_PAD_PEER (mpeg2dec->sinkpad))
peer_formats = gst_pad_get_formats (GST_PAD_PEER (mpeg2dec->sinkpad));
/* while we did not exhaust our seek formats without result */
while (peer_formats && *peer_formats) {
@ -1288,7 +1290,11 @@ gst_mpeg2dec_src_event (GstPad * pad, GstEvent * event)
break;
case GST_EVENT_NAVIGATION:
/* Forward a navigation event unchanged */
return gst_pad_send_event (GST_PAD_PEER (mpeg2dec->sinkpad), event);
if (GST_PAD_PEER (mpeg2dec->sinkpad))
return gst_pad_send_event (GST_PAD_PEER (mpeg2dec->sinkpad), event);
res = FALSE;
break;
default:
res = FALSE;
break;

View file

@ -25,11 +25,7 @@
#include <gst/gst.h>
#include "gstmpegdemux.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
#define GST_TYPE_DVD_DEMUX \
(gst_dvd_demux_get_type())
@ -139,10 +135,6 @@ GType gst_dvd_demux_get_type (void);
gboolean gst_dvd_demux_plugin_init (GstPlugin *plugin);
#ifdef __cplusplus
}
#endif /* __cplusplus */
G_END_DECLS
#endif /* __DVD_DEMUX_H__ */

View file

@ -26,10 +26,7 @@
#include <gst/gstsystemclock.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
#define GST_TYPE_MPEG_CLOCK \
(gst_mpeg_clock_get_type())
@ -63,9 +60,6 @@ GType gst_mpeg_clock_get_type (void);
GstClock* gst_mpeg_clock_new (gchar *name, GstMPEGClockGetTimeFunc func,
gpointer user_data);
#ifdef __cplusplus
}
#endif /* __cplusplus */
G_END_DECLS
#endif /* __GST_MPEG_CLOCK_H__ */

View file

@ -551,6 +551,9 @@ gst_mpeg_demux_parse_syshead (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
gint stream_count = (header_length - 6) / 3;
gint i, j = 0;
/* Reset the total_size_bound before counting it up */
mpeg_demux->total_size_bound = 0;
GST_DEBUG_OBJECT (mpeg_demux, "number of streams: %d ", stream_count);
for (i = 0; i < stream_count; i++) {
@ -618,19 +621,6 @@ gst_mpeg_demux_parse_syshead (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
outstream->index_id =
_demux_get_writer_id (mpeg_demux->index, outstream->pad);
}
if (GST_PAD_IS_USABLE (outstream->pad)) {
GstEvent *event;
GstClockTime time;
time = MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr
+ mpeg_parse->adjust) + mpeg_demux->adjust;
event = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
time, NULL);
gst_pad_push (outstream->pad, GST_DATA (event));
}
}
j++;
@ -1024,7 +1014,7 @@ normal_seek (GstPad * pad, GstEvent * event, gint64 * offset)
if (res) {
*offset = MAX (GST_EVENT_SEEK_OFFSET (event) - adjust, 0);
GST_CAT_DEBUG (GST_CAT_SEEK, "%s:%s guestimate %" G_GINT64_FORMAT
GST_CAT_DEBUG (GST_CAT_SEEK, "%s:%s guesstimate %" G_GINT64_FORMAT
" %s -> %" G_GINT64_FORMAT
" (total_size_bound = %" G_GINT64_FORMAT ")",
GST_DEBUG_PAD_NAME (pad),
@ -1063,9 +1053,12 @@ gst_mpeg_demux_handle_src_event (GstPad * pad, GstEvent * event)
break;
}
case GST_EVENT_NAVIGATION:
return gst_pad_send_event (GST_PAD_PEER (GST_MPEG_PARSE (mpeg_demux)->
sinkpad), event);
break;
{
GstPad *out = GST_PAD_PEER (GST_MPEG_PARSE (mpeg_demux)->sinkpad);
if (out && GST_PAD_IS_USABLE (out))
return gst_pad_send_event (out, event);
}
default:
gst_event_unref (event);
break;

View file

@ -25,11 +25,7 @@
#include <gst/gst.h>
#include "gstmpegparse.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
#define GST_TYPE_MPEG_DEMUX \
(gst_mpeg_demux_get_type())
@ -188,9 +184,6 @@ GType gst_mpeg_demux_get_type (void);
gboolean gst_mpeg_demux_plugin_init (GstPlugin *plugin);
#ifdef __cplusplus
}
#endif /* __cplusplus */
G_END_DECLS
#endif /* __MPEG_DEMUX_H__ */

View file

@ -25,10 +25,7 @@
#include <gst/gst.h>
#include <gst/bytestream/bytestream.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
#define PICTURE_START_CODE 0x00
#define SLICE_MIN_START_CODE 0x01
@ -71,9 +68,6 @@ void gst_mpeg_packetize_destroy (GstMPEGPacketize *packetize);
GstData* gst_mpeg_packetize_read (GstMPEGPacketize *packetize);
#ifdef __cplusplus
}
#endif /* __cplusplus */
G_END_DECLS
#endif /* __MPEGPACKETIZE_H__ */

View file

@ -27,12 +27,20 @@
static GstFormat scr_format;
GST_DEBUG_CATEGORY_STATIC (gstmpegparse_debug);
#define GST_CAT_DEFAULT (gstmpegparse_debug)
GST_DEBUG_CATEGORY_EXTERN (GST_CAT_SEEK);
#define MP_INVALID_SCR ((guint64)(-1))
#define MP_MUX_RATE_MULT 50
#define MP_MIN_VALID_BSS 8192
#define MP_MAX_VALID_BSS 16384
/*
* Hysteresis value to limit the
* total predicted time skipping about
*/
#define MP_SCR_RATE_HYST 0.08
/* elementfactory information */
static GstElementDetails mpeg_parse_details = {
@ -266,7 +274,7 @@ gst_mpeg_parse_update_streaminfo (GstMPEGParse * mpeg_parse)
gst_props_add_entry (props, (GstPropsEntry *) entry);
entry =
gst_props_entry_new ("bitrate", G_TYPE_INT (mpeg_parse->mux_rate * 400));
gst_props_entry_new ("bitrate", G_TYPE_INT (mpeg_parse->mux_rate * 8));
gst_props_add_entry (props, (GstPropsEntry *) entry);
caps = gst_caps_new ("mpeg_streaminfo",
@ -277,6 +285,27 @@ gst_mpeg_parse_update_streaminfo (GstMPEGParse * mpeg_parse)
}
#endif
static void
gst_mpeg_parse_reset (GstMPEGParse * mpeg_parse)
{
mpeg_parse->current_scr = 0;
mpeg_parse->bytes_since_scr = 0;
mpeg_parse->avg_bitrate_time = 0;
mpeg_parse->avg_bitrate_bytes = 0;
mpeg_parse->first_scr = MP_INVALID_SCR;
mpeg_parse->first_scr_pos = 0;
mpeg_parse->last_scr = MP_INVALID_SCR;
mpeg_parse->last_scr_pos = 0;
mpeg_parse->scr_rate = 0;
mpeg_parse->adjust = 0;
mpeg_parse->next_scr = 0;
mpeg_parse->mux_rate = 0;
mpeg_parse->discont_pending = FALSE;
mpeg_parse->scr_pending = FALSE;
}
static void
gst_mpeg_parse_handle_discont (GstMPEGParse * mpeg_parse, GstEvent * event)
{
@ -284,6 +313,10 @@ gst_mpeg_parse_handle_discont (GstMPEGParse * mpeg_parse, GstEvent * event)
g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS);
if (GST_EVENT_DISCONT_NEW_MEDIA (event)) {
gst_mpeg_parse_reset (mpeg_parse);
}
if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)
&& (GST_CLOCK_TIME_IS_VALID (time))) {
GST_DEBUG_OBJECT (mpeg_parse, "forwarding discontinuity, time: %0.3fs",
@ -423,15 +456,28 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
new_rate |= ((gint32) buf[1]) << 7;
new_rate |= buf[2] >> 1;
}
new_rate *= MP_MUX_RATE_MULT;
prev_scr = mpeg_parse->current_scr;
mpeg_parse->current_scr = scr;
mpeg_parse->scr_pending = FALSE;
if (mpeg_parse->next_scr == -1) {
if (mpeg_parse->next_scr == MP_INVALID_SCR) {
mpeg_parse->next_scr = mpeg_parse->current_scr;
}
if ((mpeg_parse->first_scr == MP_INVALID_SCR) ||
(mpeg_parse->current_scr < mpeg_parse->first_scr)) {
mpeg_parse->first_scr = mpeg_parse->current_scr;
mpeg_parse->first_scr_pos = gst_bytestream_tell (mpeg_parse->packetize->bs);
}
if ((mpeg_parse->last_scr == MP_INVALID_SCR) ||
(mpeg_parse->current_scr > mpeg_parse->last_scr)) {
mpeg_parse->last_scr = mpeg_parse->current_scr;
mpeg_parse->last_scr_pos = gst_bytestream_tell (mpeg_parse->packetize->bs);
}
GST_LOG_OBJECT (mpeg_parse,
"SCR is %" G_GUINT64_FORMAT
" (%" G_GUINT64_FORMAT ") next: %"
@ -449,9 +495,9 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
if (ABS ((gint64) mpeg_parse->next_scr - (gint64) (scr)) >
mpeg_parse->max_discont) {
GST_DEBUG ("discontinuity detected; expected: %" G_GUINT64_FORMAT " got: %"
G_GUINT64_FORMAT " real:%" G_GINT64_FORMAT " adjust:%" G_GINT64_FORMAT,
mpeg_parse->next_scr, mpeg_parse->current_scr + mpeg_parse->adjust,
mpeg_parse->current_scr, mpeg_parse->adjust);
G_GUINT64_FORMAT " adjusted:%" G_GINT64_FORMAT " adjust:%"
G_GINT64_FORMAT, mpeg_parse->next_scr, mpeg_parse->current_scr,
mpeg_parse->current_scr + mpeg_parse->adjust, mpeg_parse->adjust);
if (mpeg_parse->do_adjust) {
if (mpeg_parse->use_adjust) {
@ -472,23 +518,39 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
GST_FORMAT_TIME, MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr), 0);
}
if (mpeg_parse->current_scr > prev_scr) {
mpeg_parse->avg_bitrate_time +=
MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr - prev_scr);
mpeg_parse->avg_bitrate_bytes += mpeg_parse->bytes_since_scr;
}
if (mpeg_parse->mux_rate != new_rate) {
if (GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize)) {
mpeg_parse->mux_rate = new_rate;
} else {
} else if (mpeg_parse->avg_bitrate_bytes > MP_MIN_VALID_BSS) {
mpeg_parse->mux_rate =
(double) mpeg_parse->bytes_since_scr /
MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr -
prev_scr) / 50 * 1000000000;
GST_SECOND * mpeg_parse->avg_bitrate_bytes /
mpeg_parse->avg_bitrate_time;
}
//gst_mpeg_parse_update_streaminfo (mpeg_parse);
GST_DEBUG ("stream is %1.3fMbs, calculated over %1.3fkB",
(mpeg_parse->mux_rate * 400) / 1000000.0,
mpeg_parse->bytes_since_scr / 1000.0);
GST_DEBUG ("stream current is %1.3fMbs, calculated over %1.3fkB",
(mpeg_parse->mux_rate * 8) / 1048576.0,
mpeg_parse->bytes_since_scr / 1024.0);
}
if (mpeg_parse->avg_bitrate_bytes > MP_MAX_VALID_BSS) {
mpeg_parse->avg_bitrate_bytes = 0;
mpeg_parse->avg_bitrate_time = 0;
}
mpeg_parse->bytes_since_scr = 0;
if (mpeg_parse->avg_bitrate_bytes) {
GST_DEBUG ("stream avg is %1.3fMbs, calculated over %1.3fkB",
(float) (mpeg_parse->avg_bitrate_bytes) * 8 * GST_SECOND
/ mpeg_parse->avg_bitrate_time / 1048576.0,
mpeg_parse->avg_bitrate_bytes / 1024.0);
}
return TRUE;
}
@ -607,12 +669,12 @@ gst_mpeg_parse_loop (GstElement * element)
gst_element_wait (GST_ELEMENT (mpeg_parse), time);
}
if (mpeg_parse->current_scr != -1) {
if (mpeg_parse->current_scr != MP_INVALID_SCR) {
guint64 scr, bss, br;
scr = mpeg_parse->current_scr;
bss = mpeg_parse->bytes_since_scr;
br = mpeg_parse->mux_rate * 50;
br = mpeg_parse->mux_rate;
if (br) {
if (GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize)) {
@ -621,6 +683,7 @@ gst_mpeg_parse_loop (GstElement * element)
*
* mpeg_parse->next_scr = (scr * br + bss * CLOCK_FREQ) / (CLOCK_FREQ + br);
*/
mpeg_parse->next_scr = scr + (bss * CLOCK_FREQ) / br;
} else {
/* we are interpolating the scr here */
@ -632,8 +695,8 @@ gst_mpeg_parse_loop (GstElement * element)
}
GST_LOG_OBJECT (mpeg_parse, "size: %" G_GINT64_FORMAT
", total since SCR: %" G_GINT64_FORMAT
", next SCR: %" G_GINT64_FORMAT, size, bss, mpeg_parse->next_scr);
", total since SCR: %" G_GINT64_FORMAT ", br: %" G_GINT64_FORMAT
", next SCR: %" G_GINT64_FORMAT, size, bss, br, mpeg_parse->next_scr);
}
}
}
@ -650,12 +713,81 @@ gst_mpeg_parse_get_src_formats (GstPad * pad)
return formats;
}
/*
* Return the bitrate to the nearest byte/sec
*/
static gboolean
gst_mpeg_parse_get_rate (GstMPEGParse * mpeg_parse, gint64 * rate)
{
GstFormat time_format = GST_FORMAT_TIME;
GstFormat bytes_format = GST_FORMAT_BYTES;
gint64 total_time = 0;
gint64 total_bytes = 0;
/* If upstream knows the total time and the total bytes,
* use those to compute an average byterate
*/
if (gst_pad_query (GST_PAD_PEER (mpeg_parse->sinkpad),
GST_QUERY_TOTAL, &time_format, &total_time)
&&
gst_pad_query (GST_PAD_PEER (mpeg_parse->sinkpad),
GST_QUERY_TOTAL, &bytes_format, &total_bytes)
&& total_time != 0) {
*rate = GST_SECOND * total_bytes / total_time;
return TRUE;
}
if ((mpeg_parse->first_scr != MP_INVALID_SCR) &&
(mpeg_parse->last_scr != MP_INVALID_SCR) &&
(mpeg_parse->last_scr_pos - mpeg_parse->first_scr_pos > MP_MIN_VALID_BSS)
&& (mpeg_parse->last_scr != mpeg_parse->first_scr)) {
*rate =
GST_SECOND * (mpeg_parse->last_scr_pos -
mpeg_parse->first_scr_pos) / MPEGTIME_TO_GSTTIME (mpeg_parse->last_scr -
mpeg_parse->first_scr);
if (*rate != 0) {
/*
* check if we need to update scr_rate
*/
if ((mpeg_parse->scr_rate == 0) ||
(((double) (ABS (mpeg_parse->scr_rate -
*rate)) / mpeg_parse->scr_rate)
>= MP_SCR_RATE_HYST)) {
mpeg_parse->scr_rate = *rate;
return TRUE;
}
}
if (mpeg_parse->scr_rate != 0) {
*rate = mpeg_parse->scr_rate;
return TRUE;
}
}
if (mpeg_parse->avg_bitrate_time != 0 && mpeg_parse->avg_bitrate_bytes != 0) {
*rate =
GST_SECOND * mpeg_parse->avg_bitrate_bytes /
mpeg_parse->avg_bitrate_time;
if (*rate != 0) {
return TRUE;
}
}
if (mpeg_parse->mux_rate != 0) {
*rate = mpeg_parse->mux_rate;
return TRUE;
}
return FALSE;
}
gboolean
gst_mpeg_parse_convert_src (GstPad * pad, GstFormat src_format,
gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
{
gboolean res = TRUE;
GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad));
gint64 rate;
switch (src_format) {
case GST_FORMAT_BYTES:
@ -663,10 +795,11 @@ gst_mpeg_parse_convert_src (GstPad * pad, GstFormat src_format,
case GST_FORMAT_DEFAULT:
*dest_format = GST_FORMAT_TIME;
case GST_FORMAT_TIME:
if (mpeg_parse->mux_rate == 0)
if (!gst_mpeg_parse_get_rate (mpeg_parse, &rate))
res = FALSE;
else
*dest_value = src_value * GST_SECOND / (mpeg_parse->mux_rate * 50);
else {
*dest_value = GST_SECOND * src_value / rate;
}
break;
default:
res = FALSE;
@ -677,7 +810,11 @@ gst_mpeg_parse_convert_src (GstPad * pad, GstFormat src_format,
case GST_FORMAT_DEFAULT:
*dest_format = GST_FORMAT_BYTES;
case GST_FORMAT_BYTES:
*dest_value = mpeg_parse->mux_rate * 50 * src_value / GST_SECOND;
if (!gst_mpeg_parse_get_rate (mpeg_parse, &rate))
res = FALSE;
else {
*dest_value = src_value * rate / GST_SECOND;
}
break;
default:
res = FALSE;
@ -687,6 +824,7 @@ gst_mpeg_parse_convert_src (GstPad * pad, GstFormat src_format,
res = FALSE;
break;
}
return res;
}
@ -708,8 +846,8 @@ gst_mpeg_parse_handle_src_query (GstPad * pad, GstQueryType type,
{
gboolean res = TRUE;
GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad));
GstFormat src_format;
gint64 src_value;
GstFormat src_format = GST_FORMAT_UNDEFINED;
gint64 src_value = 0;
switch (type) {
case GST_QUERY_TOTAL:
@ -718,6 +856,18 @@ gst_mpeg_parse_handle_src_query (GstPad * pad, GstQueryType type,
case GST_FORMAT_DEFAULT:
*format = GST_FORMAT_TIME;
/* fallthrough */
case GST_FORMAT_TIME:
/*
* Try asking upstream if it knows the time - a DVD might know
*/
src_format = GST_FORMAT_TIME;
if (gst_pad_query (GST_PAD_PEER (mpeg_parse->sinkpad),
GST_QUERY_TOTAL, &src_format, &src_value)) {
res = TRUE;
break;
}
/* Otherwise fallthrough */
default:
src_format = GST_FORMAT_BYTES;
if (!gst_pad_query (GST_PAD_PEER (mpeg_parse->sinkpad),
@ -736,7 +886,14 @@ gst_mpeg_parse_handle_src_query (GstPad * pad, GstQueryType type,
/* fallthrough */
default:
src_format = GST_FORMAT_TIME;
src_value = MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr);
if ((mpeg_parse->current_scr == MP_INVALID_SCR) ||
(mpeg_parse->first_scr == MP_INVALID_SCR))
res = FALSE;
else {
gint64 cur =
(gint64) (mpeg_parse->current_scr) - mpeg_parse->first_scr;
src_value = MPEGTIME_TO_GSTTIME (MAX (0, cur));
}
break;
}
break;
@ -838,13 +995,16 @@ gst_mpeg_parse_handle_src_event (GstPad * pad, GstEvent * event)
if (!res)
break;
GST_DEBUG ("sending seek to %" G_GINT64_FORMAT, desired_offset);
GST_DEBUG ("sending seek to %" G_GINT64_FORMAT " expected SCR: %"
G_GUINT64_FORMAT " (%" G_GUINT64_FORMAT ")", desired_offset,
expected_scr, MPEGTIME_TO_GSTTIME (expected_scr));
if (gst_bytestream_seek (mpeg_parse->packetize->bs, desired_offset,
GST_SEEK_METHOD_SET)) {
mpeg_parse->discont_pending = TRUE;
mpeg_parse->scr_pending = TRUE;
mpeg_parse->next_scr = expected_scr;
mpeg_parse->current_scr = -1;
mpeg_parse->current_scr = MP_INVALID_SCR;
mpeg_parse->adjust = 0;
res = TRUE;
}
@ -870,15 +1030,7 @@ gst_mpeg_parse_change_state (GstElement * element)
GST_MPEG_PACKETIZE_SYSTEM);
}
/* initialize parser state */
mpeg_parse->current_scr = 0;
mpeg_parse->bytes_since_scr = 0;
mpeg_parse->adjust = 0;
mpeg_parse->next_scr = 0;
/* zero counters (should be done at RUNNING?) */
mpeg_parse->mux_rate = 0;
mpeg_parse->discont_pending = FALSE;
mpeg_parse->scr_pending = FALSE;
gst_mpeg_parse_reset (mpeg_parse);
break;
case GST_STATE_PAUSED_TO_READY:
if (mpeg_parse->packetize) {

View file

@ -25,10 +25,7 @@
#include <gst/bytestream/bytestream.h>
#include "gstmpegpacketize.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
#define GST_TYPE_MPEG_PARSE \
(gst_mpeg_parse_get_type())
@ -49,80 +46,93 @@ extern "C" {
#define MPEGTIME_TO_GSTTIME(time) (((time) * (GST_MSECOND/10)) / CLOCK_BASE)
#define GSTTIME_TO_MPEGTIME(time) (((time) * CLOCK_BASE) / (GST_MSECOND/10))
typedef struct _GstMPEGParse GstMPEGParse;
typedef struct _GstMPEGParseClass GstMPEGParseClass;
typedef struct _GstMPEGParse GstMPEGParse;
typedef struct _GstMPEGParseClass GstMPEGParseClass;
struct _GstMPEGParse {
GstElement element;
struct _GstMPEGParse
{
GstElement element;
GstPad *sinkpad, *srcpad;
GstPad *sinkpad, *srcpad;
GstMPEGPacketize *packetize;
GstMPEGPacketize *packetize;
/* pack header values */
guint32 mux_rate;
guint64 current_scr; /* Current SCR from the stream. */
guint64 next_scr; /* Expected next SCR. */
guint64 bytes_since_scr;
/*
* Keep track of total rate using SCR
* and use hysteresis.
*/
guint64 first_scr; /* Earliest SCR value for reference */
guint64 first_scr_pos; /* Byte position of reference SCR */
guint64 last_scr; /* Latest SCR value for reference */
guint64 last_scr_pos; /* Byte position of reference SCR */
guint64 scr_rate; /* Remember the last rate for hysteresis */
gboolean do_adjust; /* If false, send discont events on SCR
* jumps
*/
gboolean use_adjust; /* Collect SCR jumps into 'adjust' in
* order to adjust timestamps to smooth
* discontinuities. */
gint64 adjust; /* Current timestamp adjust value. */
/*
* Compute a rolling average for SCR interpolation (for MPEG1)
*/
guint64 avg_bitrate_time; /* Time total for local average bitrate */
guint64 avg_bitrate_bytes; /* bytes total for local average bitrate */
gboolean discont_pending;
gboolean scr_pending;
gint max_discont;
/* pack header values */
guint32 mux_rate; /* mux rate in bytes/sec derived from Pack
* header */
guint64 current_scr; /* Current SCR from the stream. */
guint64 next_scr; /* Expected next SCR. */
guint64 bytes_since_scr; /* Bytes since current_scr */
GstClock *clock;
gboolean sync;
GstClockID id;
gboolean do_adjust; /* If false, send discont events on SCR
* jumps
*/
gboolean use_adjust; /* Collect SCR jumps into 'adjust' in
* order to adjust timestamps to smooth
* discontinuities. */
gint64 adjust; /* Current timestamp adjust value. */
GstIndex *index;
gint index_id;
};
gboolean discont_pending;
gboolean scr_pending;
gint max_discont;
struct _GstMPEGParseClass {
GstElementClass parent_class;
GstClock *clock;
gboolean sync;
GstClockID id;
/* process packet types */
gboolean (*parse_packhead) (GstMPEGParse *parse, GstBuffer *buffer);
gboolean (*parse_syshead) (GstMPEGParse *parse, GstBuffer *buffer);
gboolean (*parse_packet) (GstMPEGParse *parse, GstBuffer *buffer);
gboolean (*parse_pes) (GstMPEGParse *parse, GstBuffer *buffer);
GstIndex *index;
gint index_id;
};
/* process events */
void (*handle_discont) (GstMPEGParse *parse, GstEvent *event);
struct _GstMPEGParseClass
{
GstElementClass parent_class;
/* optional method to send out the data */
void (*send_data) (GstMPEGParse *parse, GstData *data, GstClockTime time);
void (*send_discont) (GstMPEGParse *parse, GstClockTime time);
};
/* process packet types */
gboolean (*parse_packhead) (GstMPEGParse * parse, GstBuffer * buffer);
gboolean (*parse_syshead) (GstMPEGParse * parse, GstBuffer * buffer);
gboolean (*parse_packet) (GstMPEGParse * parse, GstBuffer * buffer);
gboolean (*parse_pes) (GstMPEGParse * parse, GstBuffer * buffer);
GType gst_mpeg_parse_get_type(void);
/* process events */
void (*handle_discont) (GstMPEGParse * parse, GstEvent * event);
gboolean gst_mpeg_parse_plugin_init (GstPlugin *plugin);
/* optional method to send out the data */
void (*send_data) (GstMPEGParse * parse, GstData * data, GstClockTime time);
void (*send_discont) (GstMPEGParse * parse, GstClockTime time);
};
const GstFormat*
gst_mpeg_parse_get_src_formats (GstPad *pad);
gboolean gst_mpeg_parse_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value);
const GstEventMask*
gst_mpeg_parse_get_src_event_masks (GstPad *pad);
gboolean gst_mpeg_parse_handle_src_event (GstPad *pad, GstEvent *event);
GType gst_mpeg_parse_get_type (void);
const GstQueryType*
gst_mpeg_parse_get_src_query_types (GstPad *pad);
gboolean gst_mpeg_parse_handle_src_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value);
gboolean gst_mpeg_parse_plugin_init (GstPlugin * plugin);
#ifdef __cplusplus
}
#endif /* __cplusplus */
const GstFormat *gst_mpeg_parse_get_src_formats (GstPad * pad);
gboolean gst_mpeg_parse_convert_src (GstPad * pad, GstFormat src_format,
gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
const GstEventMask *gst_mpeg_parse_get_src_event_masks (GstPad * pad);
gboolean gst_mpeg_parse_handle_src_event (GstPad * pad, GstEvent * event);
#endif /* __MPEG_PARSE_H__ */
const GstQueryType *gst_mpeg_parse_get_src_query_types (GstPad * pad);
gboolean gst_mpeg_parse_handle_src_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value);
G_END_DECLS
#endif /* __MPEG_PARSE_H__ */

View file

@ -26,11 +26,7 @@
#include <gst/bytestream/bytestream.h>
#include "gstmpegpacketize.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
#define GST_TYPE_RFC2250_ENC \
(gst_rfc2250_enc_get_type())
@ -79,10 +75,6 @@ GType gst_rfc2250_enc_get_type(void);
gboolean gst_rfc2250_enc_plugin_init (GstPlugin *plugin);
#ifdef __cplusplus
}
#endif /* __cplusplus */
G_END_DECLS
#endif /* __RFC2250_ENC_H__ */