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; }
void gst_decklink_src_finalize (GObject * object) { GstDecklinkSrc *decklinksrc; g_return_if_fail (GST_IS_DECKLINK_SRC (object)); decklinksrc = GST_DECKLINK_SRC (object); /* clean up object here */ g_cond_free (decklinksrc->cond); g_mutex_free (decklinksrc->mutex); gst_task_set_lock (decklinksrc->task, NULL); g_object_unref (decklinksrc->task); if (decklinksrc->audio_caps) { gst_caps_unref (decklinksrc->audio_caps); } if (decklinksrc->video_caps) { gst_caps_unref (decklinksrc->video_caps); } #ifdef _MSC_VER /* signal the COM thread that it should uninitialize COM */ if (decklinksrc->comInitialized) { g_mutex_lock (decklinksrc->com_deinit_lock); g_cond_signal (decklinksrc->com_uninitialize); g_cond_wait (decklinksrc->com_uninitialized, decklinksrc->com_deinit_lock); g_mutex_unlock (decklinksrc->com_deinit_lock); } g_mutex_free (decklinksrc->com_init_lock); g_mutex_free (decklinksrc->com_deinit_lock); g_cond_free (decklinksrc->com_initialized); g_cond_free (decklinksrc->com_uninitialize); g_cond_free (decklinksrc->com_uninitialized); #endif /* _MSC_VER */ G_OBJECT_CLASS (parent_class)->finalize (object); }
void test_join() { GstTask *t; gboolean ret; //xmlfile = "test_join"; std_log(LOG_FILENAME_LINE, "Test Started test_join"); t = gst_task_create (task_func2, &t); 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); 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); }
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 */ }
static void dvb_base_bin_init (DvbBaseBin * dvbbasebin) { DvbBaseBinStream *stream; GstPad *ghost, *pad; int i; dvbbasebin->dvbsrc = gst_element_factory_make ("dvbsrc", NULL); dvbbasebin->buffer_queue = gst_element_factory_make ("queue", NULL); dvbbasebin->tsparse = gst_element_factory_make ("tsparse", NULL); g_object_set (dvbbasebin->buffer_queue, "max-size-buffers", 0, "max-size-bytes", 0, "max-size-time", (guint64) 0, NULL); gst_bin_add_many (GST_BIN (dvbbasebin), dvbbasebin->dvbsrc, dvbbasebin->buffer_queue, dvbbasebin->tsparse, NULL); gst_element_link_many (dvbbasebin->dvbsrc, dvbbasebin->buffer_queue, dvbbasebin->tsparse, NULL); /* Proxy dvbsrc signals */ g_signal_connect (dvbbasebin->dvbsrc, "tuning-start", G_CALLBACK (tuning_start_signal_cb), dvbbasebin); g_signal_connect (dvbbasebin->dvbsrc, "tuning-done", G_CALLBACK (tuning_done_signal_cb), dvbbasebin); g_signal_connect (dvbbasebin->dvbsrc, "tuning-fail", G_CALLBACK (tuning_fail_signal_cb), dvbbasebin); /* Expose tsparse source pad */ if (dvbbasebin->tsparse != NULL) { pad = gst_element_get_static_pad (dvbbasebin->tsparse, "src"); ghost = gst_ghost_pad_new ("src", pad); } else { ghost = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC); } gst_element_add_pad (GST_ELEMENT (dvbbasebin), ghost); dvbbasebin->programs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, dvb_base_bin_program_destroy); dvbbasebin->streams = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); dvbbasebin->pmtlist = NULL; dvbbasebin->pmtlist_changed = FALSE; dvbbasebin->disposed = FALSE; dvb_base_bin_reset (dvbbasebin); /* add PAT, CAT, NIT, SDT, EIT, TDT to pids filter for dvbsrc */ i = 0; while (initial_pids[i] >= 0) { stream = dvb_base_bin_add_stream (dvbbasebin, (guint16) initial_pids[i]); dvb_base_bin_ref_stream (stream); i++; } dvb_base_bin_rebuild_filter (dvbbasebin); g_rec_mutex_init (&dvbbasebin->lock); dvbbasebin->task = gst_task_new ((GstTaskFunction) dvb_base_bin_task, dvbbasebin, NULL); gst_task_set_lock (dvbbasebin->task, &dvbbasebin->lock); dvbbasebin->poll = gst_poll_new_timer (); }
static void gst_decklink_src_init (GstDecklinkSrc * decklinksrc) { GstDecklinkSrcClass *decklinksrc_class; decklinksrc_class = GST_DECKLINK_SRC_GET_CLASS (decklinksrc); g_rec_mutex_init (&decklinksrc->task_mutex); decklinksrc->task = gst_task_new (gst_decklink_src_task, decklinksrc, NULL); 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_query_function (decklinksrc->audiosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_audio_src_query)); 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_query_function (decklinksrc->videosrcpad, GST_DEBUG_FUNCPTR (gst_decklink_src_video_src_query)); gst_element_add_pad (GST_ELEMENT (decklinksrc), decklinksrc->videosrcpad); g_cond_init (&decklinksrc->cond); g_mutex_init (&decklinksrc->mutex); /* FIXME: turn this into a property? */ 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->device = 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 g_mutex_init (&decklinksrc->com_init_lock); g_mutex_init (&decklinksrc->com_deinit_lock); g_cond_init (&decklinksrc->com_initialized); g_cond_init (&decklinksrc->com_uninitialize); g_cond_init (&decklinksrc->com_uninitialized); 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 */ GST_DEBUG_CATEGORY_INIT (gst_decklink_src_debug_category, "decklinksrc", 0, "debug category for decklinksrc element"); }
/** * 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); }