mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 07:16:55 +00:00
parent
d73440cb97
commit
5d9c8996da
1 changed files with 101 additions and 26 deletions
|
@ -387,6 +387,13 @@ GST_BOILERPLATE (GstQTDemux, gst_qtdemux, GstQTDemux, GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
static void gst_qtdemux_dispose (GObject * object);
|
static void gst_qtdemux_dispose (GObject * object);
|
||||||
|
|
||||||
|
static guint32
|
||||||
|
gst_qtdemux_find_index_linear (GstQTDemux * qtdemux, QtDemuxStream * str,
|
||||||
|
guint64 media_time);
|
||||||
|
static guint32
|
||||||
|
gst_qtdemux_find_index_for_given_media_offset_linear (GstQTDemux * qtdemux,
|
||||||
|
QtDemuxStream * str, gint64 media_offset);
|
||||||
|
|
||||||
static void gst_qtdemux_set_index (GstElement * element, GstIndex * index);
|
static void gst_qtdemux_set_index (GstElement * element, GstIndex * index);
|
||||||
static GstIndex *gst_qtdemux_get_index (GstElement * element);
|
static GstIndex *gst_qtdemux_get_index (GstElement * element);
|
||||||
static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element,
|
static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element,
|
||||||
|
@ -561,47 +568,57 @@ gst_qtdemux_pull_atom (GstQTDemux * qtdemux, guint64 offset, guint64 size,
|
||||||
return flow;
|
return flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_qtdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
|
gst_qtdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
|
||||||
GstFormat * dest_format, gint64 * dest_value)
|
GstFormat dest_format, gint64 * dest_value)
|
||||||
{
|
{
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
QtDemuxStream *stream = gst_pad_get_element_private (pad);
|
QtDemuxStream *stream = gst_pad_get_element_private (pad);
|
||||||
|
GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad));
|
||||||
|
gint32 index;
|
||||||
|
|
||||||
if (stream->subtype == GST_MAKE_FOURCC ('v', 'i', 'd', 'e') &&
|
if (stream->subtype != FOURCC_vide)
|
||||||
(src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
switch (src_format) {
|
switch (src_format) {
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
switch (*dest_format) {
|
switch (dest_format) {
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:{
|
||||||
*dest_value = src_value * 1; /* FIXME */
|
index = gst_qtdemux_find_index_linear (qtdemux, stream, src_value);
|
||||||
break;
|
if (-1 == index)
|
||||||
case GST_FORMAT_DEFAULT:
|
return FALSE;
|
||||||
*dest_value = src_value * 1; /* FIXME */
|
|
||||||
|
*dest_value = stream->samples[index].offset;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (qtdemux, "Format Conversion Time->Offset :%"
|
||||||
|
GST_TIME_FORMAT "->%" G_GUINT64_FORMAT,
|
||||||
|
GST_TIME_ARGS (src_value), *dest_value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
switch (*dest_format) {
|
switch (dest_format) {
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:{
|
||||||
*dest_value = src_value * 1; /* FIXME */
|
index =
|
||||||
break;
|
gst_qtdemux_find_index_for_given_media_offset_linear (qtdemux,
|
||||||
default:
|
stream, src_value);
|
||||||
res = FALSE;
|
|
||||||
break;
|
if (-1 == index)
|
||||||
}
|
return FALSE;
|
||||||
break;
|
|
||||||
case GST_FORMAT_DEFAULT:
|
*dest_value =
|
||||||
switch (*dest_format) {
|
gst_util_uint64_scale (stream->samples[index].timestamp,
|
||||||
case GST_FORMAT_TIME:
|
GST_SECOND, stream->timescale);
|
||||||
*dest_value = src_value * 1; /* FIXME */
|
GST_DEBUG_OBJECT (qtdemux, "Format Conversion Offset->Time :%"
|
||||||
|
G_GUINT64_FORMAT "->%" GST_TIME_FORMAT,
|
||||||
|
src_value, GST_TIME_ARGS (*dest_value));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
break;
|
break;
|
||||||
|
@ -621,6 +638,8 @@ gst_qtdemux_get_src_query_types (GstPad * pad)
|
||||||
static const GstQueryType src_types[] = {
|
static const GstQueryType src_types[] = {
|
||||||
GST_QUERY_POSITION,
|
GST_QUERY_POSITION,
|
||||||
GST_QUERY_DURATION,
|
GST_QUERY_DURATION,
|
||||||
|
GST_QUERY_CONVERT,
|
||||||
|
GST_QUERY_FORMATS,
|
||||||
GST_QUERY_SEEKING,
|
GST_QUERY_SEEKING,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -675,6 +694,24 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstQuery * query)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GST_QUERY_CONVERT:{
|
||||||
|
GstFormat src_fmt, dest_fmt;
|
||||||
|
gint64 src_value, dest_value;
|
||||||
|
|
||||||
|
gst_query_parse_convert (query, &src_fmt, &src_value, &dest_fmt, NULL);
|
||||||
|
|
||||||
|
res = gst_qtdemux_src_convert (pad,
|
||||||
|
src_fmt, src_value, dest_fmt, &dest_value);
|
||||||
|
if (res) {
|
||||||
|
gst_query_set_convert (query, src_fmt, src_value, dest_fmt, dest_value);
|
||||||
|
res = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GST_QUERY_FORMATS:
|
||||||
|
gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);
|
||||||
|
res = TRUE;
|
||||||
|
break;
|
||||||
case GST_QUERY_SEEKING:{
|
case GST_QUERY_SEEKING:{
|
||||||
GstFormat fmt;
|
GstFormat fmt;
|
||||||
gboolean seekable;
|
gboolean seekable;
|
||||||
|
@ -825,6 +862,44 @@ gst_qtdemux_find_index (GstQTDemux * qtdemux, QtDemuxStream * str,
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* find the index of the sample that includes the data for @media_offset using a
|
||||||
|
* linear search
|
||||||
|
*
|
||||||
|
* Returns the index of the sample.
|
||||||
|
*/
|
||||||
|
static guint32
|
||||||
|
gst_qtdemux_find_index_for_given_media_offset_linear (GstQTDemux * qtdemux,
|
||||||
|
QtDemuxStream * str, gint64 media_offset)
|
||||||
|
{
|
||||||
|
QtDemuxSample *result = str->samples;
|
||||||
|
guint32 index = 0;
|
||||||
|
|
||||||
|
if (media_offset == result->offset)
|
||||||
|
return index;
|
||||||
|
|
||||||
|
result++;
|
||||||
|
while (index < str->n_samples - 1) {
|
||||||
|
if (!qtdemux_parse_samples (qtdemux, str, index + 1))
|
||||||
|
goto parse_failed;
|
||||||
|
|
||||||
|
if (media_offset < result->offset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
index++;
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
parse_failed:
|
||||||
|
{
|
||||||
|
GST_LOG_OBJECT (qtdemux, "Parsing of index %u failed!", index + 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* find the index of the sample that includes the data for @media_time using a
|
/* find the index of the sample that includes the data for @media_time using a
|
||||||
* linear search, and keeping in mind that not all samples may have been parsed
|
* linear search, and keeping in mind that not all samples may have been parsed
|
||||||
* yet. If possible, it will delegate to binary search.
|
* yet. If possible, it will delegate to binary search.
|
||||||
|
@ -5123,7 +5198,7 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
|
||||||
/* sync sample atom */
|
/* sync sample atom */
|
||||||
stream->stps_present = FALSE;
|
stream->stps_present = FALSE;
|
||||||
if ((stream->stss_present =
|
if ((stream->stss_present =
|
||||||
!!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stss,
|
! !qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stss,
|
||||||
&stream->stss) ? TRUE : FALSE) == TRUE) {
|
&stream->stss) ? TRUE : FALSE) == TRUE) {
|
||||||
/* copy atom data into a new buffer for later use */
|
/* copy atom data into a new buffer for later use */
|
||||||
stream->stss.data = g_memdup (stream->stss.data, stream->stss.size);
|
stream->stss.data = g_memdup (stream->stss.data, stream->stss.size);
|
||||||
|
@ -5141,7 +5216,7 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
|
||||||
|
|
||||||
/* partial sync sample atom */
|
/* partial sync sample atom */
|
||||||
if ((stream->stps_present =
|
if ((stream->stps_present =
|
||||||
!!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stps,
|
! !qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stps,
|
||||||
&stream->stps) ? TRUE : FALSE) == TRUE) {
|
&stream->stps) ? TRUE : FALSE) == TRUE) {
|
||||||
/* copy atom data into a new buffer for later use */
|
/* copy atom data into a new buffer for later use */
|
||||||
stream->stps.data = g_memdup (stream->stps.data, stream->stps.size);
|
stream->stps.data = g_memdup (stream->stps.data, stream->stps.size);
|
||||||
|
@ -5261,7 +5336,7 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
|
||||||
|
|
||||||
/* composition time-to-sample */
|
/* composition time-to-sample */
|
||||||
if ((stream->ctts_present =
|
if ((stream->ctts_present =
|
||||||
!!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_ctts,
|
! !qtdemux_tree_get_child_by_type_full (stbl, FOURCC_ctts,
|
||||||
&stream->ctts) ? TRUE : FALSE) == TRUE) {
|
&stream->ctts) ? TRUE : FALSE) == TRUE) {
|
||||||
/* copy atom data into a new buffer for later use */
|
/* copy atom data into a new buffer for later use */
|
||||||
stream->ctts.data = g_memdup (stream->ctts.data, stream->ctts.size);
|
stream->ctts.data = g_memdup (stream->ctts.data, stream->ctts.size);
|
||||||
|
|
Loading…
Reference in a new issue