mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
Implement seeking/query/convert on dvdec
Original commit message from CVS: Implement seeking/query/convert on dvdec
This commit is contained in:
parent
9101d97ff2
commit
db81699feb
2 changed files with 229 additions and 50 deletions
|
@ -151,21 +151,27 @@ static GstTypeDefinition dv_definition = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A number of functon prototypes are given so we can refer to them later. */
|
/* A number of functon prototypes are given so we can refer to them later. */
|
||||||
static void gst_dvdec_class_init (GstDVDecClass *klass);
|
static void gst_dvdec_class_init (GstDVDecClass *klass);
|
||||||
static void gst_dvdec_init (GstDVDec *dvdec);
|
static void gst_dvdec_init (GstDVDec *dvdec);
|
||||||
|
|
||||||
static gboolean gst_dvdec_src_query (GstPad *pad, GstPadQueryType type,
|
static gboolean gst_dvdec_src_query (GstPad *pad, GstPadQueryType type,
|
||||||
GstFormat *format, gint64 *value);
|
GstFormat *format, gint64 *value);
|
||||||
|
static gboolean gst_dvdec_sink_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
|
||||||
|
GstFormat *dest_format, gint64 *dest_value);
|
||||||
|
static gboolean gst_dvdec_src_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
|
||||||
|
GstFormat *dest_format, gint64 *dest_value);
|
||||||
|
|
||||||
static void gst_dvdec_loop (GstElement *element);
|
static gboolean gst_dvdec_handle_src_event (GstPad *pad, GstEvent *event);
|
||||||
|
|
||||||
|
static void gst_dvdec_loop (GstElement *element);
|
||||||
|
|
||||||
static GstElementStateReturn
|
static GstElementStateReturn
|
||||||
gst_dvdec_change_state (GstElement *element);
|
gst_dvdec_change_state (GstElement *element);
|
||||||
|
|
||||||
static void gst_dvdec_set_property (GObject *object, guint prop_id,
|
static void gst_dvdec_set_property (GObject *object, guint prop_id,
|
||||||
const GValue *value, GParamSpec *pspec);
|
const GValue *value, GParamSpec *pspec);
|
||||||
static void gst_dvdec_get_property (GObject *object, guint prop_id,
|
static void gst_dvdec_get_property (GObject *object, guint prop_id,
|
||||||
GValue *value, GParamSpec *pspec);
|
GValue *value, GParamSpec *pspec);
|
||||||
|
|
||||||
/* The parent class pointer needs to be kept around for some object
|
/* The parent class pointer needs to be kept around for some object
|
||||||
* operations.
|
* operations.
|
||||||
|
@ -246,14 +252,19 @@ gst_dvdec_init(GstDVDec *dvdec)
|
||||||
dvdec->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (sink_temp), "sink");
|
dvdec->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (sink_temp), "sink");
|
||||||
gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->sinkpad);
|
||||||
gst_pad_set_query_function (dvdec->sinkpad, NULL);
|
gst_pad_set_query_function (dvdec->sinkpad, NULL);
|
||||||
|
gst_pad_set_convert_function (dvdec->sinkpad, gst_dvdec_sink_convert);
|
||||||
|
|
||||||
dvdec->videosrcpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (video_src_temp), "video");
|
dvdec->videosrcpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (video_src_temp), "video");
|
||||||
gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->videosrcpad);
|
gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->videosrcpad);
|
||||||
gst_pad_set_query_function (dvdec->videosrcpad, gst_dvdec_src_query);
|
gst_pad_set_query_function (dvdec->videosrcpad, gst_dvdec_src_query);
|
||||||
|
gst_pad_set_event_function (dvdec->videosrcpad, gst_dvdec_handle_src_event);
|
||||||
|
gst_pad_set_convert_function (dvdec->videosrcpad, gst_dvdec_src_convert);
|
||||||
|
|
||||||
dvdec->audiosrcpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET(audio_src_temp), "audio");
|
dvdec->audiosrcpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET(audio_src_temp), "audio");
|
||||||
gst_element_add_pad(GST_ELEMENT(dvdec),dvdec->audiosrcpad);
|
gst_element_add_pad(GST_ELEMENT(dvdec),dvdec->audiosrcpad);
|
||||||
gst_pad_set_query_function (dvdec->audiosrcpad, gst_dvdec_src_query);
|
gst_pad_set_query_function (dvdec->audiosrcpad, gst_dvdec_src_query);
|
||||||
|
gst_pad_set_event_function (dvdec->audiosrcpad, gst_dvdec_handle_src_event);
|
||||||
|
gst_pad_set_convert_function (dvdec->audiosrcpad, gst_dvdec_src_convert);
|
||||||
|
|
||||||
gst_element_set_loop_function (GST_ELEMENT (dvdec), gst_dvdec_loop);
|
gst_element_set_loop_function (GST_ELEMENT (dvdec), gst_dvdec_loop);
|
||||||
|
|
||||||
|
@ -262,12 +273,111 @@ gst_dvdec_init(GstDVDec *dvdec)
|
||||||
dvdec->pool = NULL;
|
dvdec->pool = NULL;
|
||||||
dvdec->length = 0;
|
dvdec->length = 0;
|
||||||
dvdec->next_ts = 0LL;
|
dvdec->next_ts = 0LL;
|
||||||
|
dvdec->need_discont = FALSE;
|
||||||
|
dvdec->framerate = 0;
|
||||||
|
dvdec->height = 0;
|
||||||
|
|
||||||
for (i = 0; i <4; i++) {
|
for (i = 0; i <4; i++) {
|
||||||
dvdec->audio_buffers[i] = (gint16 *)g_malloc (DV_AUDIO_MAX_SAMPLES * sizeof (gint16));
|
dvdec->audio_buffers[i] = (gint16 *)g_malloc (DV_AUDIO_MAX_SAMPLES * sizeof (gint16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_dvdec_src_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
|
||||||
|
GstFormat *dest_format, gint64 *dest_value)
|
||||||
|
{
|
||||||
|
gboolean res = TRUE;
|
||||||
|
GstDVDec *dvdec;
|
||||||
|
gint scale = 1;
|
||||||
|
|
||||||
|
dvdec = GST_DVDEC (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
if (dvdec->length == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (src_format) {
|
||||||
|
case GST_FORMAT_BYTES:
|
||||||
|
switch (*dest_format) {
|
||||||
|
case GST_FORMAT_DEFAULT:
|
||||||
|
*dest_format = GST_FORMAT_TIME;
|
||||||
|
case GST_FORMAT_TIME:
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_FORMAT_TIME:
|
||||||
|
switch (*dest_format) {
|
||||||
|
case GST_FORMAT_DEFAULT:
|
||||||
|
*dest_format = GST_FORMAT_BYTES;
|
||||||
|
case GST_FORMAT_BYTES:
|
||||||
|
if (pad == dvdec->videosrcpad)
|
||||||
|
scale = 720 * dvdec->height * dvdec->bpp;
|
||||||
|
else if (pad == dvdec->audiosrcpad)
|
||||||
|
scale = dvdec->decoder->audio->num_channels * 2;
|
||||||
|
/* fallthrough */
|
||||||
|
case GST_FORMAT_UNITS:
|
||||||
|
if (pad == dvdec->videosrcpad)
|
||||||
|
*dest_value = src_value * dvdec->framerate * scale / GST_SECOND;
|
||||||
|
else if (pad == dvdec->audiosrcpad)
|
||||||
|
*dest_value = src_value * dvdec->decoder->audio->frequency * scale / GST_SECOND;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_dvdec_sink_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
|
||||||
|
GstFormat *dest_format, gint64 *dest_value)
|
||||||
|
{
|
||||||
|
gboolean res = TRUE;
|
||||||
|
GstDVDec *dvdec;
|
||||||
|
|
||||||
|
dvdec = GST_DVDEC (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
if (dvdec->length == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (src_format) {
|
||||||
|
case GST_FORMAT_BYTES:
|
||||||
|
switch (*dest_format) {
|
||||||
|
case GST_FORMAT_DEFAULT:
|
||||||
|
*dest_format = GST_FORMAT_TIME;
|
||||||
|
case GST_FORMAT_TIME:
|
||||||
|
*dest_value = src_value * GST_SECOND / (dvdec->length * dvdec->framerate);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_FORMAT_TIME:
|
||||||
|
switch (*dest_format) {
|
||||||
|
case GST_FORMAT_DEFAULT:
|
||||||
|
*dest_format = GST_FORMAT_BYTES;
|
||||||
|
case GST_FORMAT_BYTES:
|
||||||
|
{
|
||||||
|
guint64 frame;
|
||||||
|
/* calculate the frame */
|
||||||
|
frame = src_value * dvdec->framerate / GST_SECOND;
|
||||||
|
/* calculate the offset */
|
||||||
|
*dest_value = frame * dvdec->length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_dvdec_src_query (GstPad *pad, GstPadQueryType type,
|
gst_dvdec_src_query (GstPad *pad, GstPadQueryType type,
|
||||||
GstFormat *format, gint64 *value)
|
GstFormat *format, gint64 *value)
|
||||||
|
@ -282,21 +392,21 @@ gst_dvdec_src_query (GstPad *pad, GstPadQueryType type,
|
||||||
switch (*format) {
|
switch (*format) {
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
*format = GST_FORMAT_TIME;
|
*format = GST_FORMAT_TIME;
|
||||||
case GST_FORMAT_TIME:
|
default:
|
||||||
{
|
{
|
||||||
guint64 len;
|
guint64 len;
|
||||||
|
GstFormat tmp_format;
|
||||||
|
|
||||||
len = gst_bytestream_length (dvdec->bs);
|
len = gst_bytestream_length (dvdec->bs);
|
||||||
if (len != -1 && dvdec->length) {
|
tmp_format = GST_FORMAT_TIME;
|
||||||
*value = (len * GST_SECOND) / (dvdec->length * 25);
|
if (len == -1 || !gst_pad_convert (dvdec->sinkpad, GST_FORMAT_BYTES, len, &tmp_format, value)) {
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!gst_pad_convert (pad, GST_FORMAT_TIME, *value, format, value)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
res = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_PAD_QUERY_POSITION:
|
case GST_PAD_QUERY_POSITION:
|
||||||
|
@ -304,7 +414,7 @@ gst_dvdec_src_query (GstPad *pad, GstPadQueryType type,
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
*format = GST_FORMAT_TIME;
|
*format = GST_FORMAT_TIME;
|
||||||
default:
|
default:
|
||||||
*value = dvdec->next_ts;
|
res = gst_pad_convert (pad, GST_FORMAT_TIME, dvdec->next_ts, format, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -316,7 +426,7 @@ gst_dvdec_src_query (GstPad *pad, GstPadQueryType type,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_dvdec_handle_event (GstDVDec *dvdec)
|
gst_dvdec_handle_sink_event (GstDVDec *dvdec)
|
||||||
{
|
{
|
||||||
guint32 remaining;
|
guint32 remaining;
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
@ -330,26 +440,73 @@ gst_dvdec_handle_event (GstDVDec *dvdec)
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
gst_pad_event_default (dvdec->sinkpad, event);
|
gst_pad_event_default (dvdec->sinkpad, event);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_SEEK:
|
|
||||||
g_warning ("seek event\n");
|
|
||||||
gst_event_free (event);
|
|
||||||
break;
|
|
||||||
case GST_EVENT_FLUSH:
|
case GST_EVENT_FLUSH:
|
||||||
g_warning ("flush event\n");
|
|
||||||
gst_event_free (event);
|
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_DISCONTINUOUS:
|
case GST_EVENT_DISCONTINUOUS:
|
||||||
g_warning ("discont event\n");
|
{
|
||||||
gst_event_free (event);
|
gint i;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
GstFormat format;
|
||||||
|
|
||||||
|
format = GST_FORMAT_TIME;
|
||||||
|
/* try to get a timestamp from the discont formats */
|
||||||
|
for (i = 0; i < GST_EVENT_DISCONT_OFFSET_LEN(event); i++) {
|
||||||
|
if (gst_pad_convert (dvdec->sinkpad, GST_EVENT_DISCONT_OFFSET(event,i).format, GST_EVENT_DISCONT_OFFSET(event,i).value,
|
||||||
|
&format, &dvdec->next_ts))
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* assume 0 then */
|
||||||
|
if (!found) {
|
||||||
|
dvdec->next_ts = 0LL;
|
||||||
|
}
|
||||||
|
dvdec->need_discont = TRUE;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
g_warning ("unhandled event %d\n", type);
|
g_warning ("unhandled event %d\n", type);
|
||||||
gst_event_free (event);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
gst_event_free (event);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_dvdec_handle_src_event (GstPad *pad, GstEvent *event)
|
||||||
|
{
|
||||||
|
gboolean res = TRUE;
|
||||||
|
GstDVDec *dvdec;
|
||||||
|
|
||||||
|
dvdec = GST_DVDEC (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_SEEK:
|
||||||
|
{
|
||||||
|
gint64 position;
|
||||||
|
GstFormat format;
|
||||||
|
|
||||||
|
/* first try to figure out the byteoffset of this seek event */
|
||||||
|
format = GST_FORMAT_BYTES;
|
||||||
|
if (!gst_pad_convert (dvdec->sinkpad, GST_EVENT_SEEK_FORMAT (event), GST_EVENT_SEEK_OFFSET (event),
|
||||||
|
&format, &position)) {
|
||||||
|
/* could not convert seek format to byte offset */
|
||||||
|
res = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* seek to offset */
|
||||||
|
if (!gst_bytestream_seek (dvdec->bs, position, GST_SEEK_METHOD_SET)) {
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_dvdec_loop (GstElement *element)
|
gst_dvdec_loop (GstElement *element)
|
||||||
|
@ -357,7 +514,6 @@ gst_dvdec_loop (GstElement *element)
|
||||||
GstDVDec *dvdec;
|
GstDVDec *dvdec;
|
||||||
GstBuffer *buf, *outbuf;
|
GstBuffer *buf, *outbuf;
|
||||||
guint8 *inframe;
|
guint8 *inframe;
|
||||||
gboolean PAL;
|
|
||||||
gint height;
|
gint height;
|
||||||
guint32 length, got_bytes;
|
guint32 length, got_bytes;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
|
@ -368,15 +524,16 @@ gst_dvdec_loop (GstElement *element)
|
||||||
/* first read enough bytes to parse the header */
|
/* first read enough bytes to parse the header */
|
||||||
got_bytes = gst_bytestream_peek_bytes (dvdec->bs, &inframe, header_size);
|
got_bytes = gst_bytestream_peek_bytes (dvdec->bs, &inframe, header_size);
|
||||||
if (got_bytes < header_size) {
|
if (got_bytes < header_size) {
|
||||||
gst_dvdec_handle_event (dvdec);
|
gst_dvdec_handle_sink_event (dvdec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dv_parse_header (dvdec->decoder, inframe);
|
dv_parse_header (dvdec->decoder, inframe);
|
||||||
/* after parsing the header we know the size of the data */
|
/* after parsing the header we know the size of the data */
|
||||||
PAL = dv_system_50_fields (dvdec->decoder);
|
dvdec->PAL = dv_system_50_fields (dvdec->decoder);
|
||||||
|
|
||||||
height = (PAL ? PAL_HEIGHT : NTSC_HEIGHT);
|
dvdec->framerate = (dvdec->PAL ? 25 : 30);
|
||||||
length = (PAL ? PAL_BUFFER : NTSC_BUFFER);
|
dvdec->height = height = (dvdec->PAL ? PAL_HEIGHT : NTSC_HEIGHT);
|
||||||
|
length = (dvdec->PAL ? PAL_BUFFER : NTSC_BUFFER);
|
||||||
|
|
||||||
if (length != dvdec->length) {
|
if (length != dvdec->length) {
|
||||||
dvdec->length = length;
|
dvdec->length = length;
|
||||||
|
@ -386,7 +543,7 @@ gst_dvdec_loop (GstElement *element)
|
||||||
/* then read the read data */
|
/* then read the read data */
|
||||||
got_bytes = gst_bytestream_read (dvdec->bs, &buf, length);
|
got_bytes = gst_bytestream_read (dvdec->bs, &buf, length);
|
||||||
if (got_bytes < length) {
|
if (got_bytes < length) {
|
||||||
gst_dvdec_handle_event (dvdec);
|
gst_dvdec_handle_sink_event (dvdec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,9 +595,18 @@ gst_dvdec_loop (GstElement *element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we did not negotiate yet, do it now */
|
format = GST_FORMAT_TIME;
|
||||||
if (!GST_PAD_CAPS (dvdec->audiosrcpad)) {
|
gst_pad_query (dvdec->videosrcpad, GST_PAD_QUERY_POSITION, &format, &ts);
|
||||||
gst_pad_try_set_caps (dvdec->audiosrcpad,
|
|
||||||
|
if (GST_PAD_IS_CONNECTED (dvdec->audiosrcpad)) {
|
||||||
|
gint16 *a_ptr;
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
dv_decode_full_audio (dvdec->decoder, GST_BUFFER_DATA (buf), dvdec->audio_buffers);
|
||||||
|
|
||||||
|
/* if we did not negotiate yet, do it now */
|
||||||
|
if (!GST_PAD_CAPS (dvdec->audiosrcpad)) {
|
||||||
|
gst_pad_try_set_caps (dvdec->audiosrcpad,
|
||||||
GST_CAPS_NEW (
|
GST_CAPS_NEW (
|
||||||
"dvdec_audio_caps",
|
"dvdec_audio_caps",
|
||||||
"audio/raw",
|
"audio/raw",
|
||||||
|
@ -453,16 +619,7 @@ gst_dvdec_loop (GstElement *element)
|
||||||
"channels", GST_PROPS_INT (dvdec->decoder->audio->num_channels),
|
"channels", GST_PROPS_INT (dvdec->decoder->audio->num_channels),
|
||||||
"endianness", GST_PROPS_INT (G_LITTLE_ENDIAN)
|
"endianness", GST_PROPS_INT (G_LITTLE_ENDIAN)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
format = GST_FORMAT_TIME;
|
|
||||||
gst_pad_query (dvdec->videosrcpad, GST_PAD_QUERY_POSITION, &format, &ts);
|
|
||||||
|
|
||||||
if (GST_PAD_IS_CONNECTED (dvdec->audiosrcpad)) {
|
|
||||||
gint16 *a_ptr;
|
|
||||||
gint i, j;
|
|
||||||
|
|
||||||
dv_decode_full_audio (dvdec->decoder, GST_BUFFER_DATA (buf), dvdec->audio_buffers);
|
|
||||||
|
|
||||||
outbuf = gst_buffer_new ();
|
outbuf = gst_buffer_new ();
|
||||||
GST_BUFFER_SIZE (outbuf) = dvdec->decoder->audio->samples_this_frame * sizeof (gint16) * dvdec->decoder->audio->num_channels;
|
GST_BUFFER_SIZE (outbuf) = dvdec->decoder->audio->samples_this_frame * sizeof (gint16) * dvdec->decoder->audio->num_channels;
|
||||||
|
@ -477,6 +634,13 @@ gst_dvdec_loop (GstElement *element)
|
||||||
}
|
}
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = ts;
|
GST_BUFFER_TIMESTAMP (outbuf) = ts;
|
||||||
|
|
||||||
|
if (dvdec->need_discont) {
|
||||||
|
GstEvent *discont;
|
||||||
|
|
||||||
|
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, ts, NULL);
|
||||||
|
gst_pad_push (dvdec->audiosrcpad, GST_BUFFER (discont));
|
||||||
|
}
|
||||||
|
|
||||||
gst_pad_push (dvdec->audiosrcpad, outbuf);
|
gst_pad_push (dvdec->audiosrcpad, outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,11 +682,22 @@ gst_dvdec_loop (GstElement *element)
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = ts;
|
GST_BUFFER_TIMESTAMP (outbuf) = ts;
|
||||||
|
|
||||||
|
if (dvdec->need_discont) {
|
||||||
|
GstEvent *discont;
|
||||||
|
|
||||||
|
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, ts, NULL);
|
||||||
|
gst_pad_push (dvdec->videosrcpad, GST_BUFFER (discont));
|
||||||
|
}
|
||||||
|
|
||||||
gst_pad_push (dvdec->videosrcpad, outbuf);
|
gst_pad_push (dvdec->videosrcpad, outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME this is inaccurate for NTSC */
|
/* FIXME this is inaccurate for NTSC */
|
||||||
dvdec->next_ts += GST_SECOND / (PAL ? 25 : 30);
|
dvdec->next_ts += GST_SECOND / dvdec->framerate;
|
||||||
|
|
||||||
|
if (dvdec->need_discont) {
|
||||||
|
dvdec->need_discont = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,12 @@ struct _GstDVDec {
|
||||||
GstBufferPool *pool;
|
GstBufferPool *pool;
|
||||||
dv_color_space_t space;
|
dv_color_space_t space;
|
||||||
gint bpp;
|
gint bpp;
|
||||||
|
gboolean PAL;
|
||||||
|
gint framerate;
|
||||||
|
gint height;
|
||||||
gint length;
|
gint length;
|
||||||
guint64 next_ts;
|
guint64 next_ts;
|
||||||
|
gboolean need_discont;
|
||||||
|
|
||||||
gint16 *audio_buffers[4];
|
gint16 *audio_buffers[4];
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue