Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
GStreamer
gstreamer
Commits
e45b8c2b
Commit
e45b8c2b
authored
Sep 26, 2004
by
Thomas Vander Stichele
Browse files
fix typefind discont handling, #153657
Original commit message from CVS: fix typefind discont handling, #153657
parent
3cd8266b
Changes
5
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
e45b8c2b
2004-09-26 Thomas Vander Stichele <thomas at apestaart dot org>
patch by: Ronald Bultje
* gst/elements/gsttypefindelement.c: (stop_typefinding),
(gst_type_find_element_handle_event),
(gst_type_find_element_chain):
* gst/elements/gsttypefindelement.h:
#153657.
Filter out discont event from seekable sources when typefind
asks them to seek. Fixes typefind with demuxers for
avi, asf and matroska.
2004-09-26 Thomas Vander Stichele <thomas at apestaart dot org>
* docs/gst/gstreamer-sections.txt:
...
...
gst/elements/gsttypefindelement.c
View file @
e45b8c2b
...
...
@@ -84,6 +84,8 @@ enum
enum
{
MODE_NORMAL
,
/* act as identity */
MODE_TRANSITION
,
/* wait for the discont between the two
* other modes */
MODE_TYPEFIND
/* do typefinding */
};
...
...
@@ -277,7 +279,7 @@ gst_type_find_element_src_event (GstPad * pad, GstEvent * event)
{
GstTypeFindElement
*
typefind
=
GST_TYPE_FIND_ELEMENT
(
GST_PAD_PARENT
(
pad
));
if
(
typefind
->
mode
=
=
MODE_
TYPEFIND
)
{
if
(
typefind
->
mode
!
=
MODE_
NORMAL
)
{
/* need to do more? */
gst_data_unref
(
GST_DATA
(
event
));
return
FALSE
;
...
...
@@ -350,10 +352,11 @@ stop_typefinding (GstTypeFindElement * typefind)
typefind
->
possibilities
=
NULL
;
}
typefind
->
mode
=
MODE_
NORMAL
;
typefind
->
mode
=
MODE_
TRANSITION
;
if
(
push_cached_buffers
)
{
GstBuffer
*
buffer
;
if
(
!
push_cached_buffers
)
{
gst_buffer_store_clear
(
typefind
->
store
);
}
else
{
guint
size
=
gst_buffer_store_get_size
(
typefind
->
store
,
0
);
GST_DEBUG_OBJECT
(
typefind
,
"seeking back to current position %u"
,
size
);
...
...
@@ -362,18 +365,31 @@ stop_typefinding (GstTypeFindElement * typefind)
size
)))
{
GST_WARNING_OBJECT
(
typefind
,
"could not seek to required position %u, hope for the best"
,
size
);
}
gst_pad_push
(
typefind
->
src
,
GST_DATA
(
gst_event_new_discontinuous
(
TRUE
,
GST_FORMAT_DEFAULT
,
(
guint64
)
0
,
GST_FORMAT_BYTES
,
(
guint64
)
0
,
GST_FORMAT_UNDEFINED
)));
if
(
size
&&
(
buffer
=
gst_buffer_store_get_buffer
(
typefind
->
store
,
0
,
size
)))
{
GST_DEBUG_OBJECT
(
typefind
,
"pushing cached data (%u bytes)"
,
size
);
gst_pad_push
(
typefind
->
src
,
GST_DATA
(
buffer
));
typefind
->
mode
=
MODE_NORMAL
;
gst_buffer_store_clear
(
typefind
->
store
);
}
else
{
size
=
0
;
typefind
->
waiting_for_discont_offset
=
size
;
}
}
}
static
void
push_buffer_store
(
GstTypeFindElement
*
typefind
)
{
guint
size
=
gst_buffer_store_get_size
(
typefind
->
store
,
0
);
GstBuffer
*
buffer
;
gst_pad_push
(
typefind
->
src
,
GST_DATA
(
gst_event_new_discontinuous
(
TRUE
,
GST_FORMAT_DEFAULT
,
(
guint64
)
0
,
GST_FORMAT_BYTES
,
(
guint64
)
0
,
GST_FORMAT_UNDEFINED
)));
if
(
size
&&
(
buffer
=
gst_buffer_store_get_buffer
(
typefind
->
store
,
0
,
size
)))
{
GST_DEBUG_OBJECT
(
typefind
,
"pushing cached data (%u bytes)"
,
size
);
gst_pad_push
(
typefind
->
src
,
GST_DATA
(
buffer
));
}
else
{
/* FIXME: shouldn't we throw an error here? */
size
=
0
;
}
gst_buffer_store_clear
(
typefind
->
store
);
}
...
...
@@ -416,40 +432,65 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
TypeFindEntry
*
entry
;
GstTypeFindElement
*
typefind
=
GST_TYPE_FIND_ELEMENT
(
GST_PAD_PARENT
(
pad
));
if
(
typefind
->
mode
==
MODE_TYPEFIND
)
{
/* need to do more? */
switch
(
GST_EVENT_TYPE
(
event
))
{
case
GST_EVENT_EOS
:
/* this should only happen when we got all available data */
entry
=
(
TypeFindEntry
*
)
typefind
->
possibilities
?
typefind
->
possibilities
->
data
:
NULL
;
if
(
entry
&&
entry
->
probability
>=
typefind
->
min_probability
)
{
GST_INFO_OBJECT
(
typefind
,
"'%s' is the best typefind left after we got all data, using it now (probability %u)"
,
GST_PLUGIN_FEATURE_NAME
(
entry
->
factory
),
entry
->
probability
);
g_signal_emit
(
typefind
,
gst_type_find_element_signals
[
HAVE_TYPE
],
0
,
entry
->
probability
,
entry
->
caps
);
stop_typefinding
(
typefind
);
gst_pad_event_default
(
pad
,
event
);
switch
(
typefind
->
mode
)
{
case
MODE_TYPEFIND
:
switch
(
GST_EVENT_TYPE
(
event
))
{
case
GST_EVENT_EOS
:
/* this should only happen when we got all available data */
entry
=
(
TypeFindEntry
*
)
typefind
->
possibilities
?
typefind
->
possibilities
->
data
:
NULL
;
if
(
entry
&&
entry
->
probability
>=
typefind
->
min_probability
)
{
GST_INFO_OBJECT
(
typefind
,
"'%s' is the best typefind left after we got all data, using it now (probability %u)"
,
GST_PLUGIN_FEATURE_NAME
(
entry
->
factory
),
entry
->
probability
);
g_signal_emit
(
typefind
,
gst_type_find_element_signals
[
HAVE_TYPE
],
0
,
entry
->
probability
,
entry
->
caps
);
stop_typefinding
(
typefind
);
gst_pad_event_default
(
pad
,
event
);
}
else
{
gst_pad_event_default
(
pad
,
event
);
GST_ELEMENT_ERROR
(
typefind
,
STREAM
,
TYPE_NOT_FOUND
,
(
NULL
),
(
NULL
));
stop_typefinding
(
typefind
);
}
break
;
default:
gst_data_unref
(
GST_DATA
(
event
));
break
;
}
break
;
case
MODE_TRANSITION
:
if
(
GST_EVENT_TYPE
(
event
)
==
GST_EVENT_DISCONTINUOUS
)
{
if
(
GST_EVENT_DISCONT_NEW_MEDIA
(
event
))
{
start_typefinding
(
typefind
);
gst_event_unref
(
event
);
}
else
{
gst_pad_event_default
(
pad
,
event
);
GST_ELEMENT_ERROR
(
typefind
,
STREAM
,
TYPE_NOT_FOUND
,
(
NULL
),
(
NULL
));
stop_typefinding
(
typefind
);
guint64
off
;
if
(
gst_event_discont_get_value
(
event
,
GST_FORMAT_BYTES
,
&
off
)
&&
off
==
typefind
->
waiting_for_discont_offset
)
{
typefind
->
mode
=
MODE_NORMAL
;
push_buffer_store
(
typefind
);
}
else
{
gst_event_unref
(
event
);
}
}
break
;
default:
gst_data_unref
(
GST_DATA
(
event
));
break
;
}
}
else
{
if
(
GST_EVENT_TYPE
(
event
)
==
GST_EVENT_DISCONTINUOUS
&&
GST_EVENT_DISCONT_NEW_MEDIA
(
event
))
{
start_typefinding
(
typefind
);
gst_event_unref
(
event
);
}
else
{
gst_pad_event_default
(
pad
,
event
);
}
}
else
{
gst_event_unref
(
event
);
}
break
;
case
MODE_NORMAL
:
if
(
GST_EVENT_TYPE
(
event
)
==
GST_EVENT_DISCONTINUOUS
&&
GST_EVENT_DISCONT_NEW_MEDIA
(
event
))
{
start_typefinding
(
typefind
);
gst_event_unref
(
event
);
}
else
{
gst_pad_event_default
(
pad
,
event
);
}
break
;
default:
g_assert_not_reached
();
}
}
static
guint8
*
...
...
@@ -537,6 +578,9 @@ gst_type_find_element_chain (GstPad * pad, GstData * data)
case
MODE_NORMAL
:
gst_pad_push
(
typefind
->
src
,
data
);
return
;
case
MODE_TRANSITION
:
gst_data_unref
(
data
);
return
;
case
MODE_TYPEFIND
:{
guint64
current_offset
;
...
...
gst/elements/gsttypefindelement.h
View file @
e45b8c2b
...
...
@@ -53,6 +53,7 @@ struct _GstTypeFindElement {
GstCaps
*
caps
;
guint
mode
;
guint64
waiting_for_discont_offset
;
GstBufferStore
*
store
;
guint64
stream_length
;
gboolean
stream_length_available
;
...
...
plugins/elements/gsttypefindelement.c
View file @
e45b8c2b
...
...
@@ -84,6 +84,8 @@ enum
enum
{
MODE_NORMAL
,
/* act as identity */
MODE_TRANSITION
,
/* wait for the discont between the two
* other modes */
MODE_TYPEFIND
/* do typefinding */
};
...
...
@@ -277,7 +279,7 @@ gst_type_find_element_src_event (GstPad * pad, GstEvent * event)
{
GstTypeFindElement
*
typefind
=
GST_TYPE_FIND_ELEMENT
(
GST_PAD_PARENT
(
pad
));
if
(
typefind
->
mode
=
=
MODE_
TYPEFIND
)
{
if
(
typefind
->
mode
!
=
MODE_
NORMAL
)
{
/* need to do more? */
gst_data_unref
(
GST_DATA
(
event
));
return
FALSE
;
...
...
@@ -350,10 +352,11 @@ stop_typefinding (GstTypeFindElement * typefind)
typefind
->
possibilities
=
NULL
;
}
typefind
->
mode
=
MODE_
NORMAL
;
typefind
->
mode
=
MODE_
TRANSITION
;
if
(
push_cached_buffers
)
{
GstBuffer
*
buffer
;
if
(
!
push_cached_buffers
)
{
gst_buffer_store_clear
(
typefind
->
store
);
}
else
{
guint
size
=
gst_buffer_store_get_size
(
typefind
->
store
,
0
);
GST_DEBUG_OBJECT
(
typefind
,
"seeking back to current position %u"
,
size
);
...
...
@@ -362,18 +365,31 @@ stop_typefinding (GstTypeFindElement * typefind)
size
)))
{
GST_WARNING_OBJECT
(
typefind
,
"could not seek to required position %u, hope for the best"
,
size
);
}
gst_pad_push
(
typefind
->
src
,
GST_DATA
(
gst_event_new_discontinuous
(
TRUE
,
GST_FORMAT_DEFAULT
,
(
guint64
)
0
,
GST_FORMAT_BYTES
,
(
guint64
)
0
,
GST_FORMAT_UNDEFINED
)));
if
(
size
&&
(
buffer
=
gst_buffer_store_get_buffer
(
typefind
->
store
,
0
,
size
)))
{
GST_DEBUG_OBJECT
(
typefind
,
"pushing cached data (%u bytes)"
,
size
);
gst_pad_push
(
typefind
->
src
,
GST_DATA
(
buffer
));
typefind
->
mode
=
MODE_NORMAL
;
gst_buffer_store_clear
(
typefind
->
store
);
}
else
{
size
=
0
;
typefind
->
waiting_for_discont_offset
=
size
;
}
}
}
static
void
push_buffer_store
(
GstTypeFindElement
*
typefind
)
{
guint
size
=
gst_buffer_store_get_size
(
typefind
->
store
,
0
);
GstBuffer
*
buffer
;
gst_pad_push
(
typefind
->
src
,
GST_DATA
(
gst_event_new_discontinuous
(
TRUE
,
GST_FORMAT_DEFAULT
,
(
guint64
)
0
,
GST_FORMAT_BYTES
,
(
guint64
)
0
,
GST_FORMAT_UNDEFINED
)));
if
(
size
&&
(
buffer
=
gst_buffer_store_get_buffer
(
typefind
->
store
,
0
,
size
)))
{
GST_DEBUG_OBJECT
(
typefind
,
"pushing cached data (%u bytes)"
,
size
);
gst_pad_push
(
typefind
->
src
,
GST_DATA
(
buffer
));
}
else
{
/* FIXME: shouldn't we throw an error here? */
size
=
0
;
}
gst_buffer_store_clear
(
typefind
->
store
);
}
...
...
@@ -416,40 +432,65 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
TypeFindEntry
*
entry
;
GstTypeFindElement
*
typefind
=
GST_TYPE_FIND_ELEMENT
(
GST_PAD_PARENT
(
pad
));
if
(
typefind
->
mode
==
MODE_TYPEFIND
)
{
/* need to do more? */
switch
(
GST_EVENT_TYPE
(
event
))
{
case
GST_EVENT_EOS
:
/* this should only happen when we got all available data */
entry
=
(
TypeFindEntry
*
)
typefind
->
possibilities
?
typefind
->
possibilities
->
data
:
NULL
;
if
(
entry
&&
entry
->
probability
>=
typefind
->
min_probability
)
{
GST_INFO_OBJECT
(
typefind
,
"'%s' is the best typefind left after we got all data, using it now (probability %u)"
,
GST_PLUGIN_FEATURE_NAME
(
entry
->
factory
),
entry
->
probability
);
g_signal_emit
(
typefind
,
gst_type_find_element_signals
[
HAVE_TYPE
],
0
,
entry
->
probability
,
entry
->
caps
);
stop_typefinding
(
typefind
);
gst_pad_event_default
(
pad
,
event
);
switch
(
typefind
->
mode
)
{
case
MODE_TYPEFIND
:
switch
(
GST_EVENT_TYPE
(
event
))
{
case
GST_EVENT_EOS
:
/* this should only happen when we got all available data */
entry
=
(
TypeFindEntry
*
)
typefind
->
possibilities
?
typefind
->
possibilities
->
data
:
NULL
;
if
(
entry
&&
entry
->
probability
>=
typefind
->
min_probability
)
{
GST_INFO_OBJECT
(
typefind
,
"'%s' is the best typefind left after we got all data, using it now (probability %u)"
,
GST_PLUGIN_FEATURE_NAME
(
entry
->
factory
),
entry
->
probability
);
g_signal_emit
(
typefind
,
gst_type_find_element_signals
[
HAVE_TYPE
],
0
,
entry
->
probability
,
entry
->
caps
);
stop_typefinding
(
typefind
);
gst_pad_event_default
(
pad
,
event
);
}
else
{
gst_pad_event_default
(
pad
,
event
);
GST_ELEMENT_ERROR
(
typefind
,
STREAM
,
TYPE_NOT_FOUND
,
(
NULL
),
(
NULL
));
stop_typefinding
(
typefind
);
}
break
;
default:
gst_data_unref
(
GST_DATA
(
event
));
break
;
}
break
;
case
MODE_TRANSITION
:
if
(
GST_EVENT_TYPE
(
event
)
==
GST_EVENT_DISCONTINUOUS
)
{
if
(
GST_EVENT_DISCONT_NEW_MEDIA
(
event
))
{
start_typefinding
(
typefind
);
gst_event_unref
(
event
);
}
else
{
gst_pad_event_default
(
pad
,
event
);
GST_ELEMENT_ERROR
(
typefind
,
STREAM
,
TYPE_NOT_FOUND
,
(
NULL
),
(
NULL
));
stop_typefinding
(
typefind
);
guint64
off
;
if
(
gst_event_discont_get_value
(
event
,
GST_FORMAT_BYTES
,
&
off
)
&&
off
==
typefind
->
waiting_for_discont_offset
)
{
typefind
->
mode
=
MODE_NORMAL
;
push_buffer_store
(
typefind
);
}
else
{
gst_event_unref
(
event
);
}
}
break
;
default:
gst_data_unref
(
GST_DATA
(
event
));
break
;
}
}
else
{
if
(
GST_EVENT_TYPE
(
event
)
==
GST_EVENT_DISCONTINUOUS
&&
GST_EVENT_DISCONT_NEW_MEDIA
(
event
))
{
start_typefinding
(
typefind
);
gst_event_unref
(
event
);
}
else
{
gst_pad_event_default
(
pad
,
event
);
}
}
else
{
gst_event_unref
(
event
);
}
break
;
case
MODE_NORMAL
:
if
(
GST_EVENT_TYPE
(
event
)
==
GST_EVENT_DISCONTINUOUS
&&
GST_EVENT_DISCONT_NEW_MEDIA
(
event
))
{
start_typefinding
(
typefind
);
gst_event_unref
(
event
);
}
else
{
gst_pad_event_default
(
pad
,
event
);
}
break
;
default:
g_assert_not_reached
();
}
}
static
guint8
*
...
...
@@ -537,6 +578,9 @@ gst_type_find_element_chain (GstPad * pad, GstData * data)
case
MODE_NORMAL
:
gst_pad_push
(
typefind
->
src
,
data
);
return
;
case
MODE_TRANSITION
:
gst_data_unref
(
data
);
return
;
case
MODE_TYPEFIND
:{
guint64
current_offset
;
...
...
plugins/elements/gsttypefindelement.h
View file @
e45b8c2b
...
...
@@ -53,6 +53,7 @@ struct _GstTypeFindElement {
GstCaps
*
caps
;
guint
mode
;
guint64
waiting_for_discont_offset
;
GstBufferStore
*
store
;
guint64
stream_length
;
gboolean
stream_length_available
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment