mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
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:
parent
501290be01
commit
3ef22c4774
10 changed files with 322 additions and 167 deletions
29
ChangeLog
29
ChangeLog
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue