private:
void makePipeline();
void stopInternal();
+ void clearPipeline();
virtual void buildPipeline() = 0;
virtual void startPipeline() = 0;
void _connectAndAppendSignal(GList** signals, GObject* obj, const char* sig_name, GCallback cb, gpointer user_data);
void _disconnectSignal(GList** signals, GObject* obj);
void _disconnectSignal(gpointer data);
-bool _addNoTargetGhostpad(GstBin* bin, GstPad** new_pad, bool is_src);
-bool _setGhostpadTarget(GstPad* ghost_pad, GstElement* target_element, bool is_src);
+bool _addNoTargetGhostpad(GstBin* bin, GstPad** new_pad, bool isSrcPad);
+bool _setGhostpadTarget(GstPad* ghost_pad, GstElement* target_element, bool isSrcPad);
+GstPad* _getGhostPadFromBin(GstBin* bin, const std::string& name, bool isSrcPad);
unsigned int _getUnoccupiedSourceId(GHashTable* slots);
void _setElementProperties(GstElement* element, std::vector<std::string> key_value_pairs);
void _printCaps(GstCaps* caps, std::string prefix);
-GstPad* _getGhostPadFromBin(GstBin* bin);
-
void _updateCaps(GstElement* element, const param::videoInfo& vInfo);
void _updateEncCaps(GstElement* element, const param::videoInfo& vInfo);
void _updateCaps(GstElement* element, const param::audioInfo& aInfo);
void _updateEncCaps(GstElement* element, const param::audioInfo& aInfo);
+void _removeAllPads(GstElement* element, bool srcPad);
+void _removeAllElements(GstBin* bin);
+
}; // gst
} // tizen_media_transporter
void setSoundStreamInfo(sound_stream_info_h streamInfo);
protected:
- int _buildForwardingElements(GstElement* demux, GstPad* pad, GCallback callback);
+ int _buildForwardingElements(GstElement* demux, GstPad* pad, bool isAudio, GCallback callback);
int _buildRenderingElements(GstElement* demux, GstPad* pad, bool isAudio);
static void _streamAddedCallback(GstPad* pad, gpointer data);
#endif // __cplusplus
#endif // __TIZEN_MEDIA_TRANSPORTER_RECEIVER_H__
-
Name: capi-media-transporter
Summary: A Media Transporter library in Tizen Native API
-Version: 1.0.29
+Version: 1.0.30
Release: 0
Group: Multimedia/API
License: Apache-2.0
MediaSourceBinMediaPacket::~MediaSourceBinMediaPacket()
{
LOG_DEBUG("dtor: %p", this);
+ if (_mediaFormat)
+ media_format_unref(_mediaFormat);
+
if (_sourceCaps)
gst_caps_unref(_sourceCaps);
{
gst::GstElements elements;
- if (_mediaPacketSource == nullptr)
- throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Media packet source isn't created");
-
try {
+ _createMediaPacketSource();
+ _makeCapsFromMediaFormat(_mediaFormat);
+ g_object_set(_mediaPacketSource, "caps", _sourceCaps, nullptr);
+ gst::_printCaps(_sourceCaps, "setAppsrcCaps");
+
elements.push_back(_mediaPacketSource);
gst::_connectAndAppendSignal(&_signals, G_OBJECT(_mediaPacketSource), "need-data", G_CALLBACK(_needDataCallback), this);
gst::_connectAndAppendSignal(&_signals, G_OBJECT(_mediaPacketSource), "enough-data", G_CALLBACK(_enoughDataCallback), this);
void MediaSourceBinMediaPacket::setMediaFormat(media_format_h format)
{
+ if (media_format_ref(format) != MEDIA_FORMAT_ERROR_NONE)
+ throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Failed to ref media_format");
+
_mediaFormat = format;
- try {
- _createMediaPacketSource();
- _makeCapsFromMediaFormat(format);
- g_object_set(_mediaPacketSource, "caps", _sourceCaps, nullptr);
- gst::_printCaps(_sourceCaps, "setAppsrcCaps");
- } catch (const MediaTransporterException& e) {
- LOG_ERROR("%s", e.what());
- throw;
- }
}
void MediaSourceBinMediaPacket::pushMediaPacket(media_packet_h packet)
try {
auto handle = static_cast<media_transporter_s*>(mtpr);
assert(handle->base);
+ assert(handle->resourceManager);
handle->base->stop();
+ handle->resourceManager->releaseAll();
} catch (const MediaTransporterException& e) {
LOG_ERROR("Failed to stop!!! : %s", e.what());
return e.error();
MTPR_FLEAVE();
}
+void MediaTransporterBase::clearPipeline()
+{
+ MTPR_FENTER();
+
+ if (_gst.signals) {
+ g_list_free_full(_gst.signals, gst::_disconnectSignal);
+ _gst.signals = nullptr;
+ }
+
+ gst::_removeAllElements(GST_BIN(_gst.pipeline));
+}
+
void MediaTransporterBase::create()
{
gst::_gstInit();
{
try {
stopPipeline();
+ clearPipeline();
_state = MTPR_STATE_IDLE;
} catch (const MediaTransporterException& e) {
LOG_ERROR("%s", e.what());
_gst.bus = NULL;
}
- if (_gst.signals) {
- g_list_free_full(_gst.signals, gst::_disconnectSignal);
- _gst.signals = NULL;
- }
-
if (_gst.pipeline) {
gst_object_unref(_gst.pipeline);
_gst.pipeline = NULL;
g_free(sig_data);
}
-bool gst::_addNoTargetGhostpad(GstBin* bin, GstPad** new_pad, bool is_src)
+bool gst::_addNoTargetGhostpad(GstBin* bin, GstPad** new_pad, bool isSrcPad)
{
RET_VAL_IF(!bin, false, "bin is NULL");
RET_VAL_IF(!new_pad, false, "new_pad is NULL");
- GstPad* ghost_pad = gst_ghost_pad_new_no_target(NULL, is_src ? GST_PAD_SRC : GST_PAD_SINK);
+ GstPad* ghost_pad = gst_ghost_pad_new_no_target(NULL, isSrcPad ? GST_PAD_SRC : GST_PAD_SINK);
if (!ghost_pad) {
LOG_ERROR("failed to gst_ghost_pad_new_no_target()");
return false;
return true;
}
-bool gst::_setGhostpadTarget(GstPad* ghost_pad, GstElement* target_element, bool is_src)
+bool gst::_setGhostpadTarget(GstPad* ghost_pad, GstElement* target_element, bool isSrcPad)
{
RET_VAL_IF(!ghost_pad, false, "ghost_pad is NULL");
RET_VAL_IF(!target_element, false, "target_element is NULL");
- GstPad* target_pad = gst_element_get_static_pad(target_element, is_src ? "src" : "sink");
+ GstPad* target_pad = gst_element_get_static_pad(target_element, isSrcPad ? "src" : "sink");
if (!target_pad) {
LOG_ERROR("failed to gst_element_get_static_pad() of [%s]",
return true;
}
+GstPad* gst::_getGhostPadFromBin(GstBin* bin, const std::string& name, bool isSrcPad)
+{
+ if (name.empty())
+ throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Element name is empty");
+
+ GstElement* element = gst_bin_get_by_name(bin, name.c_str());
+ if (!element)
+ throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Failed to get element");
+
+ GstPad* pad = nullptr;
+
+ if (!gst::_addNoTargetGhostpad(bin, &pad, isSrcPad))
+ throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Failed to _addNoTargetGhostpad");
+
+ if (!gst::_setGhostpadTarget(pad, element, isSrcPad))
+ throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Failed to _setGhostpadTarget");
+
+ return pad;
+}
+
void gst::_removeElementsFromBin(GstBin* bin, GstElements& elements)
{
for (auto element : elements)
LOG_DEBUG("%s caps[%s]", prefix.c_str(), caps_str.c_str());
}
-GstPad* gst::_getGhostPadFromBin(GstBin* bin)
-{
- GstElement* queue = gst_bin_get_by_name(bin, "srcQueue");
- if (!queue)
- throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Failed to get srcQueue");
-
- GstPad* srcPad = nullptr;
-
- if (!gst::_addNoTargetGhostpad(bin, &srcPad, true))
- throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Failed to _addNoTargetGhostpad");
-
- if (!gst::_setGhostpadTarget(srcPad, queue, true))
- throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Failed to _setGhostpadTarget");
-
- return srcPad;
-}
-
-
void gst::_updateCaps(GstElement* element, const param::videoInfo& vInfo)
{
GstCaps* oldCaps;
gst_caps_unref(newCaps);
}
+
+void gst::_removeAllPads(GstElement* element, bool srcPad)
+{
+ RET_IF(!element, "input element is null");
+
+ g_auto(GValue) item = G_VALUE_INIT;
+ g_autoptr(GstIterator) it = srcPad ? gst_element_iterate_src_pads(element) : gst_element_iterate_sink_pads(element);
+ while (it) {
+ switch (gst_iterator_next (it, &item)) {
+ case GST_ITERATOR_OK:
+ {
+ GstPad *pad = GST_PAD(g_value_get_object (&item));
+ gst_element_remove_pad (element, pad);
+ }
+ break;
+ case GST_ITERATOR_DONE:
+ case GST_ITERATOR_ERROR:
+ return;
+ case GST_ITERATOR_RESYNC:
+ {
+ gst_iterator_resync(it);
+ break;
+ }
+ }
+ }
+}
+
+void gst::_removeAllElements(GstBin* bin)
+{
+ RET_IF(!bin, "input bin is null");
+
+ g_auto(GValue) item = G_VALUE_INIT;
+ g_autoptr(GstIterator) it = gst_bin_iterate_recurse(bin);
+ while (it) {
+ switch (gst_iterator_next (it, &item)) {
+ case GST_ITERATOR_OK:
+ {
+ GstElement *element = GST_ELEMENT(g_value_get_object (&item));
+ LOG_DEBUG("destroy %s element", GST_ELEMENT_NAME(element));
+ gst::_destroyElementFromParent(element);
+ gst_iterator_resync(it);
+ }
+ break;
+ case GST_ITERATOR_DONE:
+ case GST_ITERATOR_ERROR:
+ return;
+ case GST_ITERATOR_RESYNC:
+ {
+ gst_iterator_resync(it);
+ break;
+ }
+ }
+ }
+}
gst::_connectAndAppendSignal(&_gst.signals, G_OBJECT(fakesink), "handoff", callback, this);
}
-// FIXME : exception handling
-int MediaTransporterReceiver::_buildForwardingElements(GstElement* demux, GstPad* pad, GCallback callback)
+int MediaTransporterReceiver::_buildForwardingElements(GstElement* demux, GstPad* pad, bool isAudio, GCallback callback)
{
gst::GstElements elements;
NULL);
elements.push_back(queue);
- GstElement* parser = gst::_createElementFromRegistry("Parser", gst_pad_get_current_caps(pad), NULL,
- MediaTransporterIni::get().general().gstExcludedElements);
- if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(parser)), "config-interval")) {
- g_object_set(G_OBJECT(parser), "config-interval", -1, NULL);
- LOG_DEBUG("[%s] set config-interval -1", GST_ELEMENT_NAME(parser) );
+ GstElement* parser = nullptr;
+ std::string demuxerName = GST_ELEMENT_NAME(demux);
+ if (demuxerName.find("decodebin") == std::string::npos)
+ parser = gst::_createElementFromRegistry("Parser", gst_pad_get_current_caps(pad), NULL,
+ MediaTransporterIni::get().general().gstExcludedElements);
+
+ if (parser) {
+ if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(parser)), "config-interval")) {
+ g_object_set(G_OBJECT(parser), "config-interval", -1, NULL);
+ LOG_DEBUG("[%s] set config-interval -1", GST_ELEMENT_NAME(parser) );
+ }
+ elements.push_back(parser);
}
- elements.push_back(parser);
_buildForwardingSink(elements, pad, callback);
- gst::_addElementsToBin(GST_BIN(_gst.pipeline), elements);
+ std::string binName = isAudio ? "forwardingAudioBin" : "forwordingVideoBin";
+
+ GstBin* bin = GST_BIN(gst_bin_new(binName.c_str()));
+ if (!bin) {
+ LOG_ERROR("Failed to create bin");
+ gst::_clearElements(elements);
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
+
+ try {
+ gst::_addElementsToBin(bin, elements);
+ } catch (const MediaTransporterException& e) {
+ LOG_ERROR("%s", e.what());
+ gst::_clearElements(elements);
+ gst_object_unref(bin);
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
+
+
+ if (!gst_bin_add(GST_BIN(_gst.pipeline), GST_ELEMENT(bin))) {
+ LOG_ERROR("failed to add (%s)bin into pipeline", binName.c_str());
+ gst_object_unref(bin);
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
+
+ GstPad* sinkPad = nullptr;
+ try {
+ sinkPad = gst::_getGhostPadFromBin(bin, GST_ELEMENT_NAME(queue), false);
+ GstPadLinkReturn res = gst_pad_link(pad, sinkPad);
+ if (GST_PAD_LINK_FAILED(res)) {
+ LOG_ERROR("failed to link pads, [%s:%s] - [%s:%s]",
+ GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkPad));
+ gst_bin_remove(GST_BIN(_gst.pipeline), GST_ELEMENT(bin));
+ gst_object_unref(sinkPad);
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
+
+ gst::_linkElements(elements);
+ } catch (const MediaTransporterException& e) {
+ LOG_ERROR("%s", e.what());
+
+ gst_bin_remove(GST_BIN(_gst.pipeline), GST_ELEMENT(bin));
+ gst_object_unref(sinkPad);
+ if (sinkPad)
+ gst_object_unref(sinkPad);
- if (!gst_element_link_pads(GST_ELEMENT(demux),
- GST_PAD_NAME(pad),
- GST_ELEMENT(queue),
- "sink")) {
- LOG_ERROR("failed to link demuxer and queue");
+ return MTPR_ERROR_INVALID_OPERATION;
}
- gst::_linkElements(elements);
- gst::_syncElementsStateWithParent(elements);
+ if (!gst_element_sync_state_with_parent(GST_ELEMENT(bin))) {
+ LOG_ERROR("failed to sync %s state with parent", binName.c_str());
+ gst_bin_remove(GST_BIN(_gst.pipeline), GST_ELEMENT(bin));
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
return MTPR_ERROR_NONE;
}
NULL);
elements.push_back(queue);
- GstElement* parser = gst::_createElementFromRegistry("Parser", gst_pad_get_current_caps(pad), NULL,
- MediaTransporterIni::get().general().gstExcludedElements);
- GstPad* srcPad;
+ GstPad* srcPad = nullptr;
+ GstElement* parser = nullptr;
+ std::string demuxerName = GST_ELEMENT_NAME(demux);
+
+ if (demuxerName.find("decodebin") == std::string::npos)
+ parser = gst::_createElementFromRegistry("Parser", gst_pad_get_current_caps(pad), NULL,
+ MediaTransporterIni::get().general().gstExcludedElements);
if (parser) {
if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(parser)), "config-interval")) {
g_object_set(G_OBJECT(parser), "config-interval", -1, NULL);
srcPad = gst_element_get_static_pad(parser, "src");
elements.push_back(parser);
} else {
- srcPad = gst_element_get_static_pad(queue, "src");
+ srcPad = g_object_ref(pad);
}
GstCaps* caps = gst_pad_has_current_caps(srcPad) ? gst_pad_get_current_caps(srcPad)
else
_buildVideoRenderingSink(elements);
- gst::_addElementsToBin(GST_BIN(_gst.pipeline), elements);
+ std::string binName = isAudio ? "renderingAudioBin" : "renderingVideoBin";
+
+ GstBin* bin = GST_BIN(gst_bin_new(binName.c_str()));
+ if (!bin) {
+ LOG_ERROR("Failed to create bin");
+ gst::_clearElements(elements);
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
+
+ try {
+ gst::_addElementsToBin(bin, elements);
+ } catch (const MediaTransporterException& e) {
+ LOG_ERROR("%s", e.what());
+ gst::_clearElements(elements);
+ gst_object_unref(bin);
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
+
+ if (!gst_bin_add(GST_BIN(_gst.pipeline), GST_ELEMENT(bin))) {
+ LOG_ERROR("failed to add (%s)bin into pipeline", binName.c_str());
+ gst_object_unref(bin);
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
+
+ GstPad* sinkPad = nullptr;
+ try {
+ sinkPad = gst::_getGhostPadFromBin(bin, GST_ELEMENT_NAME(queue), false);
+ GstPadLinkReturn res = gst_pad_link(pad, sinkPad);
+ if (GST_PAD_LINK_FAILED(res)) {
+ LOG_ERROR("failed to link pads, [%s:%s] - [%s:%s]",
+ GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkPad));
+ gst_bin_remove(GST_BIN(_gst.pipeline), GST_ELEMENT(bin));
+ gst_object_unref(sinkPad);
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
+
+ gst::_linkElements(elements);
+ } catch (const MediaTransporterException& e) {
+ LOG_ERROR("%s", e.what());
+
+ gst_bin_remove(GST_BIN(_gst.pipeline), GST_ELEMENT(bin));
+ gst_object_unref(sinkPad);
+ if (sinkPad)
+ gst_object_unref(sinkPad);
- if (!gst_element_link_pads(GST_ELEMENT(demux),
- GST_PAD_NAME(pad),
- GST_ELEMENT(queue),
- "sink")) {
- LOG_ERROR("failed to link demuxer and queue");
+ return MTPR_ERROR_INVALID_OPERATION;
}
- gst::_linkElements(elements);
- gst::_syncElementsStateWithParent(elements);
+ if (!gst_element_sync_state_with_parent(GST_ELEMENT(bin))) {
+ LOG_ERROR("failed to sync %s state with parent", binName.c_str());
+ gst_bin_remove(GST_BIN(_gst.pipeline), GST_ELEMENT(bin));
+ return MTPR_ERROR_INVALID_OPERATION;
+ }
return MTPR_ERROR_NONE;
}
bool MediaTransporterReceiver::_isAudioMediaType(std::string mediaType)
{
return mediaType.find("audio") != std::string::npos;
-}
\ No newline at end of file
+}
bool isAudio = _isAudioMediaType(mediaType);
if (rist->_audioCallback._callback && isAudio)
- rist->_buildForwardingElements(demux, new_pad, G_CALLBACK(_encodedAudioStreamCallback));
+ rist->_buildForwardingElements(demux, new_pad, isAudio, G_CALLBACK(_encodedAudioStreamCallback));
else if (rist->_videoCallback._callback && !isAudio)
- rist->_buildForwardingElements(demux, new_pad, G_CALLBACK(_encodedVideoStreamCallback));
+ rist->_buildForwardingElements(demux, new_pad, isAudio, G_CALLBACK(_encodedVideoStreamCallback));
else
rist->_buildRenderingElements(demux, new_pad, isAudio);
bool isAudio = _isAudioMediaType(mediaType);
if (rtsp->_audioCallback._callback && isAudio)
- rtsp->_buildForwardingElements(decodebin, new_pad, G_CALLBACK(_encodedAudioStreamCallback));
+ rtsp->_buildForwardingElements(decodebin, new_pad, isAudio, G_CALLBACK(_encodedAudioStreamCallback));
else if (rtsp->_videoCallback._callback && !isAudio)
- rtsp->_buildForwardingElements(decodebin, new_pad, G_CALLBACK(_encodedVideoStreamCallback));
+ rtsp->_buildForwardingElements(decodebin, new_pad, isAudio, G_CALLBACK(_encodedVideoStreamCallback));
else
rtsp->_buildRenderingElements(decodebin, new_pad, isAudio);
bool isAudio = _isAudioMediaType(mediaType);
if (srt->_audioCallback._callback && isAudio)
- srt->_buildForwardingElements(demux, new_pad, G_CALLBACK(_encodedAudioStreamCallback));
+ srt->_buildForwardingElements(demux, new_pad, isAudio, G_CALLBACK(_encodedAudioStreamCallback));
else if (srt->_videoCallback._callback && !isAudio)
- srt->_buildForwardingElements(demux, new_pad, G_CALLBACK(_encodedVideoStreamCallback));
+ srt->_buildForwardingElements(demux, new_pad, isAudio, G_CALLBACK(_encodedVideoStreamCallback));
else
srt->_buildRenderingElements(demux, new_pad, isAudio);
void MediaTransporterReceiverSrt::foreachConnectionStats(InvokablePtr callback)
{
ConnectionStatsFactory::createReceiverSrtConnectionStats(_srtSrc, std::move(callback))->foreach();
-}
\ No newline at end of file
+}
gst_bin_add(GST_BIN(_gst.pipeline), GST_ELEMENT(bin));
- GstPad* srcPad = gst::_getGhostPadFromBin(bin);
+ GstPad* srcPad = gst::_getGhostPadFromBin(bin, "srcQueue", true);
if (gst_pad_is_linked(srcPad)) {
LOG_ERROR("pad %s:%s is already linked", GST_DEBUG_PAD_NAME(srcPad));
throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "already linked");
void MediaTransporterSenderRist::stopPipeline()
{
- _ristSink = NULL;
_canSendPacket = false;
gst::_setPipelineState(_gst.pipeline, GST_STATE_NULL,
MediaTransporterIni::get().general().timeout);
+ _ristSink = nullptr;
}
void MediaTransporterSenderRist::setConnection(std::string name, std::string val)
#define ADDR_PATH_DELIM "/"
#define ADDR_RTSP_PREFIX "rtsp://"
+#define DEFAULT_RTMP2PAY_NAME "pay0"
+
static GstRTSPFilterResult
__clientFilter(GstRTSPServer* server, GstRTSPClient* client, gpointer userData)
{
g_object_set(G_OBJECT(mux), "alignment", 7, NULL);
/* pay element name have to be "pay0" */
- pay = gst::_createElement("rtpmp2tpay", "pay0");
+ pay = gst::_createElement("rtpmp2tpay", DEFAULT_RTMP2PAY_NAME);
gst_bin_add_many(GST_BIN(_gst.pipeline), mux, pay, NULL);
if (!gst_element_link(mux, pay)) {
LOG_ERROR("failed to gst_element_link()");
void MediaTransporterSenderRtsp::startPipeline()
{
+ /* _canSendPacket flag is changed to true when _clientConnectedCb() is called */
startRtspServer();
}
void MediaTransporterSenderRtsp::stopPipeline()
{
_canSendPacket = false;
+
if (_rtspPipeline) {
GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(_rtspPipeline));
gst_bus_set_sync_handler(bus, NULL, NULL, NULL);
gst_object_unref(bus);
+ gst::_setPipelineState(_rtspPipeline, GST_STATE_NULL,
+ MediaTransporterIni::get().general().timeout);
+
+ gst::_removeAllPads(GST_ELEMENT(_gst.pipeline), true);
+
gst_object_unref(_rtspPipeline);
_rtspPipeline = NULL;
}
+
stopRtspServer();
removeIdleEventSource();
}
gst::_setPipelineState(_gst.pipeline, GST_STATE_PLAYING,
MediaTransporterIni::get().general().timeout, _asyncStart);
_canSendPacket = true;
+
startStatsMonitoring();
}
{
stopStatsMonitoring();
- _srtSink = NULL;
_canSendPacket = false;
gst::_setPipelineState(_gst.pipeline, GST_STATE_NULL,
MediaTransporterIni::get().general().timeout);
+ _srtSink = nullptr;
}
void MediaTransporterSenderSrt::setConnection(std::string name, std::string val)
void MediaTransporterSenderToServerRtsp::stopPipeline()
{
- _rtspSink = NULL;
_canSendPacket = false;
gst::_setPipelineState(_gst.pipeline, GST_STATE_NULL,
MediaTransporterIni::get().general().timeout);
+ _rtspSink = nullptr;
}
void MediaTransporterSenderToServerRtsp::setConnection(std::string name, std::string val)
}
case CURRENT_STATUS_ADD_MEDIA_SOURCE: {
value = atoi(cmd);
- _mtpr_test_add_media_source((mtpr_source_type_e) value - 1);
+ if (value < 1) {
+ reset_menu_state();
+ break;
+ }
+ _mtpr_test_add_media_source((mtpr_source_type_e)(value - 1));
if (value == 5) {
_mtpr_test_camera_packet_src_create(g_mtpr, g_video_source_id);
g_use_camera_for_packet = true;
int source_id;
camera_h camera;
bool push_packet;
+ bool stopped;
media_format_h format;
} test_camera_packet_src_s;
void _mtpr_test_camera_packet_src_start()
{
g_camera_src->push_packet = true;
+ if (g_camera_src->stopped) {
+ camera_start_preview(g_camera_src->camera);
+ g_camera_src->stopped = false;
+ }
}
void _mtrp_test_camera_packet_src_stop()
{
g_camera_src->push_packet = false;
camera_stop_preview(g_camera_src->camera);
+ g_camera_src->stopped = true;
}
void _mtrp_test_camera_packet_src_destroy()