Merge branch 'master' into 0.11

Conflicts:
	ext/ogg/gstoggmux.c
	gst/playback/gstplaysink.c
This commit is contained in:
Wim Taymans 2011-08-18 19:36:50 +02:00
commit ba41bb5ca7
8 changed files with 141 additions and 83 deletions

View file

@ -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

View file

@ -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));
}

View file

@ -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 */

View file

@ -83,8 +83,6 @@ typedef struct
gint64 keyframe_granule; /* granule of last preceding keyframe */
GstPadEventFunction collect_event;
gboolean always_flush_page;
}
GstOggPadData;

View file

@ -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;
}

View file

@ -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);

View file

@ -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,

View file

@ -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)