void test_no_lock() { GstTask *t; gboolean ret; //xmlfile = "test_no_lock"; std_log(LOG_FILENAME_LINE, "Test Started test_no_lock"); t = gst_task_create (task_func, NULL); fail_if (t == NULL); TEST_ASSERT_FAIL /* stop should be possible without lock */ gst_task_stop (t); /* pause should give a warning */ ASSERT_WARNING (ret = gst_task_pause (t)); //b failing fail_unless (ret == FALSE); TEST_ASSERT_FAIL /* start should give a warning */ ASSERT_WARNING (ret = gst_task_start (t)); fail_unless (ret == FALSE); TEST_ASSERT_FAIL /* stop should be possible without lock */ gst_task_stop (t); gst_object_unref (t); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
void test_lock_start() { GstTask *t; gboolean ret; //xmlfile = "test_lock_start"; std_log(LOG_FILENAME_LINE, "Test Started test_lock_start"); t = gst_task_create (task_func, NULL); fail_if (t == NULL); TEST_ASSERT_FAIL gst_task_set_lock (t, &task_mutex); task_cond = g_cond_new (); task_lock = g_mutex_new (); g_mutex_lock (task_lock); GST_DEBUG ("starting"); ret = gst_task_start (t); fail_unless (ret == TRUE); TEST_ASSERT_FAIL /* wait for it to spin up */ GST_DEBUG ("waiting"); g_cond_wait (task_cond, task_lock); GST_DEBUG ("done waiting"); g_mutex_unlock (task_lock); /* cannot set mutex now */ ASSERT_WARNING (gst_task_set_lock (t, &task_mutex));//b failing GST_DEBUG ("joining"); ret = gst_task_join (t); fail_unless (ret == TRUE); TEST_ASSERT_FAIL gst_object_unref (t); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
void test_lock() { GstTask *t; gboolean ret; //xmlfile = "test_lock"; std_log(LOG_FILENAME_LINE, "Test Started test_lock"); t = gst_task_create (task_func, NULL); fail_if (t == NULL); TEST_ASSERT_FAIL gst_task_set_lock (t, &task_mutex); GST_DEBUG ("pause"); ret = gst_task_pause (t); fail_unless (ret == TRUE); TEST_ASSERT_FAIL g_usleep (1 * G_USEC_PER_SEC / 2); GST_DEBUG ("joining"); ret = gst_task_join (t); fail_unless (ret == TRUE); TEST_ASSERT_FAIL g_usleep (1 * G_USEC_PER_SEC / 2); gst_object_unref (t); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static void gst_swfdec_init (GstSwfdec * swfdec) { /* create the sink and src pads */ swfdec->sinkpad = gst_pad_new_from_static_template (&sink_template_factory, "sink"); gst_element_add_pad (GST_ELEMENT (swfdec), swfdec->sinkpad); gst_pad_set_chain_function (swfdec->sinkpad, gst_swfdec_chain); gst_pad_set_event_function (swfdec->sinkpad, gst_swfdec_sink_event); swfdec->videopad = gst_pad_new_from_static_template (&video_template_factory, "video_00"); gst_pad_set_query_function (swfdec->videopad, gst_swfdec_src_query); gst_pad_set_getcaps_function (swfdec->videopad, gst_swfdec_video_getcaps); gst_pad_set_setcaps_function (swfdec->videopad, gst_swfdec_video_link); gst_pad_set_event_function (swfdec->videopad, gst_swfdec_src_event); gst_pad_set_query_type_function (swfdec->videopad, gst_swfdec_get_query_types); gst_element_add_pad (GST_ELEMENT (swfdec), swfdec->videopad); swfdec->audiopad = gst_pad_new_from_static_template (&audio_template_factory, "audio_00"); gst_pad_set_query_function (swfdec->audiopad, gst_swfdec_src_query); gst_pad_set_event_function (swfdec->audiopad, gst_swfdec_src_event); gst_pad_set_query_type_function (swfdec->audiopad, gst_swfdec_get_query_types); gst_element_add_pad (GST_ELEMENT (swfdec), swfdec->audiopad); /* initialize the swfdec decoder state */ swfdec->decoder = swfdec_decoder_new (); g_return_if_fail (swfdec->decoder != NULL); swfdec_decoder_set_colorspace (swfdec->decoder, SWF_COLORSPACE_RGB888); swfdec->frame_rate_n = 0; swfdec->frame_rate_d = 1; swfdec->x = -1; swfdec->y = -1; swfdec->skip_frames = 2; swfdec->skip_index = 0; swfdec->adapter = gst_adapter_new (); swfdec->task = gst_task_create ((GstTaskFunction) gst_swfdec_loop, swfdec); g_static_rec_mutex_init (&swfdec->mutex); gst_task_set_lock (swfdec->task, &swfdec->mutex); }
void test_create() { GstTask *t; //xmlfile = "test_create"; std_log(LOG_FILENAME_LINE, "Test Started test_create"); t = gst_task_create (task_func, NULL); fail_if (t == NULL); TEST_ASSERT_FAIL gst_object_unref (t); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static void gst_hls_demux_init (GstHLSDemux * demux, GstHLSDemuxClass * klass) { /* sink pad */ demux->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink"); gst_pad_set_chain_function (demux->sinkpad, GST_DEBUG_FUNCPTR (gst_hls_demux_chain)); gst_pad_set_event_function (demux->sinkpad, GST_DEBUG_FUNCPTR (gst_hls_demux_sink_event)); gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad); /* demux pad */ demux->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); gst_pad_set_event_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_event)); gst_pad_set_query_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_hls_demux_src_query)); gst_pad_set_element_private (demux->srcpad, demux); gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad); /* fetcher pad */ demux->fetcherpad = gst_pad_new_from_static_template (&fetchertemplate, "sink"); gst_pad_set_chain_function (demux->fetcherpad, GST_DEBUG_FUNCPTR (gst_hls_demux_fetcher_chain)); gst_pad_set_event_function (demux->fetcherpad, GST_DEBUG_FUNCPTR (gst_hls_demux_fetcher_sink_event)); gst_pad_set_element_private (demux->fetcherpad, demux); gst_pad_activate_push (demux->fetcherpad, TRUE); /* Properties */ demux->fragments_cache = DEFAULT_FRAGMENTS_CACHE; demux->bitrate_switch_tol = DEFAULT_BITRATE_SWITCH_TOLERANCE; demux->download = gst_adapter_new (); demux->fetcher_bus = gst_bus_new (); gst_bus_set_sync_handler (demux->fetcher_bus, gst_hls_demux_fetcher_bus_handler, demux); demux->thread_cond = g_cond_new (); demux->thread_lock = g_mutex_new (); demux->fetcher_cond = g_cond_new (); demux->fetcher_lock = g_mutex_new (); demux->queue = g_queue_new (); g_static_rec_mutex_init (&demux->task_lock); demux->task = gst_task_create ((GstTaskFunction) gst_hls_demux_loop, demux); gst_task_set_lock (demux->task, &demux->task_lock); }
void gst_curl_multi_context_ref (GstCurlMultiContext * thiz) { g_mutex_lock (&thiz->mutex); if (thiz->refcount == 0) { /* Set up various in-task properties */ /* set up curl */ thiz->multi_handle = curl_multi_init (); curl_multi_setopt (thiz->multi_handle, CURLMOPT_PIPELINING, 1); #ifdef CURLMOPT_MAX_HOST_CONNECTIONS curl_multi_setopt (thiz->multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1); #endif /* Start the thread */ #if GST_CHECK_VERSION(1,0,0) thiz->task = gst_task_new ( (GstTaskFunction) gst_curl_multi_context_loop, (gpointer) thiz, NULL); #else thiz->task = gst_task_create ( (GstTaskFunction) gst_curl_multi_context_loop, (gpointer) thiz); #endif gst_task_set_lock (thiz->task, &thiz->task_rec_mutex); if (gst_task_start (thiz->task) == FALSE) { /* * This is a pretty critical failure and is not recoverable, so commit * sudoku and run away. */ GST_ERROR ("Couldn't start curl_multi task! Aborting."); abort (); } GST_INFO ("Curl multi loop has been correctly initialised!"); } thiz->refcount++; g_mutex_unlock (&thiz->mutex); }
/** * Tell the GST sink element it is time to prepare to do work * * This is one of the last functions GStreamer will call when the pipeline * is being put together. It is the last place the element has a chance to * allocate resources and in our case startup our background task for network * connectivity. * After this function returns, we are ready to start processing data from the pipeliine. * * We allocate some of the last minute buffers, and setup a connection to the network; * this is used primarily by the background task, but we need access to it for name initialization. * * Next we initialize our fifo queue, and startup the background task. * * Lastly we return to the GST to begin processing information. * * \param bsink -> to the context sink element * \return true if the initialization went well and we are ready to process data, false otherwise */ static gboolean gst_ccnxsink_start (GstBaseSink * bsink) { Gstccnxsink *me; gboolean b_ret = FALSE; me = GST_CCNXSINK (bsink); me->temp = ccn_charbuf_create (); me->lastPublish = ccn_charbuf_create (); GST_DEBUG ("CCNxSink: starting, getting connections"); GST_DEBUG ("CCNxSink: step 1, %s", me->uri); /* setup the connection to ccnx */ setup_ccn (me); GST_DEBUG ("CCNxSink: ccn is setup"); /* setup and start the background task */ eventTask = gst_task_create (ccn_event_thread, me); if (NULL == eventTask) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("creating event thread failed")); return FALSE; } me->fifo_cond = g_cond_new (); me->fifo_lock = g_mutex_new (); gst_task_set_lock (eventTask, &task_mutex); eventCond = g_cond_new (); eventLock = g_mutex_new (); b_ret = gst_task_start (eventTask); if (FALSE == b_ret) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("starting event thread failed")); return FALSE; } GST_DEBUG ("CCNxSink: event thread started"); return TRUE; }
GstAlsaMixer * gst_alsa_mixer_new (const char *device, GstAlsaMixerDirection dir) { GstAlsaMixer *ret = NULL; g_return_val_if_fail (device != NULL, NULL); ret = g_new0 (GstAlsaMixer, 1); if (pipe (ret->pfd) == -1) goto error; ret->rec_mutex = g_new (GStaticRecMutex, 1); g_static_rec_mutex_init (ret->rec_mutex); ret->task_mutex = g_new (GStaticRecMutex, 1); g_static_rec_mutex_init (ret->task_mutex); ret->task = gst_task_create (task_monitor_alsa, ret); gst_task_set_lock (ret->task, ret->task_mutex); ret->device = g_strdup (device); ret->dir = dir; if (!gst_alsa_mixer_open (ret)) goto error; if (gst_task_start (ret->task) == FALSE) { GST_WARNING ("Could not start alsamixer task"); } return ret; /* ERRORS */ error: { gst_alsa_mixer_free (ret); return NULL; } }
static GstStateChangeReturn gst_qt_moov_recover_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret; GstQTMoovRecover *qtmr = GST_QT_MOOV_RECOVER_CAST (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: qtmr->task = gst_task_create (gst_qt_moov_recover_run, qtmr); qtmr->task_mutex = g_new (GStaticRecMutex, 1); g_static_rec_mutex_init (qtmr->task_mutex); gst_task_set_lock (qtmr->task, qtmr->task_mutex); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: gst_task_start (qtmr->task); break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: gst_task_stop (qtmr->task); gst_task_join (qtmr->task); break; case GST_STATE_CHANGE_READY_TO_NULL: g_assert (gst_task_get_state (qtmr->task) == GST_TASK_STOPPED); gst_object_unref (qtmr->task); qtmr->task = NULL; g_static_rec_mutex_free (qtmr->task_mutex); break; default: break; } return ret; }
static void gst_decklink_src_init (GstDecklinkSrc * decklinksrc, GstDecklinkSrcClass * decklinksrc_class) { g_static_rec_mutex_init (&decklinksrc->task_mutex); decklinksrc->task = gst_task_create (gst_decklink_src_task, decklinksrc); gst_task_set_lock (decklinksrc->task, &decklinksrc->task_mutex); decklinksrc->audiosrcpad = gst_pad_new_from_static_template (&gst_decklink_src_audio_src_template, "audiosrc"); gst_pad_set_getcaps_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_getcaps)); gst_pad_set_setcaps_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_setcaps)); gst_pad_set_acceptcaps_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_acceptcaps)); gst_pad_set_fixatecaps_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_fixatecaps)); gst_pad_set_activate_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_activate)); gst_pad_set_activatepush_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_activatepush)); gst_pad_set_activatepull_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_activatepull)); gst_pad_set_link_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_link)); gst_pad_set_getrange_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_getrange)); gst_pad_set_event_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_event)); gst_pad_set_query_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_query)); gst_pad_set_iterate_internal_links_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_iterintlink)); gst_element_add_pad (GST_ELEMENT (decklinksrc), decklinksrc->audiosrcpad); decklinksrc->videosrcpad = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (decklinksrc_class), "videosrc"), "videosrc"); gst_pad_set_getcaps_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_getcaps)); gst_pad_set_setcaps_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_setcaps)); gst_pad_set_acceptcaps_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_acceptcaps)); gst_pad_set_fixatecaps_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_fixatecaps)); gst_pad_set_activate_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_activate)); gst_pad_set_activatepush_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_activatepush)); gst_pad_set_activatepull_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_activatepull)); gst_pad_set_link_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_link)); gst_pad_set_getrange_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_getrange)); gst_pad_set_event_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_event)); gst_pad_set_query_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_query)); gst_pad_set_iterate_internal_links_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_iterintlink)); gst_element_add_pad (GST_ELEMENT (decklinksrc), decklinksrc->videosrcpad); decklinksrc->cond = g_cond_new (); decklinksrc->mutex = g_mutex_new (); decklinksrc->copy_data = TRUE; decklinksrc->mode = GST_DECKLINK_MODE_NTSC; decklinksrc->connection = GST_DECKLINK_CONNECTION_SDI; decklinksrc->audio_connection = GST_DECKLINK_AUDIO_CONNECTION_AUTO; decklinksrc->subdevice = 0; decklinksrc->stop = FALSE; decklinksrc->dropped_frames = 0; decklinksrc->dropped_frames_old = 0; decklinksrc->frame_num = -1; /* -1 so will be 0 after incrementing */ #ifdef _MSC_VER decklinksrc->com_init_lock = g_mutex_new(); decklinksrc->com_deinit_lock = g_mutex_new(); decklinksrc->com_initialized = g_cond_new(); decklinksrc->com_uninitialize = g_cond_new(); decklinksrc->com_uninitialized = g_cond_new(); g_mutex_lock (decklinksrc->com_init_lock); /* create the COM initialization thread */ g_thread_create ((GThreadFunc)gst_decklink_src_com_thread, decklinksrc, FALSE, NULL); /* wait until the COM thread signals that COM has been initialized */ g_cond_wait (decklinksrc->com_initialized, decklinksrc->com_init_lock); g_mutex_unlock (decklinksrc->com_init_lock); #endif /* _MSC_VER */ }
/** * Tell the GST source element it is time to prepare to do work * * This is one of the last functions GStreamer will call when the pipeline * is being put together. It is the last place the element has a chance to * allocate resources and in our case startup our background task for network * connectivity. * After this function returns, we are ready to start processing data from the pipeliine. * * We allocate some of the last minute buffers, and setup a connection to the network; * this is used primarily by the background task, but we need access to it for name initialization. * * Next we initialize our fifo queue, and startup the background task. * * Lastly we return to the GST to begin processing information. * * \param bsrc -> to the context source element * \return true if the initialization went well and we are ready to process data, false otherwise */ static gboolean gst_ccnxsrc_start (GstBaseSrc * bsrc) { Gstccnxsrc *src; CcnxInterestState *istate; struct ccn_charbuf *p_name = NULL; uintmax_t *p_seg = NULL; gint i_ret = 0; gboolean b_ret = FALSE; src = GST_CCNXSRC (bsrc); GST_DEBUG ("starting, getting connections"); /* setup the connection to ccnx */ if ((src->ccn = ccn_create ()) == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("ccn_create failed")); return FALSE; } if (-1 == ccn_connect (src->ccn, ccndHost ())) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("ccn_connect failed to %s", ccndHost ())); return FALSE; } loadKey (src->ccn, &src->sp); /* A closure is what defines what to do when an inbound interest or data arrives */ if ((src->ccn_closure = calloc (1, sizeof (struct ccn_closure))) == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("closure alloc failed")); return FALSE; } /* We setup the closure to keep our context [src] and to call the incoming_content() function */ src->ccn_closure->data = src; src->ccn_closure->p = incoming_content; /* Allocate buffers and construct the name from the uri the user gave us */ GST_INFO ("step 1"); if ((p_name = ccn_charbuf_create ()) == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("p_name alloc failed")); return FALSE; } if ((src->p_name = ccn_charbuf_create ()) == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("src->p_name alloc failed")); return FALSE; } if ((i_ret = ccn_name_from_uri (p_name, src->uri)) < 0) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("name from uri failed for \"%s\"", src->uri)); return FALSE; } /* Find out what the latest one of these is called, and keep it in our context */ ccn_charbuf_append (src->p_name, p_name->buf, p_name->length); i_ret = ccn_resolve_version (src->ccn, src->p_name, CCN_V_HIGHEST, CCN_VERSION_TIMEOUT); GST_INFO ("step 20 - name so far..."); // hDump(src->p_name->buf, src->p_name->length); src->i_seg = 0; if (i_ret == 0) { /* name is versioned, so get the meta data to obtain the length */ p_seg = get_segment (src->ccn, src->p_name, CCN_HEADER_TIMEOUT); if (p_seg != NULL) { src->i_seg = *p_seg; GST_INFO ("step 25 - next seg: %d", src->i_seg); free (p_seg); } } ccn_charbuf_destroy (&p_name); /* Even though the recent segment published is likely to be >> 0, we still need to ask for segment 0 */ /* because it seems to contain valuable stream information. Attempts to skip segment 0 resulted in no */ /* proper rendering of the stream on my screen during testing */ i_ret = request_segment (src, 0); if (i_ret < 0) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("interest sending failed")); return FALSE; } src->post_seg = 0; istate = allocInterestState (src); if (!istate) { // This should not happen, but maybe GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("trouble allocating interest state structure")); return FALSE; } istate->seg = 0; istate->state = OInterest_waiting; /* Now start up the background work which will fetch all the rest of the R/T segments */ eventTask = gst_task_create (ccn_event_thread, src); if (NULL == eventTask) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("creating event thread failed")); return FALSE; } src->fifo_cond = g_cond_new (); src->fifo_lock = g_mutex_new (); gst_task_set_lock (eventTask, &task_mutex); eventCond = g_cond_new (); eventLock = g_mutex_new (); b_ret = gst_task_start (eventTask); if (FALSE == b_ret) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("starting event thread failed")); return FALSE; } GST_DEBUG ("event thread started"); /* Done! */ return TRUE; }
static gboolean gst_ss_demux_sink_event (GstPad * pad, GstEvent * event) { GstSSDemux *demux = GST_SS_DEMUX (gst_pad_get_parent (pad)); GstQuery *query; gboolean ret; gchar *uri; switch (event->type) { case GST_EVENT_EOS: { int i = 0; if (demux->manifest == NULL) { GST_WARNING_OBJECT (demux, "Received EOS without a manifest."); break; } GST_DEBUG_OBJECT (demux, "Got EOS on the sink pad: mainifest file fetched"); query = gst_query_new_uri (); ret = gst_pad_peer_query (demux->sinkpad, query); if (ret) { gst_query_parse_uri (query, &uri); demux->parser = gst_ssm_parse_new (uri); g_free (uri); } else { GST_ERROR_OBJECT (demux, "failed to query URI from upstream"); return FALSE; } gst_query_unref (query); GST_LOG_OBJECT (demux, "data = %p & size = %d", GST_BUFFER_DATA(demux->manifest), GST_BUFFER_SIZE(demux->manifest)); if (!gst_ssm_parse_manifest (demux->parser, (char *)GST_BUFFER_DATA(demux->manifest), GST_BUFFER_SIZE(demux->manifest))) { /* In most cases, this will happen if we set a wrong url in the * source element and we have received the 404 HTML response instead of * the playlist */ GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid playlist."), (NULL)); return FALSE; } for( i = 0; i < SS_STREAM_NUM; i++) { if (gst_ssm_parse_check_stream (demux->parser, i)) { GstSSDemuxStream *stream = g_new0 (GstSSDemuxStream, 1); // Add pad emission of the stream gst_ss_demux_stream_init (demux, stream, i); g_static_rec_mutex_init (&stream->stream_lock); stream->stream_task = gst_task_create ((GstTaskFunction) gst_ss_demux_stream_loop, demux); gst_task_set_lock (stream->stream_task, &stream->stream_lock); demux->streams[i] = stream; g_print ("Starting stream - %d task loop...\n", i); gst_task_start (stream->stream_task); } } gst_event_unref (event); return TRUE; } case GST_EVENT_NEWSEGMENT: /* Swallow newsegments, we'll push our own */ gst_event_unref (event); return TRUE; default: break; } return gst_pad_event_default (pad, event); }