gst/qtdemux/qtdemux.*: Bitch. Also known as seeking, querying & co.

Original commit message from CVS:
* gst/qtdemux/qtdemux.c: (gst_qtdemux_init),
(gst_qtdemux_handle_src_query), (gst_qtdemux_handle_src_event),
(gst_qtdemux_handle_sink_event), (gst_qtdemux_change_state),
(gst_qtdemux_loop_header), (qtdemux_dump_mvhd),
(qtdemux_parse_trak):
* gst/qtdemux/qtdemux.h:
Bitch. Also known as seeking, querying & co.
* sys/oss/gstosssink.c: (gst_osssink_init), (gst_osssink_chain),
(gst_osssink_change_state):
* sys/oss/gstosssink.h:
Resyncing is for weenies, this hack is no longer needed and was
broken anyway (since it - unintendedly - always leaves resync to
TRUE).
This commit is contained in:
Ronald S. Bultje 2004-06-05 18:50:48 +00:00
parent d30bd01770
commit 45b9c25415
5 changed files with 114 additions and 49 deletions

View file

@ -1,3 +1,19 @@
2004-06-04 Ronald Bultje <rbultje@ronald.bitfreak.net>
* gst/qtdemux/qtdemux.c: (gst_qtdemux_init),
(gst_qtdemux_handle_src_query), (gst_qtdemux_handle_src_event),
(gst_qtdemux_handle_sink_event), (gst_qtdemux_change_state),
(gst_qtdemux_loop_header), (qtdemux_dump_mvhd),
(qtdemux_parse_trak):
* gst/qtdemux/qtdemux.h:
Bitch. Also known as seeking, querying & co.
* sys/oss/gstosssink.c: (gst_osssink_init), (gst_osssink_chain),
(gst_osssink_change_state):
* sys/oss/gstosssink.h:
Resyncing is for weenies, this hack is no longer needed and was
broken anyway (since it - unintendedly - always leaves resync to
TRUE).
2004-06-05 Andrew Turner <zxombie@hotpop.com>
* gst/tcp/gsttcp.c: portability (Solaris 10/FreeBSD)

View file

@ -231,6 +231,10 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
gst_element_set_loop_function (GST_ELEMENT (qtdemux),
gst_qtdemux_loop_header);
gst_element_add_pad (GST_ELEMENT (qtdemux), qtdemux->sinkpad);
qtdemux->last_ts = GST_CLOCK_TIME_NONE;
qtdemux->need_discont = FALSE;
qtdemux->need_flush = FALSE;
}
static const GstFormat *
@ -332,7 +336,8 @@ static gboolean
gst_qtdemux_handle_src_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value)
{
gboolean res = TRUE;
gboolean res = FALSE;
GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad));
//QtDemuxStream *stream = gst_pad_get_element_private(pad);
@ -340,7 +345,11 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstQueryType type,
case GST_QUERY_TOTAL:
switch (*format) {
case GST_FORMAT_TIME:
*value = 0; /* FIXME */
if (qtdemux->duration != 0 && qtdemux->timescale != 0) {
*value =
(guint64) qtdemux->duration * GST_SECOND / qtdemux->timescale;
res = TRUE;
}
break;
case GST_FORMAT_BYTES:
*value = 0; /* FIXME */
@ -356,7 +365,10 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstQueryType type,
case GST_QUERY_POSITION:
switch (*format) {
case GST_FORMAT_TIME:
*value = 0; /* FIXME */
if (GST_CLOCK_TIME_IS_VALID (qtdemux->last_ts)) {
*value = qtdemux->last_ts;
res = TRUE;
}
break;
case GST_FORMAT_BYTES:
*value = 0; /* FIXME */
@ -381,8 +393,7 @@ static gboolean
gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event)
{
gboolean res = TRUE;
//QtDemuxStream *stream = gst_pad_get_element_private(pad);
GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
@ -391,13 +402,35 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_SEEK_FORMAT (event)) {
case GST_FORMAT_BYTES:
case GST_FORMAT_DEFAULT:
res = FALSE;
break;
case GST_FORMAT_TIME:
{
gint64 desired_offset = GST_EVENT_SEEK_OFFSET (event);
gint i = 0, n;
QtDemuxStream *stream = gst_pad_get_element_private (pad);
GST_DEBUG ("seeking to %" G_GINT64_FORMAT, desired_offset);
res = FALSE;
if (!stream->n_samples) {
res = FALSE;
break;
}
/* resync to new time */
for (n = 0; n < qtdemux->n_streams; n++) {
QtDemuxStream *str = qtdemux->streams[n];
for (i = 0; i < str->n_samples; i++) {
if (str->samples[i].timestamp > desired_offset)
break;
}
str->sample_index = i;
}
qtdemux->need_discont = TRUE;
if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH)
qtdemux->need_flush = TRUE;
break;
}
default:
res = FALSE;
@ -456,7 +489,6 @@ gst_qtdemux_handle_sink_event (GstQTDemux * qtdemux)
gst_pad_event_default (qtdemux->sinkpad, event);
return FALSE;
case GST_EVENT_FLUSH:
//g_warning("flush event");
break;
case GST_EVENT_DISCONTINUOUS:
GST_DEBUG ("discontinuous event");
@ -490,6 +522,9 @@ gst_qtdemux_change_state (GstElement * element)
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
qtdemux->last_ts = GST_CLOCK_TIME_NONE;
qtdemux->need_discont = FALSE;
qtdemux->need_flush = FALSE;
break;
case GST_STATE_READY_TO_NULL:
gst_bytestream_destroy (qtdemux->bs);
@ -727,8 +762,29 @@ gst_qtdemux_loop_header (GstElement * element)
GST_BUFFER_TIMESTAMP (buf) =
stream->samples[stream->sample_index].timestamp;
qtdemux->last_ts = GST_BUFFER_TIMESTAMP (buf);
GST_BUFFER_DURATION (buf) =
stream->samples[stream->sample_index].duration;
if (qtdemux->need_flush) {
gst_pad_event_default (qtdemux->sinkpad,
gst_event_new (GST_EVENT_FLUSH));
qtdemux->need_flush = FALSE;
}
if (qtdemux->need_discont) {
GstEvent *event = gst_event_new_discontinuous (FALSE,
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf),
GST_FORMAT_UNDEFINED);
gint n;
qtdemux->need_discont = FALSE;
for (n = 0; n < qtdemux->n_streams; n++) {
gst_event_ref (event);
gst_pad_push (qtdemux->streams[n]->pad, GST_DATA (event));
}
gst_event_unref (event);
}
g_print ("Pushing buf with time=%" GST_TIME_FORMAT "\n",
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
gst_pad_push (stream->pad, GST_DATA (buf));
GST_INFO ("pushing buffer on %" GST_PTR_FORMAT, stream->pad);
@ -1307,6 +1363,8 @@ qtdemux_dump_mvhd (GstQTDemux * qtdemux, void *buffer, int depth)
QTDEMUX_GUINT32_GET (buffer + 20));
GST_LOG ("%*s duration: %u", depth, "",
QTDEMUX_GUINT32_GET (buffer + 24));
qtdemux->duration = QTDEMUX_GUINT32_GET (buffer + 24);
qtdemux->timescale = QTDEMUX_GUINT32_GET (buffer + 20);
GST_LOG ("%*s pref. rate: %g", depth, "", QTDEMUX_FP32_GET (buffer + 28));
GST_LOG ("%*s pref. volume: %g", depth, "", QTDEMUX_FP16_GET (buffer + 32));
GST_LOG ("%*s preview time: %u", depth, "",
@ -2077,30 +2135,31 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
sample_index += samples_per_chunk;
}
}
/*
done2:
n_sample_times = QTDEMUX_GUINT32_GET(stts->data + 12);
GST_LOG("n_sample_times = %d",n_sample_times);
#if 0
done2:
n_sample_times = QTDEMUX_GUINT32_GET (stts->data + 12);
GST_LOG ("n_sample_times = %d", n_sample_times);
timestamp = 0;
index = 0;
sample_index = 0;
for(i=0;i<n_sample_times;i++){
for (i = 0; i < n_sample_times; i++) {
int duration;
guint64 time;
sample_index += QTDEMUX_GUINT32_GET(stts->data + 16 + 8*i);
duration = QTDEMUX_GUINT32_GET(stts->data + 16 + 8*i + 4);
for(;index < n_samples && samples[index].sample_index < sample_index;index++){
int size;
sample_index += QTDEMUX_GUINT32_GET (stts->data + 16 + 8 * i);
duration = QTDEMUX_GUINT32_GET (stts->data + 16 + 8 * i + 4);
for (; index < n_samples && samples[index].sample_index < sample_index;
index++) {
int size;
samples[index].timestamp = timestamp;
size = samples[index+1].sample_index - samples[index].sample_index;
time = GST_SECOND / stream->rate; //(GST_SECOND * duration * samples[index].size)/stream->timescale ;
size = samples[index + 1].sample_index - samples[index].sample_index;
time = GST_SECOND / stream->rate; //(GST_SECOND * duration * samples[index].size)/stream->timescale ;
timestamp += time;
samples[index].duration = time;
}
}
*/
#endif
}
done2:
#if 0

View file

@ -74,6 +74,9 @@ struct _GstQTDemux {
/* track stuff */
guint64 last_ts;
gboolean need_discont;
gboolean need_flush;
};
struct _GstQTDemuxClass {

View file

@ -218,7 +218,6 @@ gst_osssink_init (GstOssSink * osssink)
osssink->chunk_size = 4096;
osssink->mute = FALSE;
osssink->sync = TRUE;
osssink->resync = TRUE;
osssink->provided_clock =
gst_audio_clock_new ("ossclock", gst_osssink_get_time, osssink);
gst_object_set_parent (GST_OBJECT (osssink->provided_clock),
@ -392,9 +391,6 @@ gst_osssink_chain (GstPad * pad, GstData * _data)
FALSE);
gst_pad_event_default (pad, event);
return;
case GST_EVENT_DISCONTINUOUS:
osssink->resync = TRUE;
/* pass-through */
default:
gst_pad_event_default (pad, event);
return;
@ -424,13 +420,13 @@ gst_osssink_chain (GstPad * pad, GstData * _data)
buftime = soundtime;
}
GST_LOG_OBJECT (osssink,
"time: real %" G_GUINT64_FORMAT ", buffer: %" G_GUINT64_FORMAT, soundtime,
buftime);
"time: real %" GST_TIME_FORMAT ", buffer: %" GST_TIME_FORMAT,
GST_TIME_ARGS (soundtime), GST_TIME_ARGS (buftime));
if (MAX (buftime, soundtime) - MIN (buftime, soundtime) > (GST_SECOND / 10)) {
/* we need to adjust to the buffers here */
GST_INFO_OBJECT (osssink,
"need sync: real %" G_GUINT64_FORMAT ", buffer: %" G_GUINT64_FORMAT,
soundtime, buftime);
"need sync: real %" GST_TIME_FORMAT ", buffer: %" GST_TIME_FORMAT,
GST_TIME_ARGS (soundtime), GST_TIME_ARGS (buftime));
if (soundtime > buftime) {
/* do *not* throw frames out. It's useless. The next frame will come in
* too late. And the next one. And so on. We don't want to lose sound.
@ -444,29 +440,22 @@ gst_osssink_chain (GstPad * pad, GstData * _data)
GST_OSSELEMENT (osssink)->channels)) *
(GST_OSSELEMENT (osssink)->width / 8) *
GST_OSSELEMENT (osssink)->channels;
guint8 *sbuf = g_new (guint8, to_handle);
if (!osssink->resync) {
guint8 *buf = g_new (guint8, to_handle);
memset (sbuf, (GST_OSSELEMENT (osssink)->width == 8) ? 0 : 128,
to_handle);
while (to_handle > 0) {
gint done = write (GST_OSSELEMENT (osssink)->fd, sbuf,
MIN (to_handle, osssink->chunk_size));
memset (buf, (GST_OSSELEMENT (osssink)->width == 8) ? 0 : 128,
to_handle);
while (to_handle > 0) {
gint done = write (GST_OSSELEMENT (osssink)->fd, buf,
MIN (to_handle, osssink->chunk_size));
if (done == -1 && errno != EINTR) {
break;
} else {
to_handle -= done;
osssink->handled += done;
}
if (done == -1 && errno != EINTR) {
break;
} else {
to_handle -= done;
osssink->handled += done;
}
g_free (buf);
} else {
/* Timestamps at start-of-stream (MPEG) or after seek (hey,
* again MPEG!) can be borken, therefore this hacklet. */
osssink->handled += to_handle;
}
g_free (sbuf);
}
}
@ -666,7 +655,6 @@ gst_osssink_change_state (GstElement * element)
ioctl (GST_OSSELEMENT (osssink)->fd, SNDCTL_DSP_RESET, 0);
gst_osselement_reset (GST_OSSELEMENT (osssink));
osssink->handled = 0;
osssink->resync = TRUE;
break;
default:
break;

View file

@ -59,7 +59,6 @@ struct _GstOssSink {
GstClock *provided_clock;
GstClock *clock;
gboolean resync;
gboolean sync;
guint64 handled;