mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-15 20:44:16 +00:00
Merge branch 'master' into 0.11
Conflicts: ext/ogg/gstoggmux.c gst/playback/gstplaysink.c
This commit is contained in:
commit
ba41bb5ca7
8 changed files with 141 additions and 83 deletions
|
@ -30,7 +30,7 @@ The granulepos in theora is an encoding of the frame number of the last
|
|||
key frame ("i frame"), and the number of frames since the last key frame
|
||||
("p frame"). The granulepos is constructed as the sum of the first number,
|
||||
shifted to the left for granuleshift bits, and the second number:
|
||||
granulepos = pframe << granuleshift + iframe
|
||||
granulepos = (pframe << granuleshift) + iframe
|
||||
|
||||
(This means that given a framenumber or a timestamp, one cannot generate
|
||||
the one and only granulepos for that page; several granulepos possibilities
|
||||
|
|
|
@ -115,7 +115,7 @@ static const GstQueryType *gst_ogg_pad_query_types (GstPad * pad);
|
|||
static gboolean gst_ogg_pad_src_query (GstPad * pad, GstQuery * query);
|
||||
static gboolean gst_ogg_pad_event (GstPad * pad, GstEvent * event);
|
||||
static GstOggPad *gst_ogg_chain_get_stream (GstOggChain * chain,
|
||||
glong serialno);
|
||||
guint32 serialno);
|
||||
|
||||
static GstFlowReturn gst_ogg_demux_combine_flows (GstOggDemux * ogg,
|
||||
GstOggPad * pad, GstFlowReturn ret);
|
||||
|
@ -419,8 +419,8 @@ gst_ogg_demux_queue_data (GstOggPad * pad, ogg_packet * packet)
|
|||
GstOggDemux *ogg = pad->ogg;
|
||||
#endif
|
||||
|
||||
GST_DEBUG_OBJECT (ogg, "%p queueing data serial %08lx", pad,
|
||||
pad->map.serialno);
|
||||
GST_DEBUG_OBJECT (ogg, "%p queueing data serial %08" G_GINT32_MODIFIER "x",
|
||||
pad, pad->map.serialno);
|
||||
|
||||
pad->map.queued = g_list_append (pad->map.queued, _ogg_packet_copy (packet));
|
||||
|
||||
|
@ -447,7 +447,8 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
|||
cret = GST_FLOW_OK;
|
||||
|
||||
GST_DEBUG_OBJECT (ogg,
|
||||
"%p streaming to peer serial %08lx", pad, pad->map.serialno);
|
||||
"%p streaming to peer serial %08" G_GINT32_MODIFIER "x", pad,
|
||||
pad->map.serialno);
|
||||
|
||||
if (pad->map.is_ogm) {
|
||||
const guint8 *data;
|
||||
|
@ -697,8 +698,8 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||
|
||||
GstOggDemux *ogg = pad->ogg;
|
||||
|
||||
GST_DEBUG_OBJECT (ogg, "%p submit packet serial %08lx", pad,
|
||||
pad->map.serialno);
|
||||
GST_DEBUG_OBJECT (ogg, "%p submit packet serial %08" G_GINT32_MODIFIER "x",
|
||||
pad, pad->map.serialno);
|
||||
|
||||
if (!pad->have_type) {
|
||||
pad->have_type = gst_ogg_stream_setup_map (&pad->map, packet);
|
||||
|
@ -982,8 +983,8 @@ gst_ogg_pad_stream_out (GstOggPad * pad, gint npackets)
|
|||
could_not_submit:
|
||||
{
|
||||
GST_WARNING_OBJECT (ogg,
|
||||
"could not submit packet for stream %08lx, error: %d",
|
||||
pad->map.serialno, result);
|
||||
"could not submit packet for stream %08" G_GINT32_MODIFIER
|
||||
"x, error: %d", pad->map.serialno, result);
|
||||
gst_ogg_pad_reset (pad);
|
||||
return result;
|
||||
}
|
||||
|
@ -1075,8 +1076,8 @@ done:
|
|||
choked:
|
||||
{
|
||||
GST_WARNING_OBJECT (ogg,
|
||||
"ogg stream choked on page (serial %08lx), resetting stream",
|
||||
pad->map.serialno);
|
||||
"ogg stream choked on page (serial %08" G_GINT32_MODIFIER
|
||||
"x), resetting stream", pad->map.serialno);
|
||||
gst_ogg_pad_reset (pad);
|
||||
/* we continue to recover */
|
||||
return GST_FLOW_OK;
|
||||
|
@ -1149,14 +1150,15 @@ gst_ogg_chain_reset (GstOggChain * chain)
|
|||
}
|
||||
|
||||
static GstOggPad *
|
||||
gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
||||
gst_ogg_chain_new_stream (GstOggChain * chain, guint32 serialno)
|
||||
{
|
||||
GstOggPad *ret;
|
||||
GstTagList *list;
|
||||
gchar *name;
|
||||
|
||||
GST_DEBUG_OBJECT (chain->ogg, "creating new stream %08lx in chain %p",
|
||||
serialno, chain);
|
||||
GST_DEBUG_OBJECT (chain->ogg,
|
||||
"creating new stream %08" G_GINT32_MODIFIER "x in chain %p", serialno,
|
||||
chain);
|
||||
|
||||
ret = g_object_new (GST_TYPE_OGG_PAD, NULL);
|
||||
/* we own this one */
|
||||
|
@ -1172,7 +1174,7 @@ gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
|||
if (ogg_stream_init (&ret->map.stream, serialno) != 0)
|
||||
goto init_failed;
|
||||
|
||||
name = g_strdup_printf ("serial_%08lx", serialno);
|
||||
name = g_strdup_printf ("serial_%08" G_GINT32_MODIFIER "x", serialno);
|
||||
gst_object_set_name (GST_OBJECT (ret), name);
|
||||
g_free (name);
|
||||
|
||||
|
@ -1183,7 +1185,8 @@ gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
|||
gst_tag_list_free (list);
|
||||
|
||||
GST_DEBUG_OBJECT (chain->ogg,
|
||||
"created new ogg src %p for stream with serial %08lx", ret, serialno);
|
||||
"created new ogg src %p for stream with serial %08" G_GINT32_MODIFIER "x",
|
||||
ret, serialno);
|
||||
|
||||
g_array_append_val (chain->streams, ret);
|
||||
gst_pad_set_active (GST_PAD_CAST (ret), TRUE);
|
||||
|
@ -1193,15 +1196,15 @@ gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
|||
/* ERRORS */
|
||||
init_failed:
|
||||
{
|
||||
GST_ERROR ("Could not initialize ogg_stream struct for serial %08lx.",
|
||||
serialno);
|
||||
GST_ERROR ("Could not initialize ogg_stream struct for serial %08"
|
||||
G_GINT32_MODIFIER "x.", serialno);
|
||||
gst_object_unref (ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GstOggPad *
|
||||
gst_ogg_chain_get_stream (GstOggChain * chain, glong serialno)
|
||||
gst_ogg_chain_get_stream (GstOggChain * chain, guint32 serialno)
|
||||
{
|
||||
gint i;
|
||||
|
||||
|
@ -1215,7 +1218,7 @@ gst_ogg_chain_get_stream (GstOggChain * chain, glong serialno)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_ogg_chain_has_stream (GstOggChain * chain, glong serialno)
|
||||
gst_ogg_chain_has_stream (GstOggChain * chain, guint32 serialno)
|
||||
{
|
||||
return gst_ogg_chain_get_stream (chain, serialno) != NULL;
|
||||
}
|
||||
|
@ -2162,7 +2165,8 @@ gst_ogg_demux_do_seek (GstOggDemux * ogg, GstSegment * segment,
|
|||
/* get time of the keyframe */
|
||||
keyframe_time =
|
||||
gst_ogg_stream_granule_to_time (&pad->map, pad->keyframe_granule);
|
||||
GST_LOG_OBJECT (ogg, "stream %08lx granule time %" GST_TIME_FORMAT,
|
||||
GST_LOG_OBJECT (ogg,
|
||||
"stream %08" G_GINT32_MODIFIER "x granule time %" GST_TIME_FORMAT,
|
||||
pad->map.serialno, GST_TIME_ARGS (keyframe_time));
|
||||
|
||||
/* collect smallest value */
|
||||
|
@ -2566,7 +2570,7 @@ gst_ogg_demux_bisect_forward_serialno (GstOggDemux * ogg,
|
|||
if (ret == GST_FLOW_UNEXPECTED) {
|
||||
endsearched = bisect;
|
||||
} else if (ret == GST_FLOW_OK) {
|
||||
glong serial = ogg_page_serialno (&og);
|
||||
guint32 serial = ogg_page_serialno (&og);
|
||||
|
||||
if (!gst_ogg_chain_has_stream (chain, serial)) {
|
||||
endsearched = bisect;
|
||||
|
@ -2635,7 +2639,7 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain)
|
|||
* the decoders, send data to the decoders. */
|
||||
while (TRUE) {
|
||||
GstOggPad *pad;
|
||||
glong serial;
|
||||
guint32 serial;
|
||||
|
||||
ret = gst_ogg_demux_get_next_page (ogg, &op, -1, NULL);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
|
@ -2658,7 +2662,8 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain)
|
|||
|
||||
serial = ogg_page_serialno (&op);
|
||||
if (gst_ogg_chain_get_stream (chain, serial) != NULL) {
|
||||
GST_WARNING_OBJECT (ogg, "found serial %08lx BOS page twice, ignoring",
|
||||
GST_WARNING_OBJECT (ogg,
|
||||
"found serial %08" G_GINT32_MODIFIER "x BOS page twice, ignoring",
|
||||
serial);
|
||||
continue;
|
||||
}
|
||||
|
@ -2699,7 +2704,7 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain)
|
|||
|
||||
done = FALSE;
|
||||
while (!done) {
|
||||
glong serial;
|
||||
guint32 serial;
|
||||
gboolean known_serial = FALSE;
|
||||
GstFlowReturn ret;
|
||||
|
||||
|
@ -2708,7 +2713,8 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain)
|
|||
for (i = 0; i < chain->streams->len; i++) {
|
||||
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||
|
||||
GST_LOG_OBJECT (ogg, "serial %08lx time %" GST_TIME_FORMAT,
|
||||
GST_LOG_OBJECT (ogg,
|
||||
"serial %08" G_GINT32_MODIFIER "x time %" GST_TIME_FORMAT,
|
||||
pad->map.serialno, GST_TIME_ARGS (pad->start_time));
|
||||
|
||||
if (pad->map.serialno == serial) {
|
||||
|
@ -2732,14 +2738,15 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain)
|
|||
if (!pad->map.is_sparse)
|
||||
done &= (pad->start_time != GST_CLOCK_TIME_NONE);
|
||||
|
||||
GST_LOG_OBJECT (ogg, "done %08lx now %d", pad->map.serialno, done);
|
||||
GST_LOG_OBJECT (ogg, "done %08" G_GINT32_MODIFIER "x now %d",
|
||||
pad->map.serialno, done);
|
||||
}
|
||||
|
||||
/* we read a page not belonging to the current chain: seek back to the
|
||||
* beginning of the chain
|
||||
*/
|
||||
if (!known_serial) {
|
||||
GST_LOG_OBJECT (ogg, "unknown serial %08lx", serial);
|
||||
GST_LOG_OBJECT (ogg, "unknown serial %08" G_GINT32_MODIFIER "x", serial);
|
||||
gst_ogg_demux_seek (ogg, offset);
|
||||
break;
|
||||
}
|
||||
|
@ -2836,7 +2843,7 @@ gst_ogg_demux_read_end_chain (GstOggDemux * ogg, GstOggChain * chain)
|
|||
/* find a pad with a given serial number
|
||||
*/
|
||||
static GstOggPad *
|
||||
gst_ogg_demux_find_pad (GstOggDemux * ogg, glong serialno)
|
||||
gst_ogg_demux_find_pad (GstOggDemux * ogg, guint32 serialno)
|
||||
{
|
||||
GstOggPad *pad;
|
||||
gint i;
|
||||
|
@ -2868,7 +2875,7 @@ gst_ogg_demux_find_pad (GstOggDemux * ogg, glong serialno)
|
|||
/* find a chain with a given serial number
|
||||
*/
|
||||
static GstOggChain *
|
||||
gst_ogg_demux_find_chain (GstOggDemux * ogg, glong serialno)
|
||||
gst_ogg_demux_find_chain (GstOggDemux * ogg, guint32 serialno)
|
||||
{
|
||||
GstOggPad *pad;
|
||||
|
||||
|
@ -2936,7 +2943,7 @@ gst_ogg_demux_find_chains (GstOggDemux * ogg)
|
|||
ogg_page og;
|
||||
GstPad *peer;
|
||||
gboolean res;
|
||||
gulong serialno;
|
||||
guint32 serialno;
|
||||
GstOggChain *chain;
|
||||
GstFlowReturn ret;
|
||||
|
||||
|
@ -3024,16 +3031,16 @@ gst_ogg_demux_handle_page (GstOggDemux * ogg, ogg_page * page)
|
|||
{
|
||||
GstOggPad *pad;
|
||||
gint64 granule;
|
||||
glong serialno;
|
||||
guint32 serialno;
|
||||
GstFlowReturn result = GST_FLOW_OK;
|
||||
|
||||
serialno = ogg_page_serialno (page);
|
||||
granule = ogg_page_granulepos (page);
|
||||
|
||||
GST_LOG_OBJECT (ogg,
|
||||
"processing ogg page (serial %08lx, pageno %ld, granulepos %"
|
||||
G_GINT64_FORMAT ", bos %d)",
|
||||
serialno, ogg_page_pageno (page), granule, ogg_page_bos (page));
|
||||
"processing ogg page (serial %08" G_GINT32_MODIFIER
|
||||
"x, pageno %ld, granulepos %" G_GINT64_FORMAT ", bos %d)", serialno,
|
||||
ogg_page_pageno (page), granule, ogg_page_bos (page));
|
||||
|
||||
if (ogg_page_bos (page)) {
|
||||
GstOggChain *chain;
|
||||
|
@ -3104,7 +3111,9 @@ gst_ogg_demux_handle_page (GstOggDemux * ogg, ogg_page * page)
|
|||
/* no pad. This means an ogg page without bos has been seen for this
|
||||
* serialno. we just ignore it but post a warning... */
|
||||
GST_ELEMENT_WARNING (ogg, STREAM, DECODE,
|
||||
(NULL), ("unknown ogg pad for serial %08lx detected", serialno));
|
||||
(NULL),
|
||||
("unknown ogg pad for serial %08" G_GINT32_MODIFIER "x detected",
|
||||
serialno));
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
return result;
|
||||
|
@ -3113,7 +3122,9 @@ gst_ogg_demux_handle_page (GstOggDemux * ogg, ogg_page * page)
|
|||
unknown_chain:
|
||||
{
|
||||
GST_ELEMENT_ERROR (ogg, STREAM, DECODE,
|
||||
(NULL), ("unknown ogg chain for serial %08lx detected", serialno));
|
||||
(NULL),
|
||||
("unknown ogg chain for serial %08" G_GINT32_MODIFIER "x detected",
|
||||
serialno));
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -3675,7 +3686,8 @@ gst_ogg_print (GstOggDemux * ogg)
|
|||
for (j = 0; j < chain->streams->len; j++) {
|
||||
GstOggPad *stream = g_array_index (chain->streams, GstOggPad *, j);
|
||||
|
||||
GST_INFO_OBJECT (ogg, " stream %08lx:", stream->map.serialno);
|
||||
GST_INFO_OBJECT (ogg, " stream %08" G_GINT32_MODIFIER "x:",
|
||||
stream->map.serialno);
|
||||
GST_INFO_OBJECT (ogg, " start time: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (stream->start_time));
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ gst_ogg_mux_request_new_pad (GstElement * element,
|
|||
goto wrong_template;
|
||||
|
||||
{
|
||||
gint serial;
|
||||
guint32 serial;
|
||||
gchar *name;
|
||||
|
||||
if (req_name == NULL || strlen (req_name) < 6) {
|
||||
|
@ -374,7 +374,15 @@ gst_ogg_mux_request_new_pad (GstElement * element,
|
|||
serial = gst_ogg_mux_generate_serialno (ogg_mux);
|
||||
} else {
|
||||
/* parse serial number from requested padname */
|
||||
serial = atoi (&req_name[5]);
|
||||
unsigned long long_serial;
|
||||
char *endptr = NULL;
|
||||
long_serial = strtoul (&req_name[5], &endptr, 10);
|
||||
if ((endptr && *endptr) || (long_serial & ~0xffffffff)) {
|
||||
GST_WARNING_OBJECT (ogg_mux, "Invalid serial number specification: %s",
|
||||
req_name + 5);
|
||||
return NULL;
|
||||
}
|
||||
serial = (guint32) long_serial;
|
||||
}
|
||||
/* create new pad with the name */
|
||||
GST_DEBUG_OBJECT (ogg_mux, "Creating new pad for serial %d", serial);
|
||||
|
@ -1014,13 +1022,9 @@ gst_ogg_mux_get_headers (GstOggPadData * pad)
|
|||
GST_LOG_OBJECT (thepad, "streamheader is not fixed list");
|
||||
}
|
||||
|
||||
/* Start a new page for every CMML buffer */
|
||||
if (gst_structure_has_name (structure, "text/x-cmml"))
|
||||
pad->always_flush_page = TRUE;
|
||||
} else if (gst_structure_has_name (structure, "video/x-dirac")) {
|
||||
res = g_list_append (res, pad->buffer);
|
||||
pad->buffer = NULL;
|
||||
pad->always_flush_page = TRUE;
|
||||
} else {
|
||||
GST_LOG_OBJECT (thepad, "caps don't have streamheader");
|
||||
}
|
||||
|
@ -1070,6 +1074,21 @@ gst_ogg_mux_set_header_on_caps (GstCaps * caps, GList * buffers)
|
|||
return caps;
|
||||
}
|
||||
|
||||
static void
|
||||
create_header_packet (ogg_packet * packet, GstBuffer * buf, GstOggPadData * pad)
|
||||
{
|
||||
gsize size;
|
||||
|
||||
packet->packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||
packet->bytes = size;
|
||||
packet->granulepos = 0;
|
||||
/* mark BOS and packet number */
|
||||
packet->b_o_s = (pad->packetno == 0);
|
||||
packet->packetno = pad->packetno++;
|
||||
/* mark EOS */
|
||||
packet->e_o_s = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each pad we need to write out one (small) header in one
|
||||
* page that allows decoders to identify the type of the stream.
|
||||
|
@ -1151,16 +1170,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
|
|||
}
|
||||
|
||||
/* create a packet from the buffer */
|
||||
packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||
packet.bytes = size;
|
||||
packet.granulepos = GST_BUFFER_OFFSET_END (buf);
|
||||
if (packet.granulepos == -1)
|
||||
packet.granulepos = 0;
|
||||
/* mark BOS and packet number */
|
||||
packet.b_o_s = (pad->packetno == 0);
|
||||
packet.packetno = pad->packetno++;
|
||||
/* mark EOS */
|
||||
packet.e_o_s = 0;
|
||||
create_header_packet (&packet, buf, pad);
|
||||
|
||||
/* swap the packet in */
|
||||
ogg_stream_packetin (&pad->map.stream, &packet);
|
||||
|
@ -1177,25 +1187,20 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
|
|||
GST_LOG_OBJECT (mux, "swapped out page with mime type %s",
|
||||
gst_structure_get_name (structure));
|
||||
|
||||
/* quick hack: put Theora, VP8 and Dirac video pages at the front.
|
||||
/* quick hack: put video pages at the front.
|
||||
* Ideally, we would have a settable enum for which Ogg
|
||||
* profile we work with, and order based on that.
|
||||
* (FIXME: if there is more than one video stream, shouldn't we only put
|
||||
* one's BOS into the first page, followed by an audio stream's BOS, and
|
||||
* only then followed by the remaining video and audio streams?) */
|
||||
if (gst_structure_has_name (structure, "video/x-theora")) {
|
||||
GST_DEBUG_OBJECT (thepad, "putting %s page at the front", "Theora");
|
||||
hbufs = g_list_prepend (hbufs, hbuf);
|
||||
} else if (gst_structure_has_name (structure, "video/x-dirac")) {
|
||||
GST_DEBUG_OBJECT (thepad, "putting %s page at the front", "Dirac");
|
||||
hbufs = g_list_prepend (hbufs, hbuf);
|
||||
pad->always_flush_page = TRUE;
|
||||
} else if (gst_structure_has_name (structure, "video/x-vp8")) {
|
||||
GST_DEBUG_OBJECT (thepad, "putting %s page at the front", "VP8");
|
||||
if (pad->map.is_video) {
|
||||
GST_DEBUG_OBJECT (thepad, "putting %s page at the front",
|
||||
gst_structure_get_name (structure));
|
||||
hbufs = g_list_prepend (hbufs, hbuf);
|
||||
} else {
|
||||
hbufs = g_list_append (hbufs, hbuf);
|
||||
}
|
||||
|
||||
gst_caps_unref (caps);
|
||||
}
|
||||
|
||||
|
@ -1223,16 +1228,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
|
|||
hwalk = hwalk->next;
|
||||
|
||||
/* create a packet from the buffer */
|
||||
packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||
packet.bytes = size;
|
||||
packet.granulepos = GST_BUFFER_OFFSET_END (buf);
|
||||
if (packet.granulepos == -1)
|
||||
packet.granulepos = 0;
|
||||
/* mark BOS and packet number */
|
||||
packet.b_o_s = (pad->packetno == 0);
|
||||
packet.packetno = pad->packetno++;
|
||||
/* mark EOS */
|
||||
packet.e_o_s = 0;
|
||||
create_header_packet (&packet, buf, pad);
|
||||
|
||||
/* swap the packet in */
|
||||
ogg_stream_packetin (&pad->map.stream, &packet);
|
||||
|
@ -1453,7 +1449,8 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
|
|||
tmpbuf = NULL;
|
||||
|
||||
/* we flush when we see a new keyframe */
|
||||
force_flush = (pad->prev_delta && !delta_unit) || pad->always_flush_page;
|
||||
force_flush = (pad->prev_delta && !delta_unit)
|
||||
|| pad->map.always_flush_page;
|
||||
if (duration != -1) {
|
||||
pad->duration += duration;
|
||||
/* if page duration exceeds max, flush page */
|
||||
|
|
|
@ -83,8 +83,6 @@ typedef struct
|
|||
gint64 keyframe_granule; /* granule of last preceding keyframe */
|
||||
|
||||
GstPadEventFunction collect_event;
|
||||
|
||||
gboolean always_flush_page;
|
||||
}
|
||||
GstOggPadData;
|
||||
|
||||
|
|
|
@ -225,6 +225,19 @@ gst_ogg_stream_extract_tags (GstOggStream * pad, ogg_packet * packet)
|
|||
mappers[pad->map].extract_tags_func (pad, packet);
|
||||
}
|
||||
|
||||
const char *
|
||||
gst_ogg_stream_get_media_type (GstOggStream * pad)
|
||||
{
|
||||
const GstCaps *caps = pad->caps;
|
||||
const GstStructure *structure;
|
||||
if (!caps)
|
||||
return NULL;
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
if (!structure)
|
||||
return NULL;
|
||||
return gst_structure_get_name (structure);
|
||||
}
|
||||
|
||||
/* some generic functions */
|
||||
|
||||
static gboolean
|
||||
|
@ -467,6 +480,7 @@ setup_dirac_mapper (GstOggStream * pad, ogg_packet * packet)
|
|||
}
|
||||
|
||||
pad->is_video = TRUE;
|
||||
pad->always_flush_page = TRUE;
|
||||
pad->granulerate_n = header.frame_rate_numerator * 2;
|
||||
pad->granulerate_d = header.frame_rate_denominator;
|
||||
pad->granuleshift = 22;
|
||||
|
@ -696,6 +710,7 @@ setup_vorbis_mapper (GstOggStream * pad, ogg_packet * packet)
|
|||
pad->granulerate_n = GST_READ_UINT32_LE (data);
|
||||
pad->granulerate_d = 1;
|
||||
pad->granuleshift = 0;
|
||||
pad->preroll = 2;
|
||||
pad->last_size = 0;
|
||||
GST_LOG ("sample rate: %d", pad->granulerate_n);
|
||||
|
||||
|
@ -1661,6 +1676,7 @@ setup_cmml_mapper (GstOggStream * pad, ogg_packet * packet)
|
|||
GST_DEBUG ("blocksize1: %u", 1 << (data[0] & 0x0F));
|
||||
|
||||
pad->caps = gst_caps_new_simple ("text/x-cmml", NULL);
|
||||
pad->always_flush_page = TRUE;
|
||||
pad->is_sparse = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -1722,6 +1738,7 @@ setup_kate_mapper (GstOggStream * pad, ogg_packet * packet)
|
|||
}
|
||||
|
||||
pad->is_sparse = TRUE;
|
||||
pad->always_flush_page = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ struct _GstOggStream
|
|||
{
|
||||
ogg_stream_state stream;
|
||||
|
||||
glong serialno;
|
||||
guint32 serialno;
|
||||
GList *headers;
|
||||
gboolean have_headers;
|
||||
GList *queued;
|
||||
|
@ -73,6 +73,8 @@ struct _GstOggStream
|
|||
GstCaps *caps;
|
||||
|
||||
gboolean is_video;
|
||||
gboolean always_flush_page;
|
||||
|
||||
/* vorbis stuff */
|
||||
int nln_increments[4];
|
||||
int nsn_increment;
|
||||
|
@ -123,6 +125,7 @@ gboolean gst_ogg_stream_granulepos_is_key_frame (GstOggStream *pad,
|
|||
gboolean gst_ogg_stream_packet_is_header (GstOggStream *pad, ogg_packet *packet);
|
||||
gint64 gst_ogg_stream_get_packet_duration (GstOggStream * pad, ogg_packet *packet);
|
||||
void gst_ogg_stream_extract_tags (GstOggStream * pad, ogg_packet * packet);
|
||||
const char *gst_ogg_stream_get_media_type (GstOggStream * pad);
|
||||
|
||||
gboolean gst_ogg_map_parse_fisbone (GstOggStream * pad, const guint8 * data, guint size,
|
||||
guint32 * serialno, GstOggSkeleton *type);
|
||||
|
|
|
@ -924,6 +924,7 @@ speex_resampler_init (spx_uint32_t nb_channels, spx_uint32_t in_rate,
|
|||
out_rate, quality, err);
|
||||
}
|
||||
|
||||
#if defined HAVE_ORC && !defined DISABLE_ORC
|
||||
static void
|
||||
check_insn_set (SpeexResamplerState * st, const char *name)
|
||||
{
|
||||
|
@ -934,6 +935,7 @@ check_insn_set (SpeexResamplerState * st, const char *name)
|
|||
if (!strcmp (name, "sse2"))
|
||||
st->use_sse = st->use_sse2 = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
EXPORT SpeexResamplerState *
|
||||
speex_resampler_init_frac (spx_uint32_t nb_channels, spx_uint32_t ratio_num,
|
||||
|
|
|
@ -127,6 +127,19 @@ typedef struct
|
|||
g_static_rec_mutex_unlock (GST_PLAY_SINK_GET_LOCK (playsink)); \
|
||||
} G_STMT_END
|
||||
|
||||
#define PENDING_FLAG_SET(playsink, flagtype) \
|
||||
((playsink->pending_blocked_pads) |= (1 << flagtype))
|
||||
#define PENDING_FLAG_UNSET(playsink, flagtype) \
|
||||
((playsink->pending_blocked_pads) &= ~(1 << flagtype))
|
||||
#define PENDING_FLAG_IS_SET(playsink, flagtype) \
|
||||
((playsink->pending_blocked_pads) & (1 << flagtype))
|
||||
#define PENDING_VIDEO_BLOCK(playsink) \
|
||||
((playsink->pending_blocked_pads) & (1 << GST_PLAY_SINK_TYPE_VIDEO_RAW | 1 << GST_PLAY_SINK_TYPE_VIDEO))
|
||||
#define PENDING_AUDIO_BLOCK(playsink) \
|
||||
((playsink->pending_blocked_pads) & (1 << GST_PLAY_SINK_TYPE_AUDIO_RAW | 1 << GST_PLAY_SINK_TYPE_AUDIO))
|
||||
#define PENDING_TEXT_BLOCK(playsink) \
|
||||
PENDING_FLAG_IS_SET(playsink, GST_PLAY_SINK_TYPE_TEXT)
|
||||
|
||||
struct _GstPlaySink
|
||||
{
|
||||
GstBin bin;
|
||||
|
@ -173,6 +186,8 @@ struct _GstPlaySink
|
|||
GstPad *text_sinkpad_stream_synchronizer;
|
||||
gulong text_block_id;
|
||||
|
||||
guint32 pending_blocked_pads;
|
||||
|
||||
/* properties */
|
||||
GstElement *audio_sink;
|
||||
GstElement *video_sink;
|
||||
|
@ -2880,6 +2895,8 @@ video_set_blocked (GstPlaySink * playsink, gboolean blocked)
|
|||
gst_object_ref (playsink), (GDestroyNotify) gst_object_unref);
|
||||
} else if (!blocked && playsink->video_block_id) {
|
||||
gst_pad_remove_probe (opad, playsink->video_block_id);
|
||||
PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_VIDEO_RAW);
|
||||
PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_VIDEO);
|
||||
playsink->video_block_id = 0;
|
||||
playsink->video_pad_blocked = FALSE;
|
||||
}
|
||||
|
@ -2900,6 +2917,8 @@ audio_set_blocked (GstPlaySink * playsink, gboolean blocked)
|
|||
gst_object_ref (playsink), (GDestroyNotify) gst_object_unref);
|
||||
} else if (!blocked && playsink->audio_block_id) {
|
||||
gst_pad_remove_probe (opad, playsink->audio_block_id);
|
||||
PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_AUDIO_RAW);
|
||||
PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_AUDIO);
|
||||
playsink->audio_block_id = 0;
|
||||
playsink->audio_pad_blocked = FALSE;
|
||||
}
|
||||
|
@ -2920,6 +2939,7 @@ text_set_blocked (GstPlaySink * playsink, gboolean blocked)
|
|||
gst_object_ref (playsink), (GDestroyNotify) gst_object_unref);
|
||||
} else if (!blocked && playsink->text_block_id) {
|
||||
gst_pad_remove_probe (opad, playsink->text_block_id);
|
||||
PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_TEXT);
|
||||
playsink->text_block_id = 0;
|
||||
playsink->text_pad_blocked = FALSE;
|
||||
}
|
||||
|
@ -2948,9 +2968,17 @@ sinkpad_blocked_cb (GstPad * blockedpad, GstProbeType type, gpointer type_data,
|
|||
GST_DEBUG_OBJECT (pad, "Text pad blocked");
|
||||
}
|
||||
|
||||
if ((!playsink->video_pad || playsink->video_pad_blocked) &&
|
||||
(!playsink->audio_pad || playsink->audio_pad_blocked) &&
|
||||
(!playsink->text_pad || playsink->text_pad_blocked)) {
|
||||
/* We reconfigure when for ALL streams:
|
||||
* * there isn't a pad
|
||||
* * OR the pad is blocked
|
||||
* * OR there are no pending blocks on that pad
|
||||
*/
|
||||
|
||||
if ((!playsink->video_pad || playsink->video_pad_blocked
|
||||
|| !PENDING_VIDEO_BLOCK (playsink)) && (!playsink->audio_pad
|
||||
|| playsink->audio_pad_blocked || !PENDING_AUDIO_BLOCK (playsink))
|
||||
&& (!playsink->text_pad || playsink->text_pad_blocked
|
||||
|| !PENDING_TEXT_BLOCK (playsink))) {
|
||||
GST_DEBUG_OBJECT (playsink, "All pads blocked -- reconfiguring");
|
||||
|
||||
if (playsink->video_pad) {
|
||||
|
@ -2992,14 +3020,14 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink)
|
|||
|
||||
if (pad == playsink->audio_pad) {
|
||||
raw = is_raw_pad (pad);
|
||||
reconfigure = (!!playsink->audio_pad_raw != !!raw)
|
||||
reconfigure = (! !playsink->audio_pad_raw != ! !raw)
|
||||
&& playsink->audiochain;
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"Audio caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,
|
||||
reconfigure, caps);
|
||||
} else if (pad == playsink->video_pad) {
|
||||
raw = is_raw_pad (pad);
|
||||
reconfigure = (!!playsink->video_pad_raw != !!raw)
|
||||
reconfigure = (! !playsink->video_pad_raw != ! !raw)
|
||||
&& playsink->videochain;
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"Video caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,
|
||||
|
@ -3131,6 +3159,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
|
|||
*block_id =
|
||||
gst_pad_add_probe (blockpad, GST_PROBE_TYPE_BLOCK, sinkpad_blocked_cb,
|
||||
gst_object_ref (playsink), (GDestroyNotify) gst_object_unref);
|
||||
PENDING_FLAG_SET (playsink, type);
|
||||
gst_object_unref (blockpad);
|
||||
}
|
||||
if (!activate)
|
||||
|
|
Loading…
Reference in a new issue