Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
George Kiagiadakis
gst-plugins-good
Commits
710fa239
Commit
710fa239
authored
Jun 08, 2011
by
Wim Taymans
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into 0.11
parents
0af32751
9175a903
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
833 additions
and
1343 deletions
+833
-1343
ext/soup/gstsouphttpsink.c
ext/soup/gstsouphttpsink.c
+71
-19
ext/soup/gstsouphttpsink.h
ext/soup/gstsouphttpsink.h
+2
-0
gst/interleave/interleave.c
gst/interleave/interleave.c
+5
-0
gst/matroska/matroska-demux.c
gst/matroska/matroska-demux.c
+102
-681
gst/matroska/matroska-demux.h
gst/matroska/matroska-demux.h
+0
-9
gst/matroska/matroska-parse.c
gst/matroska/matroska-parse.c
+39
-625
gst/matroska/matroska-parse.h
gst/matroska/matroska-parse.h
+0
-9
gst/matroska/matroska-read-common.c
gst/matroska/matroska-read-common.c
+593
-0
gst/matroska/matroska-read-common.h
gst/matroska/matroska-read-common.h
+19
-0
gst/rtsp/gstrtspsrc.c
gst/rtsp/gstrtspsrc.c
+2
-0
No files found.
ext/soup/gstsouphttpsink.c
View file @
710fa239
...
...
@@ -74,6 +74,9 @@ static void authenticate (SoupSession * session, SoupMessage * msg,
SoupAuth
*
auth
,
gboolean
retrying
,
gpointer
user_data
);
static
void
callback
(
SoupSession
*
session
,
SoupMessage
*
msg
,
gpointer
user_data
);
static
gboolean
gst_soup_http_sink_set_proxy
(
GstSoupHttpSink
*
souphttpsink
,
const
gchar
*
uri
);
enum
{
...
...
@@ -87,7 +90,7 @@ enum
PROP_PROXY_ID
,
PROP_PROXY_PW
,
PROP_COOKIES
,
PROP_SESSION
,
PROP_SESSION
};
#define DEFAULT_USER_AGENT "GStreamer souphttpsink "
...
...
@@ -159,13 +162,11 @@ gst_soup_http_sink_class_init (GstSoupHttpSinkClass * klass)
g_param_spec_boolean
(
"automatic-redirect"
,
"automatic-redirect"
,
"Automatically follow HTTP redirects (HTTP Status Code 3xx)"
,
TRUE
,
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
#if 0
g_object_class_install_property
(
gobject_class
,
PROP_PROXY
,
g_param_spec_string
(
"proxy"
,
"Proxy"
,
"HTTP proxy server URI"
,
""
,
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
#endif
g_object_class_install_property
(
gobject_class
,
PROP_USER_ID
,
g_param_spec_string
(
"user-id"
,
"user-id"
,
...
...
@@ -187,7 +188,9 @@ gst_soup_http_sink_class_init (GstSoupHttpSinkClass * klass)
g_param_spec_object
(
"session"
,
"session"
,
"SoupSession object to use for communication"
,
SOUP_TYPE_SESSION
,
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
g_object_class_install_property
(
gobject_class
,
PROP_COOKIES
,
g_param_spec_boxed
(
"cookies"
,
"Cookies"
,
"HTTP request cookies"
,
G_TYPE_STRV
,
G_PARAM_READWRITE
|
G_PARAM_STATIC_STRINGS
));
}
...
...
@@ -195,9 +198,7 @@ static void
gst_soup_http_sink_init
(
GstSoupHttpSink
*
souphttpsink
,
GstSoupHttpSinkClass
*
souphttpsink_class
)
{
#if 0
const
char
*
proxy
;
#endif
souphttpsink
->
sinkpad
=
gst_pad_new_from_static_template
(
&
gst_soup_http_sink_sink_template
,
...
...
@@ -215,14 +216,12 @@ gst_soup_http_sink_init (GstSoupHttpSink * souphttpsink,
souphttpsink
->
proxy_pw
=
NULL
;
souphttpsink
->
prop_session
=
NULL
;
souphttpsink
->
timeout
=
1
;
#if 0
proxy
=
g_getenv
(
"http_proxy"
);
if
(
proxy
&&
!
gst_soup_http_sink_set_proxy
(
souphttpsink
,
proxy
))
{
GST_WARNING_OBJECT
(
souphttpsink
,
"The proxy in the http_proxy env var (
\"
%s
\"
) cannot be parsed."
,
proxy
);
}
#endif
gst_soup_http_sink_reset
(
souphttpsink
);
}
...
...
@@ -237,6 +236,25 @@ gst_soup_http_sink_reset (GstSoupHttpSink * souphttpsink)
}
static
gboolean
gst_soup_http_sink_set_proxy
(
GstSoupHttpSink
*
souphttpsink
,
const
gchar
*
uri
)
{
if
(
souphttpsink
->
proxy
)
{
soup_uri_free
(
souphttpsink
->
proxy
);
souphttpsink
->
proxy
=
NULL
;
}
if
(
g_str_has_prefix
(
uri
,
"http://"
))
{
souphttpsink
->
proxy
=
soup_uri_new
(
uri
);
}
else
{
gchar
*
new_uri
=
g_strconcat
(
"http://"
,
uri
,
NULL
);
souphttpsink
->
proxy
=
soup_uri_new
(
new_uri
);
g_free
(
new_uri
);
}
return
TRUE
;
}
void
gst_soup_http_sink_set_property
(
GObject
*
object
,
guint
property_id
,
const
GValue
*
value
,
GParamSpec
*
pspec
)
...
...
@@ -279,10 +297,31 @@ gst_soup_http_sink_set_property (GObject * object, guint property_id,
g_free
(
souphttpsink
->
proxy_pw
);
souphttpsink
->
proxy_pw
=
g_value_dup_string
(
value
);
break
;
case
PROP_PROXY
:
{
const
gchar
*
proxy
;
proxy
=
g_value_get_string
(
value
);
if
(
proxy
==
NULL
)
{
GST_WARNING
(
"proxy property cannot be NULL"
);
goto
done
;
}
if
(
!
gst_soup_http_sink_set_proxy
(
souphttpsink
,
proxy
))
{
GST_WARNING
(
"badly formatted proxy URI"
);
goto
done
;
}
break
;
}
case
PROP_COOKIES
:
g_strfreev
(
souphttpsink
->
cookies
);
souphttpsink
->
cookies
=
g_strdupv
(
g_value_get_boxed
(
value
));
break
;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
object
,
property_id
,
pspec
);
break
;
}
done:
g_mutex_unlock
(
souphttpsink
->
mutex
);
}
...
...
@@ -317,7 +356,19 @@ gst_soup_http_sink_get_property (GObject * object, guint property_id,
case
PROP_PROXY_PW
:
g_value_set_string
(
value
,
souphttpsink
->
proxy_pw
);
break
;
case
PROP_PROXY
:
if
(
souphttpsink
->
proxy
==
NULL
)
g_value_set_static_string
(
value
,
""
);
else
{
char
*
proxy
=
soup_uri_to_string
(
souphttpsink
->
proxy
,
FALSE
);
g_value_set_string
(
value
,
proxy
);
g_free
(
proxy
);
}
break
;
case
PROP_COOKIES
:
g_value_set_boxed
(
value
,
g_strdupv
(
souphttpsink
->
cookies
));
break
;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
object
,
property_id
,
pspec
);
break
;
...
...
@@ -349,6 +400,8 @@ gst_soup_http_sink_finalize (GObject * object)
g_free
(
souphttpsink
->
user_pw
);
g_free
(
souphttpsink
->
proxy_id
);
g_free
(
souphttpsink
->
proxy_pw
);
if
(
souphttpsink
->
proxy
)
soup_uri_free
(
souphttpsink
->
proxy
);
g_free
(
souphttpsink
->
location
);
g_cond_free
(
souphttpsink
->
cond
);
...
...
@@ -482,17 +535,17 @@ gst_soup_http_sink_event (GstBaseSink * sink, GstEvent * event)
{
GstSoupHttpSink
*
souphttpsink
=
GST_SOUP_HTTP_SINK
(
sink
);
GST_DEBUG
(
"event"
);
GST_DEBUG
_OBJECT
(
souphttpsink
,
"event"
);
if
(
GST_EVENT_TYPE
(
event
)
==
GST_EVENT_EOS
)
{
GST_DEBUG
(
"got eos"
);
GST_DEBUG
_OBJECT
(
souphttpsink
,
"got eos"
);
g_mutex_lock
(
souphttpsink
->
mutex
);
while
(
souphttpsink
->
message
)
{
GST_DEBUG
(
"waiting"
);
GST_DEBUG
_OBJECT
(
souphttpsink
,
"waiting"
);
g_cond_wait
(
souphttpsink
->
cond
,
souphttpsink
->
mutex
);
}
g_mutex_unlock
(
souphttpsink
->
mutex
);
GST_DEBUG
(
"finished eos"
);
GST_DEBUG
_OBJECT
(
souphttpsink
,
"finished eos"
);
}
return
TRUE
;
...
...
@@ -536,8 +589,6 @@ send_message_locked (GstSoupHttpSink * souphttpsink)
souphttpsink
->
message
=
soup_message_new
(
"PUT"
,
souphttpsink
->
location
);
//soup_message_body_set_accumulate (souphttpsink->message->request_body, TRUE);
n
=
0
;
if
(
souphttpsink
->
offset
==
0
)
{
for
(
g
=
souphttpsink
->
streamheader_buffers
;
g
;
g
=
g_list_next
(
g
))
{
...
...
@@ -579,10 +630,11 @@ send_message_locked (GstSoupHttpSink * souphttpsink)
souphttpsink
->
sent_buffers
=
souphttpsink
->
queued_buffers
;
souphttpsink
->
queued_buffers
=
NULL
;
GST_DEBUG
(
"queue message %"
G_GUINT64_FORMAT
" %"
G_GUINT64_FORMAT
,
GST_DEBUG_OBJECT
(
souphttpsink
,
"queue message %"
G_GUINT64_FORMAT
" %"
G_GUINT64_FORMAT
,
souphttpsink
->
offset
,
n
);
soup_session_queue_message
(
souphttpsink
->
session
,
souphttpsink
->
message
,
callback
,
souphttpsink
);
soup_session_queue_message
(
souphttpsink
->
session
,
souphttpsink
->
message
,
callback
,
souphttpsink
);
souphttpsink
->
offset
+=
n
;
}
...
...
@@ -631,6 +683,7 @@ gst_soup_http_sink_render (GstBaseSink * sink, GstBuffer * buffer)
gboolean
wake
;
if
(
souphttpsink
->
status_code
!=
0
)
{
/* FIXME we should allow a moderate amount of retries. */
GST_ELEMENT_ERROR
(
souphttpsink
,
RESOURCE
,
WRITE
,
(
"Could not write to HTTP URI"
),
(
"error: %d %s"
,
souphttpsink
->
status_code
,
...
...
@@ -646,7 +699,6 @@ gst_soup_http_sink_render (GstBaseSink * sink, GstBuffer * buffer)
if
(
wake
)
{
source
=
g_idle_source_new
();
//g_source_set_priority (source, G_PRIORITY_DEFAULT);
g_source_set_callback
(
source
,
(
GSourceFunc
)
(
send_message
),
souphttpsink
,
NULL
);
g_source_attach
(
source
,
souphttpsink
->
context
);
...
...
ext/soup/gstsouphttpsink.h
View file @
710fa239
...
...
@@ -62,10 +62,12 @@ struct _GstSoupHttpSink
char
*
location
;
char
*
user_id
;
char
*
user_pw
;
SoupURI
*
proxy
;
char
*
proxy_id
;
char
*
proxy_pw
;
char
*
user_agent
;
gboolean
automatic_redirect
;
gchar
**
cookies
;
};
...
...
gst/interleave/interleave.c
View file @
710fa239
...
...
@@ -479,8 +479,13 @@ gst_interleave_request_new_pad (GstElement * element, GstPadTemplate * templ,
if
(
templ
->
direction
!=
GST_PAD_SINK
)
goto
not_sink_pad
;
#if GLIB_CHECK_VERSION(2,29,5)
channels
=
g_atomic_int_add
(
&
self
->
channels
,
1
);
padnumber
=
g_atomic_int_add
(
&
self
->
padcounter
,
1
);
#else
channels
=
g_atomic_int_exchange_and_add
(
&
self
->
channels
,
1
);
padnumber
=
g_atomic_int_exchange_and_add
(
&
self
->
padcounter
,
1
);
#endif
pad_name
=
g_strdup_printf
(
"sink%d"
,
padnumber
);
new_pad
=
GST_PAD_CAST
(
g_object_new
(
GST_TYPE_INTERLEAVE_PAD
,
...
...
gst/matroska/matroska-demux.c
View file @
710fa239
This diff is collapsed.
Click to expand it.
gst/matroska/matroska-demux.h
View file @
710fa239
...
...
@@ -55,11 +55,6 @@ typedef struct _GstMatroskaDemux {
guint
num_a_streams
;
guint
num_t_streams
;
/* metadata */
gchar
*
muxing_app
;
gchar
*
writing_app
;
gint64
created
;
/* state */
gboolean
streaming
;
guint
level_up
;
...
...
@@ -68,16 +63,12 @@ typedef struct _GstMatroskaDemux {
/* did we parse cues/tracks/segmentinfo already? */
gboolean
tracks_parsed
;
gboolean
segmentinfo_parsed
;
gboolean
attachments_parsed
;
GList
*
tags_parsed
;
GList
*
seek_parsed
;
/* cluster positions (optional) */
GArray
*
clusters
;
/* keeping track of playback position */
GstSegment
segment
;
gboolean
segment_running
;
GstClockTime
last_stop_end
;
...
...
gst/matroska/matroska-parse.c
View file @
710fa239
This diff is collapsed.
Click to expand it.
gst/matroska/matroska-parse.h
View file @
710fa239
...
...
@@ -60,11 +60,6 @@ typedef struct _GstMatroskaParse {
gboolean
pushed_headers
;
GstClockTime
last_timestamp
;
/* metadata */
gchar
*
muxing_app
;
gchar
*
writing_app
;
gint64
created
;
/* state */
//gboolean streaming;
guint
level_up
;
...
...
@@ -73,13 +68,9 @@ typedef struct _GstMatroskaParse {
/* did we parse cues/tracks/segmentinfo already? */
gboolean
tracks_parsed
;
gboolean
segmentinfo_parsed
;
gboolean
attachments_parsed
;
GList
*
tags_parsed
;
GList
*
seek_parsed
;
/* keeping track of playback position */
GstSegment
segment
;
gboolean
segment_running
;
GstClockTime
last_stop_end
;
...
...
gst/matroska/matroska-read-common.c
View file @
710fa239
...
...
@@ -36,6 +36,9 @@
#include <bzlib.h>
#endif
#include <gst/tag/tag.h>
#include <gst/base/gsttypefindhelper.h>
#include "lzo.h"
#include "ebml-read.h"
...
...
@@ -484,6 +487,242 @@ gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
return
gst_ebml_read_skip
(
ebml
);
}
static
GstFlowReturn
gst_matroska_read_common_parse_attached_file
(
GstMatroskaReadCommon
*
common
,
GstEbmlRead
*
ebml
,
GstTagList
*
taglist
)
{
guint32
id
;
GstFlowReturn
ret
;
gchar
*
description
=
NULL
;
gchar
*
filename
=
NULL
;
gchar
*
mimetype
=
NULL
;
guint8
*
data
=
NULL
;
guint64
datalen
=
0
;
DEBUG_ELEMENT_START
(
common
,
ebml
,
"AttachedFile"
);
if
((
ret
=
gst_ebml_read_master
(
ebml
,
&
id
))
!=
GST_FLOW_OK
)
{
DEBUG_ELEMENT_STOP
(
common
,
ebml
,
"AttachedFile"
,
ret
);
return
ret
;
}
while
(
ret
==
GST_FLOW_OK
&&
gst_ebml_read_has_remaining
(
ebml
,
1
,
TRUE
))
{
/* read all sub-entries */
if
((
ret
=
gst_ebml_peek_id
(
ebml
,
&
id
))
!=
GST_FLOW_OK
)
break
;
switch
(
id
)
{
case
GST_MATROSKA_ID_FILEDESCRIPTION
:
if
(
description
)
{
GST_WARNING_OBJECT
(
common
,
"FileDescription can only appear once"
);
break
;
}
ret
=
gst_ebml_read_utf8
(
ebml
,
&
id
,
&
description
);
GST_DEBUG_OBJECT
(
common
,
"FileDescription: %s"
,
GST_STR_NULL
(
description
));
break
;
case
GST_MATROSKA_ID_FILENAME
:
if
(
filename
)
{
GST_WARNING_OBJECT
(
common
,
"FileName can only appear once"
);
break
;
}
ret
=
gst_ebml_read_utf8
(
ebml
,
&
id
,
&
filename
);
GST_DEBUG_OBJECT
(
common
,
"FileName: %s"
,
GST_STR_NULL
(
filename
));
break
;
case
GST_MATROSKA_ID_FILEMIMETYPE
:
if
(
mimetype
)
{
GST_WARNING_OBJECT
(
common
,
"FileMimeType can only appear once"
);
break
;
}
ret
=
gst_ebml_read_ascii
(
ebml
,
&
id
,
&
mimetype
);
GST_DEBUG_OBJECT
(
common
,
"FileMimeType: %s"
,
GST_STR_NULL
(
mimetype
));
break
;
case
GST_MATROSKA_ID_FILEDATA
:
if
(
data
)
{
GST_WARNING_OBJECT
(
common
,
"FileData can only appear once"
);
break
;
}
ret
=
gst_ebml_read_binary
(
ebml
,
&
id
,
&
data
,
&
datalen
);
GST_DEBUG_OBJECT
(
common
,
"FileData of size %"
G_GUINT64_FORMAT
,
datalen
);
break
;
default:
ret
=
gst_matroska_read_common_parse_skip
(
common
,
ebml
,
"AttachedFile"
,
id
);
break
;
case
GST_MATROSKA_ID_FILEUID
:
ret
=
gst_ebml_read_skip
(
ebml
);
break
;
}
}
DEBUG_ELEMENT_STOP
(
common
,
ebml
,
"AttachedFile"
,
ret
);
if
(
filename
&&
mimetype
&&
data
&&
datalen
>
0
)
{
GstTagImageType
image_type
=
GST_TAG_IMAGE_TYPE_NONE
;
GstBuffer
*
tagbuffer
=
NULL
;
GstCaps
*
caps
;
gchar
*
filename_lc
=
g_utf8_strdown
(
filename
,
-
1
);
GST_DEBUG_OBJECT
(
common
,
"Creating tag for attachment with "
"filename '%s', mimetype '%s', description '%s', "
"size %"
G_GUINT64_FORMAT
,
filename
,
mimetype
,
GST_STR_NULL
(
description
),
datalen
);
/* TODO: better heuristics for different image types */
if
(
strstr
(
filename_lc
,
"cover"
))
{
if
(
strstr
(
filename_lc
,
"back"
))
image_type
=
GST_TAG_IMAGE_TYPE_BACK_COVER
;
else
image_type
=
GST_TAG_IMAGE_TYPE_FRONT_COVER
;
}
else
if
(
g_str_has_prefix
(
mimetype
,
"image/"
)
||
g_str_has_suffix
(
filename_lc
,
"png"
)
||
g_str_has_suffix
(
filename_lc
,
"jpg"
)
||
g_str_has_suffix
(
filename_lc
,
"jpeg"
)
||
g_str_has_suffix
(
filename_lc
,
"gif"
)
||
g_str_has_suffix
(
filename_lc
,
"bmp"
))
{
image_type
=
GST_TAG_IMAGE_TYPE_UNDEFINED
;
}
g_free
(
filename_lc
);
/* First try to create an image tag buffer from this */
if
(
image_type
!=
GST_TAG_IMAGE_TYPE_NONE
)
{
tagbuffer
=
gst_tag_image_data_to_image_buffer
(
data
,
datalen
,
image_type
);
if
(
!
tagbuffer
)
image_type
=
GST_TAG_IMAGE_TYPE_NONE
;
}
/* if this failed create an attachment buffer */
if
(
!
tagbuffer
)
{
tagbuffer
=
gst_buffer_new_and_alloc
(
datalen
);
memcpy
(
GST_BUFFER_DATA
(
tagbuffer
),
data
,
datalen
);
GST_BUFFER_SIZE
(
tagbuffer
)
=
datalen
;
caps
=
gst_type_find_helper_for_buffer
(
NULL
,
tagbuffer
,
NULL
);
if
(
caps
==
NULL
)
caps
=
gst_caps_new_simple
(
mimetype
,
NULL
);
gst_buffer_set_caps
(
tagbuffer
,
caps
);
gst_caps_unref
(
caps
);
}
/* Set filename and description on the caps */
caps
=
GST_BUFFER_CAPS
(
tagbuffer
);
gst_caps_set_simple
(
caps
,
"filename"
,
G_TYPE_STRING
,
filename
,
NULL
);
if
(
description
)
gst_caps_set_simple
(
caps
,
"description"
,
G_TYPE_STRING
,
description
,
NULL
);
GST_DEBUG_OBJECT
(
common
,
"Created attachment buffer with caps: %"
GST_PTR_FORMAT
,
caps
);
/* and append to the tag list */
if
(
image_type
!=
GST_TAG_IMAGE_TYPE_NONE
)
gst_tag_list_add
(
taglist
,
GST_TAG_MERGE_APPEND
,
GST_TAG_IMAGE
,
tagbuffer
,
NULL
);
else
gst_tag_list_add
(
taglist
,
GST_TAG_MERGE_APPEND
,
GST_TAG_ATTACHMENT
,
tagbuffer
,
NULL
);
}
g_free
(
filename
);
g_free
(
mimetype
);
g_free
(
data
);
g_free
(
description
);
return
ret
;
}
GstFlowReturn
gst_matroska_read_common_parse_attachments
(
GstMatroskaReadCommon
*
common
,
GstElement
*
el
,
GstEbmlRead
*
ebml
)
{
guint32
id
;
GstFlowReturn
ret
=
GST_FLOW_OK
;
GstTagList
*
taglist
;
DEBUG_ELEMENT_START
(
common
,
ebml
,
"Attachments"
);
if
((
ret
=
gst_ebml_read_master
(
ebml
,
&
id
))
!=
GST_FLOW_OK
)
{
DEBUG_ELEMENT_STOP
(
common
,
ebml
,
"Attachments"
,
ret
);
return
ret
;
}
taglist
=
gst_tag_list_new
();
while
(
ret
==
GST_FLOW_OK
&&
gst_ebml_read_has_remaining
(
ebml
,
1
,
TRUE
))
{
if
((
ret
=
gst_ebml_peek_id
(
ebml
,
&
id
))
!=
GST_FLOW_OK
)
break
;
switch
(
id
)
{
case
GST_MATROSKA_ID_ATTACHEDFILE
:
ret
=
gst_matroska_read_common_parse_attached_file
(
common
,
ebml
,
taglist
);
break
;
default:
ret
=
gst_matroska_read_common_parse_skip
(
common
,
ebml
,
"Attachments"
,
id
);
break
;
}
}
DEBUG_ELEMENT_STOP
(
common
,
ebml
,
"Attachments"
,
ret
);
if
(
gst_structure_n_fields
(
GST_STRUCTURE
(
taglist
))
>
0
)
{
GST_DEBUG_OBJECT
(
common
,
"Storing attachment tags"
);
gst_matroska_read_common_found_global_tag
(
common
,
el
,
taglist
);
}
else
{
GST_DEBUG_OBJECT
(
common
,
"No valid attachments found"
);
gst_tag_list_free
(
taglist
);
}
common
->
attachments_parsed
=
TRUE
;
return
ret
;
}
GstFlowReturn
gst_matroska_read_common_parse_chapters
(
GstMatroskaReadCommon
*
common
,
GstEbmlRead
*
ebml
)
{
guint32
id
;
GstFlowReturn
ret
=
GST_FLOW_OK
;
GST_WARNING_OBJECT
(
common
,
"Parsing of chapters not implemented yet"
);
/* TODO: implement parsing of chapters */
DEBUG_ELEMENT_START
(
common
,
ebml
,
"Chapters"
);
if
((
ret
=
gst_ebml_read_master
(
ebml
,
&
id
))
!=
GST_FLOW_OK
)
{
DEBUG_ELEMENT_STOP
(
common
,
ebml
,
"Chapters"
,
ret
);
return
ret
;
}
while
(
ret
==
GST_FLOW_OK
&&
gst_ebml_read_has_remaining
(
ebml
,
1
,
TRUE
))
{
if
((
ret
=
gst_ebml_peek_id
(
ebml
,
&
id
))
!=
GST_FLOW_OK
)
break
;
switch
(
id
)
{
default:
ret
=
gst_ebml_read_skip
(
ebml
);
break
;
}
}
DEBUG_ELEMENT_STOP
(
common
,
ebml
,
"Chapters"
,
ret
);
return
ret
;
}
GstFlowReturn
gst_matroska_read_common_parse_header
(
GstMatroskaReadCommon
*
common
,
GstEbmlRead
*
ebml
)
...
...
@@ -953,6 +1192,360 @@ gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
return
ret
;
}
GstFlowReturn
gst_matroska_read_common_parse_info
(
GstMatroskaReadCommon
*
common
,
GstElement
*
el
,
GstEbmlRead
*
ebml
)
{
GstFlowReturn
ret
=
GST_FLOW_OK
;
gdouble
dur_f
=
-
1
.
0
;
guint32
id
;
DEBUG_ELEMENT_START
(
common
,
ebml
,
"SegmentInfo"
);
if
((
ret
=
gst_ebml_read_master
(
ebml
,
&
id
))
!=
GST_FLOW_OK
)
{
DEBUG_ELEMENT_STOP
(
common
,
ebml
,
"SegmentInfo"
,
ret
);
return
ret
;
}
while
(
ret
==
GST_FLOW_OK
&&
gst_ebml_read_has_remaining
(
ebml
,
1
,
TRUE
))
{
if
((
ret
=
gst_ebml_peek_id
(
ebml
,
&
id
))
!=
GST_FLOW_OK
)
break
;
switch
(
id
)
{
/* cluster timecode */
case
GST_MATROSKA_ID_TIMECODESCALE
:{
guint64
num
;
if
((
ret
=
gst_ebml_read_uint
(
ebml
,
&
id
,
&
num
))
!=
GST_FLOW_OK
)
break
;
GST_DEBUG_OBJECT
(
common
,
"TimeCodeScale: %"
G_GUINT64_FORMAT
,
num
);
common
->
time_scale
=
num
;
break
;
}
case
GST_MATROSKA_ID_DURATION
:{
if
((
ret
=
gst_ebml_read_float
(
ebml
,
&
id
,
&
dur_f
))
!=
GST_FLOW_OK
)
break
;
if
(
dur_f
<=
0
.
0
)
{
GST_WARNING_OBJECT
(
common
,
"Invalid duration %lf"
,
dur_f
);
break
;
}
GST_DEBUG_OBJECT
(
common
,
"Duration: %lf"
,
dur_f
);
break
;
}
case
GST_MATROSKA_ID_WRITINGAPP
:{
gchar
*
text
;
if
((
ret
=
gst_ebml_read_utf8
(
ebml
,
&
id
,
&
text
))
!=
GST_FLOW_OK
)
break
;
GST_DEBUG_OBJECT
(
common
,
"WritingApp: %s"
,
GST_STR_NULL
(
text
));
common
->
writing_app
=
text
;
break
;
}
case
GST_MATROSKA_ID_MUXINGAPP
:{
gchar
*
text
;
if
((
ret
=
gst_ebml_read_utf8
(
ebml
,
&
id
,
&
text
))
!=
GST_FLOW_OK
)
break
;
GST_DEBUG_OBJECT
(
common
,
"MuxingApp: %s"
,
GST_STR_NULL
(
text
));
common
->
muxing_app
=
text
;
break
;
}