Add media packet source type for webrtc module
authorJiung Yu <jiung.yu@samsung.com>
Wed, 12 Apr 2023 04:28:01 +0000 (13:28 +0900)
committerJiung Yu <jiung.yu@samsung.com>
Wed, 14 Jun 2023 11:45:21 +0000 (20:45 +0900)
23 files changed:
include/AittStream.h
include/AittTypes.h
modules/rtsp/Module.cc
modules/rtsp/Module.h
modules/webrtc/CMakeLists.txt
modules/webrtc/CameraHandler.cc [deleted file]
modules/webrtc/CameraHandler.h [deleted file]
modules/webrtc/Module.cc
modules/webrtc/Module.h
modules/webrtc/SinkStreamManager.cc
modules/webrtc/SinkStreamManager.h
modules/webrtc/SrcStreamManager.cc
modules/webrtc/SrcStreamManager.h
modules/webrtc/StreamManager.cc
modules/webrtc/StreamManager.h
modules/webrtc/WebRtcEventHandler.h
modules/webrtc/WebRtcState.cc
modules/webrtc/WebRtcState.h
modules/webrtc/WebRtcStream.cc
modules/webrtc/WebRtcStream.h
modules/webrtc/tests/WEBRTC_test.cc
packaging/aitt.spec
tests/AittStream_test.cc

index bcaed9792e97472cfe1239d8efdbf3b559e55428..faa659c83d5700bd77c652a41aca050a3dd091c3 100644 (file)
@@ -39,6 +39,7 @@ class AittStream {
     virtual int GetHeight(void) = 0;
     virtual void Start(void) = 0;
     virtual void Stop(void) = 0;
+    virtual int Push(void *obj) = 0;
     virtual void SetStateCallback(StateCallback cb, void *user_data) = 0;
 
     // Subscriber ONLY
index 2f81371122af5b33253aabba8baba608f1089aad..f5014ce5b2b5f7bc1b7590c130117b58cd37692a 100644 (file)
@@ -36,8 +36,11 @@ enum AittStreamState {
     AITT_STREAM_STATE_INIT = 0,
     AITT_STREAM_STATE_READY = 1,
     AITT_STREAM_STATE_PLAYING = 2,
+    AITT_STREAM_STATE_UNDERFLOW = 3,
+    AITT_STREAM_STATE_OVERFLOW = 4
 };
 
+
 enum AittStreamRole {
     AITT_STREAM_ROLE_PUBLISHER = 0,   // Role of source media
     AITT_STREAM_ROLE_SUBSCRIBER = 1,  // Role of destination(receiver)
index 070fb01c7effaa013f4c11ff5656a906c0dc2060..7aaa434ef74c5e9ba822d6b60bb5352d9fbe5d66 100644 (file)
@@ -168,6 +168,11 @@ void Module::Stop(void)
     }
 }
 
+int Module::Push(void *obj)
+{
+    return AITT_ERROR_NOT_SUPPORTED;
+}
+
 void Module::UpdateDiscoveryMsg()
 {
     if (role_ == AittStreamRole::AITT_STREAM_ROLE_SUBSCRIBER)
index 4ad840123b2363a393b0de96389fc3bfbbf3a644..4e2deca4d30c506b3fcfd7016875b87062f91b78 100644 (file)
@@ -40,6 +40,7 @@ class Module : public AittStreamModule {
     int GetHeight(void) override;
     void Start(void) override;
     void Stop(void) override;
+    int Push(void *obj) override;
     void SetStateCallback(StateCallback cb, void *user_data) override;
     void SetReceiveCallback(ReceiveCallback cb, void *user_data) override;
 
index 04fe831f745da777ea6220a974394615c347982e..e45a733a3ac5e020b6127150950341ca49315b98 100644 (file)
@@ -3,7 +3,6 @@ set(AITT_WEBRTC aitt-stream-webrtc)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 pkg_check_modules(AITT_WEBRTC_NEEDS REQUIRED
-    capi-media-camera
     capi-media-webrtc
     gstreamer-video-1.0
     json-glib-1.0
diff --git a/modules/webrtc/CameraHandler.cc b/modules/webrtc/CameraHandler.cc
deleted file mode 100644 (file)
index c3fc8ec..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "CameraHandler.h"
-
-#include "aitt_internal.h"
-
-#define RETURN_DEFINED_NAME_AS_STRING(defined_constant) \
-    case defined_constant:                              \
-        return #defined_constant;
-
-CameraHandler::~CameraHandler(void)
-{
-    if (handle_) {
-        camera_state_e state = CAMERA_STATE_NONE;
-
-        int ret = camera_get_state(handle_, &state);
-        if (ret != CAMERA_ERROR_NONE) {
-            ERR("camera_get_state() Fail(%s)", ErrorToString(ret));
-        }
-
-        if (state == CAMERA_STATE_PREVIEW) {
-            INFO("CameraHandler preview is not stopped (stop)");
-            ret = camera_stop_preview(handle_);
-            if (ret != CAMERA_ERROR_NONE) {
-                ERR("camera_stop_preview() Fail(%s)", ErrorToString(ret));
-            }
-        }
-    }
-
-    if (handle_)
-        camera_destroy(handle_);
-}
-
-int CameraHandler::Init(const MediaPacketPreviewCallback &preview_cb, void *user_data)
-{
-    int ret = camera_create(CAMERA_DEVICE_CAMERA0, &handle_);
-    if (ret != CAMERA_ERROR_NONE) {
-        ERR("camera_create() Fail(%s)", ErrorToString(ret));
-        return -1;
-    }
-    SettingCamera(preview_cb, user_data);
-
-    return 0;
-}
-
-void CameraHandler::SettingCamera(const MediaPacketPreviewCallback &preview_cb, void *user_data)
-{
-    int ret = camera_set_media_packet_preview_cb(handle_, CameraPreviewCB, this);
-    if (ret != CAMERA_ERROR_NONE) {
-        ERR("camera_set_media_packet_preview_cb() Fail(%s)", ErrorToString(ret));
-        return;
-    }
-    media_packet_preview_cb_ = preview_cb;
-    user_data_ = user_data;
-}
-
-void CameraHandler::Deinit(void)
-{
-    if (!handle_) {
-        ERR("Handler is nullptr");
-        return;
-    }
-
-    is_started_ = false;
-    media_packet_preview_cb_ = nullptr;
-    user_data_ = nullptr;
-}
-
-int CameraHandler::StartPreview(void)
-{
-    camera_state_e state;
-    int ret = camera_get_state(handle_, &state);
-    if (ret != CAMERA_ERROR_NONE) {
-        ERR("camera_get_state() Fail(%s)", ErrorToString(ret));
-        return -1;
-    }
-
-    if (state == CAMERA_STATE_PREVIEW) {
-        INFO("Preview is already started");
-        is_started_ = true;
-        return 0;
-    }
-
-    ret = camera_start_preview(handle_);
-    if (ret != CAMERA_ERROR_NONE) {
-        ERR("camera_start_preview() Fail(%s)", ErrorToString(ret));
-        return -1;
-    }
-
-    is_started_ = true;
-
-    return 0;
-}
-
-int CameraHandler::StopPreview(void)
-{
-    RETV_IF(handle_ == nullptr, -1);
-    is_started_ = false;
-
-    return 0;
-}
-
-void CameraHandler::CameraPreviewCB(media_packet_h media_packet, void *user_data)
-{
-    auto camera_handler = static_cast<CameraHandler *>(user_data);
-    if (!camera_handler) {
-        ERR("Invalid user_data");
-        return;
-    }
-
-    if (!camera_handler->is_started_) {
-        ERR("Preveiw is not started yet");
-        return;
-    }
-
-    if (!camera_handler->media_packet_preview_cb_) {
-        ERR("Preveiw cb is not set");
-        return;
-    }
-
-    camera_handler->media_packet_preview_cb_(media_packet, camera_handler->user_data_);
-}
-
-const char *CameraHandler::ErrorToString(const int error)
-{
-    switch (error) {
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_NONE)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_INVALID_PARAMETER)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_INVALID_STATE)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_OUT_OF_MEMORY)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_DEVICE)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_INVALID_OPERATION)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_SECURITY_RESTRICTED)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_DEVICE_BUSY)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_DEVICE_NOT_FOUND)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_ESD)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_PERMISSION_DENIED)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_NOT_SUPPORTED)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_RESOURCE_CONFLICT)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_ERROR_SERVICE_DISCONNECTED)
-    }
-
-    return "Unknown error";
-}
-
-const char *CameraHandler::StateToString(const camera_state_e state)
-{
-    switch (state) {
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_STATE_NONE)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_STATE_CREATED)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_STATE_PREVIEW)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_STATE_CAPTURING)
-        RETURN_DEFINED_NAME_AS_STRING(CAMERA_STATE_CAPTURED)
-    }
-
-    return "Unknown state";
-}
diff --git a/modules/webrtc/CameraHandler.h b/modules/webrtc/CameraHandler.h
deleted file mode 100644 (file)
index 5c44828..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <camera.h>
-
-#include <functional>
-
-class CameraHandler {
-  public:
-    using MediaPacketPreviewCallback = std::function<void(media_packet_h, void *)>;
-
-    ~CameraHandler();
-    int Init(const MediaPacketPreviewCallback &preview_cb, void *user_data);
-    void Deinit(void);
-    int StartPreview(void);
-    int StopPreview(void);
-
-    static const char *ErrorToString(const int error);
-    static const char *StateToString(const camera_state_e state);
-
-  private:
-    void SettingCamera(const MediaPacketPreviewCallback &preview_cb, void *user_data);
-    static void CameraPreviewCB(media_packet_h media_packet, void *user_data);
-
-    camera_h handle_;
-    bool is_started_;
-    MediaPacketPreviewCallback media_packet_preview_cb_;
-    void *user_data_;
-};
index 6c64a137d6b604b43d9daedede595def3fecebae..0e125e21cf0e452f7d2137352de6d725ff07f06c 100644 (file)
@@ -45,6 +45,11 @@ Module::Module(AittDiscovery &discovery, const std::string &topic, AittStreamRol
     discovery_cb_ = discovery_.AddDiscoveryCB(stream_manager_->GetWatchingTopic(),
           std::bind(&Module::DiscoveryMessageCallback, this, std::placeholders::_1,
                 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
+    stream_manager_->SetIceCandidateAddedCallback(std::bind(&Module::OnIceCandidateAdded, this));
+    stream_manager_->SetStreamStartCallback(std::bind(&Module::OnStreamStarted, this));
+    stream_manager_->SetStreamStopCallback(std::bind(&Module::OnStreamStopped, this));
+    stream_manager_->SetStreamStateCallback(
+          std::bind(&Module::OnStreamState, this, std::placeholders::_1));
 }
 
 Module::~Module(void)
@@ -66,6 +71,12 @@ int Module::SetConfig(const std::string &key, const std::string &value)
             stream_manager_->SetHeight(std::stoi(value));
         else if (key == "FRAME_RATE")
             stream_manager_->SetFrameRate(std::stoi(value));
+        else if (key == "MEDIA_FORMAT")
+            stream_manager_->SetMediaFormat(value);
+        else if (key == "SOURCE_TYPE")
+            stream_manager_->SetSourceType(value);
+        else if (key == "DECODE_CODEC")
+            stream_manager_->SetDecodeCodec(value);
         else
             return AITT_ERROR_INVALID_PARAMETER;
     } catch (std::exception &e) {
@@ -97,10 +108,6 @@ int Module::GetHeight(void)
 
 void Module::Start(void)
 {
-    stream_manager_->SetIceCandidateAddedCallback(std::bind(&Module::OnIceCandidateAdded, this));
-    stream_manager_->SetStreamStartCallback(std::bind(&Module::OnStreamStarted, this));
-    stream_manager_->SetStreamStopCallback(std::bind(&Module::OnStreamStopped, this));
-
     stream_manager_->Start();
 }
 
@@ -108,6 +115,12 @@ void Module::Stop(void)
 {
 }
 
+int Module::Push(void *obj)
+{
+    // TODO: We need to classify error codes
+    return stream_manager_->Push(obj);
+}
+
 void Module::OnIceCandidateAdded(void)
 {
     DBG("OnIceCandidateAdded");
@@ -139,6 +152,22 @@ void Module::OnStreamStopped(void)
     discovery_.UpdateDiscoveryMsg(stream_manager_->GetTopic(), msg.data(), msg.size());
 }
 
+void Module::OnStreamState(const std::string &state)
+{
+    if (!state_callback_)
+        return;
+
+    DBG("%s", state.c_str());
+    if (state == "IDLE")
+        state_callback_(this, AITT_STREAM_STATE_INIT, state_cb_user_data_);
+    else if (state == "PLAYING")
+        state_callback_(this, AITT_STREAM_STATE_PLAYING, state_cb_user_data_);
+    else if (state == "UNDERFLOW")
+        state_callback_(this, AITT_STREAM_STATE_UNDERFLOW, state_cb_user_data_);
+    else if (state == "OVERFLOW")
+        state_callback_(this, AITT_STREAM_STATE_OVERFLOW, state_cb_user_data_);
+}
+
 void Module::SetStateCallback(StateCallback cb, void *user_data)
 {
     state_callback_ = cb;
index d746cddf5f994222c5f5dd936a95b2bd2ad9955e..01cc9bfe6c366201de11b84d98106f748d252025 100644 (file)
@@ -44,6 +44,7 @@ class Module : public AittStreamModule {
     int GetHeight(void) override;
     void Start(void) override;
     void Stop(void) override;
+    int Push(void *obj) override;
     void SetStateCallback(StateCallback cb, void *user_data) override;
     void SetReceiveCallback(ReceiveCallback cb, void *user_data) override;
 
@@ -52,6 +53,7 @@ class Module : public AittStreamModule {
     void OnIceCandidateAdded(void);
     void OnStreamStarted(void);
     void OnStreamStopped(void);
+    void OnStreamState(const std::string &state);
     void DiscoveryMessageCallback(const std::string &clientId, const std::string &status,
           const void *msg, const int szmsg);
 
index 841e88fe78cf6a3f3381692dbd96eac6151021db..a61687a684a648dae1467f036a426a9181791b8a 100644 (file)
@@ -30,6 +30,10 @@ SinkStreamManager::SinkStreamManager(const std::string &topic, const std::string
         video_appsrc_(nullptr),
         decode_pipeline_(nullptr)
 {
+    SetWebRtcStreamCallbacks(stream_);
+    stream_.AttachSignals(false, need_display_);
+    stream_.ActivateSource();
+    stream_.SetDecodeCodec(decode_codec_);
 }
 
 SinkStreamManager::~SinkStreamManager()
@@ -57,6 +61,8 @@ void SinkStreamManager::SetWebRtcStreamCallbacks(WebRtcStream &stream)
 void SinkStreamManager::OnStreamStateChanged(WebRtcState::Stream state, WebRtcStream &stream)
 {
     DBG("OnSinkStreamStateChanged: %s", WebRtcState::StreamToStr(state).c_str());
+    if (stream_state_cb_)
+        stream_state_cb_(WebRtcState::StreamToStr(state));
     if (state == WebRtcState::Stream::NEGOTIATING) {
         stream.CreateOfferAsync(std::bind(&SinkStreamManager::OnOfferCreated, this,
               std::placeholders::_1, std::ref(stream)));
@@ -108,11 +114,22 @@ void SinkStreamManager::BuildDecodePipeline(void)
     GstElement *src = gst_element_factory_make("appsrc", nullptr);
 
     // TODO:How do we can know decoder type
-    GstCaps *app_src_caps = gst_caps_new_simple("video/x-vp8", nullptr, nullptr);
-    g_object_set(G_OBJECT(src), "format", GST_FORMAT_TIME, "caps", app_src_caps, nullptr);
-    gst_caps_unref(app_src_caps);
+    GstElement *dec = nullptr;
+    if (decode_codec_ == "H264") {
+        GstCaps *app_src_caps = gst_caps_new_simple("video/x-h264", "stream-format", G_TYPE_STRING,
+              "byte-stream", "alignment", G_TYPE_STRING, "au", NULL);
+
+        g_object_set(G_OBJECT(src), "caps", app_src_caps, "format", GST_FORMAT_TIME, NULL);
+        gst_caps_unref(app_src_caps);
 
-    GstElement *dec = gst_element_factory_make("vp8dec", nullptr);
+        dec = gst_element_factory_make("avdec_h264", NULL);
+    } else {
+        GstCaps *app_src_caps = gst_caps_new_simple("video/x-vp8", nullptr, nullptr);
+        g_object_set(G_OBJECT(src), "format", GST_FORMAT_TIME, "caps", app_src_caps, nullptr);
+        gst_caps_unref(app_src_caps);
+
+        dec = gst_element_factory_make("vp8dec", nullptr);
+    }
     GstElement *convert = gst_element_factory_make("videoconvert", nullptr);
     GstElement *filter = gst_element_factory_make("capsfilter", "I420toRGBCapsfilter");
     GstCaps *filter_caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "BGR", NULL);
@@ -154,7 +171,9 @@ void SinkStreamManager::OnSignalHandOff(GstElement *object, GstBuffer *buffer, G
         return;
     }
     RET_IF(vinfo.width == 0 || vinfo.height == 0 || vinfo.finfo == nullptr);
-    manager->SetFormat(vinfo.finfo->name, vinfo.width, vinfo.height);
+    manager->SetMediaFormat(vinfo.finfo->name);
+    manager->SetWidth(vinfo.width);
+    manager->SetHeight(vinfo.height);
     manager->HandleFrame(buffer);
 }
 
@@ -198,8 +217,6 @@ void SinkStreamManager::HandleStartStream(const std::string &discovery_id)
 
 void SinkStreamManager::AddStream(const std::string &discovery_id)
 {
-    SetWebRtcStreamCallbacks(stream_);
-    stream_.Create(false, need_display_);
     stream_.Start();
 
     std::stringstream s_stream;
@@ -278,4 +295,10 @@ void SinkStreamManager::SetOnFrameCallback(OnFrameCallback cb)
     request_server_.SetOnFrameCallback(cb);
 }
 
+int SinkStreamManager::Push(void *obj)
+{
+    DBG("Not supported");
+    return -1;
+}
+
 }  // namespace AittWebRTCNamespace
index f17ae848e38b98305c270813d1899716f5cc75ef..084677d15572e0cc0d48a313a0b4b3cefe0a18b3 100644 (file)
@@ -22,8 +22,8 @@
 #include <mutex>
 #include <thread>
 
-#include "StreamManager.h"
 #include "RequestServer.h"
+#include "StreamManager.h"
 namespace AittWebRTCNamespace {
 
 class SinkStreamManager : public StreamManager {
@@ -33,6 +33,7 @@ class SinkStreamManager : public StreamManager {
     virtual ~SinkStreamManager();
     std::vector<uint8_t> GetDiscoveryMessage(void) override;
     void SetOnFrameCallback(OnFrameCallback cb) override;
+    int Push(void *obj) override;
 
   private:
     void SetWebRtcStreamCallbacks(WebRtcStream &stream) override;
index 3a4b534f751d400aa48bde9c9aaef94108c827ab..55bcb24c3843137e6841e52cf8b43a8ffb40c912 100644 (file)
@@ -28,6 +28,11 @@ SrcStreamManager::SrcStreamManager(const std::string &topic, const std::string &
       const std::string &thread_id)
       : StreamManager(topic + "/SRC", topic + "/SINK", aitt_id, thread_id)
 {
+    SetWebRtcStreamCallbacks(stream_);
+    stream_.AttachSignals(true, false);
+    source_type_ = "CAMERA";
+    stream_.SetSourceType(WEBRTC_MEDIA_SOURCE_TYPE_CAMERA);
+    stream_.ActivateSource();
 }
 
 SrcStreamManager::~SrcStreamManager()
@@ -45,11 +50,16 @@ void SrcStreamManager::SetWebRtcStreamCallbacks(WebRtcStream &stream)
 
     stream.GetEventHandler().SetOnIceCandidateCb(
           std::bind(&SrcStreamManager::OnIceCandidate, this));
+
+    stream.GetEventHandler().SetOnSourceBufferStateCb(
+          std::bind(&SrcStreamManager::OnSourceBufferStateNotify, this, std::placeholders::_1));
 }
 
 void SrcStreamManager::OnStreamStateChanged(WebRtcState::Stream state)
 {
     DBG("OnSrcStreamStateChanged: %s", WebRtcState::StreamToStr(state).c_str());
+    if (stream_state_cb_)
+        stream_state_cb_(WebRtcState::StreamToStr(state));
 }
 
 void SrcStreamManager::OnSignalingStateNotify(WebRtcState::Signaling state, WebRtcStream &stream)
@@ -74,6 +84,13 @@ void SrcStreamManager::OnIceCandidate(void)
         ice_candidate_added_cb_();
 }
 
+void SrcStreamManager::OnSourceBufferStateNotify(WebRtcState::SourceBufferState state)
+{
+    DBG("OnSourceBufferStateNotify: %s", WebRtcState::SourceBufferStateToStr(state).c_str());
+    if (stream_state_cb_)
+        stream_state_cb_(WebRtcState::SourceBufferStateToStr(state));
+}
+
 void SrcStreamManager::HandleStreamState(const std::string &discovery_id,
       const std::vector<uint8_t> &message)
 {
@@ -123,8 +140,6 @@ void SrcStreamManager::UpdateStreamInfo(const std::string &discovery_id, const s
 void SrcStreamManager::AddStream(const std::string &discovery_id, const std::string &id,
       const std::string &sdp, const std::vector<std::string> &ice_candidates)
 {
-    SetWebRtcStreamCallbacks(stream_);
-    CreateSrcStream();
     stream_.Start();
 
     std::stringstream s_stream;
@@ -138,22 +153,6 @@ void SrcStreamManager::AddStream(const std::string &discovery_id, const std::str
     return;
 }
 
-void SrcStreamManager::CreateSrcStream(void)
-{
-    SetWebRtcStreamCallbacks(stream_);
-    stream_.Create(true, false);
-    if (source_type_ == "MEDIA_PACKET")
-        stream_.AttachMediaPacketSource();
-    else if (source_type_ == "CAMERA") {
-        stream_.AttachCameraSource();
-        if (width_ && height_)
-            stream_.SetVideoResolution(width_, height_);
-        if (frame_rate_)
-            stream_.SetVideoFrameRate(frame_rate_);
-    } else
-        DBG("Source is not available");
-}
-
 std::vector<uint8_t> SrcStreamManager::GetDiscoveryMessage(void)
 {
     std::vector<uint8_t> message;
@@ -175,4 +174,14 @@ std::vector<uint8_t> SrcStreamManager::GetDiscoveryMessage(void)
     return message;
 }
 
+int SrcStreamManager::Push(void *obj)
+{
+    if (source_type_ != "MEDIA_PACKET") {
+        DBG("Wrong source type");
+        return -1;
+    }
+
+    return stream_.Push(obj);
+}
+
 }  // namespace AittWebRTCNamespace
index f76e8e1e6a6710ac7e6139245e419bb84fc6661d..fe5091c94bcc1a2fde7612766d5427b1831779c3 100644 (file)
@@ -28,6 +28,7 @@ class SrcStreamManager : public StreamManager {
           const std::string &thread_id);
     virtual ~SrcStreamManager();
     std::vector<uint8_t> GetDiscoveryMessage(void) override;
+    int Push(void *obj) override;
 
   private:
     void SetWebRtcStreamCallbacks(WebRtcStream &stream) override;
@@ -35,6 +36,7 @@ class SrcStreamManager : public StreamManager {
     void OnAnswerCreated(std::string sdp, WebRtcStream &stream);
     void OnIceCandidate(void);
     void OnSignalingStateNotify(WebRtcState::Signaling state, WebRtcStream &stream);
+    void OnSourceBufferStateNotify(WebRtcState::SourceBufferState state);
     void HandleStreamState(const std::string &discovery_id,
           const std::vector<uint8_t> &message) override;
     void HandleStreamInfo(const std::string &discovery_id,
index f24aba81d5c9fbb57e91e4ab2db6aedc84ba7948..c78700587e5d7c7d70ca0704231d036bfa49fce1 100644 (file)
@@ -27,12 +27,15 @@ StreamManager::StreamManager(const std::string &topic, const std::string &watchi
         width_(0),
         height_(0),
         frame_rate_(0),
-        source_type_("CAMERA"),
+        //Need to sync with source_type_ on stream
+        source_type_("NULL"),
+        decode_codec_("VP8"),
         topic_(topic),
         watching_topic_(watching_topic),
         aitt_id_(aitt_id),
         thread_id_(thread_id)
 {
+    stream_.AddDataChannel();
 }
 
 bool StreamManager::IsStarted(void) const
@@ -55,33 +58,89 @@ int StreamManager::GetHeight(void)
     return height_;
 }
 
-void StreamManager::SetFormat(const std::string &format, int width, int height)
-{
-    format_ = format;
-    width_ = width;
-    height_ = height;
-}
-
 void StreamManager::SetWidth(int width)
 {
+    if (width_ == width)
+        return;
+
+    if (source_type_ == "MEDIA_PACKET" && height_ && frame_rate_ && format_.size())
+        stream_.SetMediaFormat(width_, height_, frame_rate_, format_);
+    else if (source_type_ == "CAMERA" && height_)
+        stream_.SetVideoResolution(width, height_);
     width_ = width;
 }
 
 void StreamManager::SetHeight(int height)
 {
+    if (height_ == height)
+        return;
+
+    if (source_type_ == "MEDIA_PACKET" && width_ && frame_rate_ && format_.size())
+        stream_.SetMediaFormat(width_, height, frame_rate_, format_);
+    else if (source_type_ == "CAMERA" && width_)
+        stream_.SetVideoResolution(width_, height);
     height_ = height;
 }
 
 void StreamManager::SetFrameRate(int frame_rate)
 {
+    if (frame_rate_ == frame_rate)
+        return;
+
+    if (source_type_ == "MEDIA_PACKET" && width_ && height_ && format_.size())
+        stream_.SetMediaFormat(width_, height_, frame_rate, format_);
+    else if (source_type_ == "CAMERA")
+        stream_.SetVideoFrameRate(frame_rate);
     frame_rate_ = frame_rate;
 }
 
 void StreamManager::SetSourceType(const std::string &source_type)
 {
+    if (source_type_ == source_type)
+        return;
+
+    stream_.DeactivateSource();
+    if (source_type == "MEDIA_PACKET") {
+        stream_.SetSourceType(WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET);
+        stream_.ActivateSource();
+        if (width_ && height_ && frame_rate_ && format_.size())
+            stream_.SetMediaFormat(width_, height_, frame_rate_, format_);
+    } else if (source_type == "CAMERA") {
+        stream_.SetSourceType(WEBRTC_MEDIA_SOURCE_TYPE_CAMERA);
+        stream_.ActivateSource();
+        if (width_ && height_)
+            stream_.SetVideoResolution(width_, height_);
+        if (frame_rate_)
+            stream_.SetVideoFrameRate(frame_rate_);
+    } else if (source_type == "NULL") {
+        stream_.SetSourceType(WEBRTC_MEDIA_SOURCE_TYPE_NULL);
+        stream_.ActivateSource();
+    } else
+        DBG("%s is not available source type", source_type.c_str());
+
     source_type_ = source_type;
 }
 
+void StreamManager::SetMediaFormat(const std::string &format)
+{
+    if (format_ == format)
+        return;
+
+    if (source_type_ == "MEDIA_PACKET" && width_ && height_ && frame_rate_)
+        stream_.SetMediaFormat(width_, height_, frame_rate_, format);
+    format_ = format;
+}
+
+void StreamManager::SetDecodeCodec(const std::string &codec)
+{
+    if (decode_codec_ == codec)
+        return;
+
+    if (source_type_ == "NULL")
+        stream_.SetDecodeCodec(codec);
+    decode_codec_ = codec;
+}
+
 void StreamManager::Start(void)
 {
     DBG("%s %s", __func__, GetTopic().c_str());
@@ -146,6 +205,11 @@ void StreamManager::SetStreamStopCallback(StreamStopCallback cb)
     stream_stop_cb_ = cb;
 }
 
+void StreamManager::SetStreamStateCallback(StreamStateCallback cb)
+{
+    stream_state_cb_ = cb;
+}
+
 void StreamManager::SetOnFrameCallback(OnFrameCallback cb)
 {
     on_frame_cb_ = cb;
index 3663c58cdb1d2bbcf4dc2461d9bfa0dc0e8b528f..353dad499b426f9bdc3bab99b782f5036dbec2f5 100644 (file)
@@ -31,6 +31,7 @@ class StreamManager {
     using StreamStartCallback = std::function<void(void)>;
     using StreamStopCallback = std::function<void(void)>;
     using OnFrameCallback = std::function<void(void *)>;
+    using StreamStateCallback = std::function<void(const std::string &)>;
     explicit StreamManager(const std::string &topic, const std::string &watching_topic,
           const std::string &aitt_id, const std::string &thread_id);
     virtual ~StreamManager() = default;
@@ -40,18 +41,21 @@ class StreamManager {
     std::string GetFormat(void);
     int GetWidth(void);
     int GetHeight(void);
-    void SetFormat(const std::string &format, int width, int height);
     void SetWidth(int width);
     void SetHeight(int height);
     void SetFrameRate(int frame_rate);
+    void SetMediaFormat(const std::string &format);
     void SetSourceType(const std::string &source_type);
+    void SetDecodeCodec(const std::string &codec);
     void Start(void);
     void Stop(void);
+    virtual int Push(void *obj) = 0;
     void HandleRemovedClient(const std::string &discovery_id);
     void HandleMsg(const std::string &discovery_id, const std::vector<uint8_t> &message);
     void SetIceCandidateAddedCallback(IceCandidateAddedCallback cb);
     void SetStreamStartCallback(StreamStartCallback cb);
     void SetStreamStopCallback(StreamStopCallback cb);
+    void SetStreamStateCallback(StreamStateCallback cb);
     virtual void SetOnFrameCallback(OnFrameCallback cb);
 
     std::string GetTopic(void) const;
@@ -65,16 +69,18 @@ class StreamManager {
     int frame_rate_;
     std::string source_type_;
     std::string format_;
+    std::string decode_codec_;
     std::string topic_;
     std::string watching_topic_;
     // TODO: why dont' we remove below
     std::string aitt_id_;
     std::string thread_id_;
-    // We assume Module class can't be copyable
     std::string peer_aitt_id_;
+    // We assume Module class can't be copyable
     WebRtcStream stream_;
     StreamStartCallback stream_start_cb_;
     StreamStopCallback stream_stop_cb_;
+    StreamStateCallback stream_state_cb_;
     IceCandidateAddedCallback ice_candidate_added_cb_;
     OnFrameCallback on_frame_cb_;
 
index bc5ffa870b48fe65a2c4e0e008b8ccef841d0bcd..34b2923bba99858211dc6b4f9699705610b2fe59 100644 (file)
@@ -105,6 +105,17 @@ class WebRtcEventHandler {
     };
     void UnsetTrackAddedCb(void) { on_track_added_cb_ = nullptr; };
 
+    void SetOnSourceBufferStateCb(std::function<void(WebRtcState::SourceBufferState)> on_source_buffer_state_notify_cb)
+    {
+        on_source_buffer_state_notify_cb_ = on_source_buffer_state_notify_cb;
+    }
+    void CallOnSourceBufferStateCb(WebRtcState::SourceBufferState state) const
+    {
+        if (on_source_buffer_state_notify_cb_)
+            on_source_buffer_state_notify_cb_(state);
+    };
+    void UnsetSourceBufferStateCb(void) { on_source_buffer_state_notify_cb_ = nullptr; };
+
   private:
     std::function<void(void)> on_negotiation_needed_cb_;
     std::function<void(WebRtcState::Stream)> on_state_changed_cb_;
@@ -114,6 +125,7 @@ class WebRtcEventHandler {
     std::function<void(WebRtcState::IceConnection)> on_ice_connection_state_notify_cb_;
     std::function<void(media_packet_h)> on_encoded_frame_cb_;
     std::function<void(unsigned int id)> on_track_added_cb_;
+    std::function<void(WebRtcState::SourceBufferState)> on_source_buffer_state_notify_cb_;
 };
 
 }  // namespace AittWebRTCNamespace
index a547dd84c7f124167ec065c9182ad4910d9bc8a4..e1964f8709486e45b50022e6305a717811a103ec 100644 (file)
@@ -188,4 +188,30 @@ std::string WebRtcState::IceConnectionToStr(WebRtcState::IceConnection state)
     return std::string("");
 }
 
+WebRtcState::SourceBufferState WebRtcState::ToSourceBufferState(webrtc_media_packet_source_buffer_state_e state)
+{
+    switch (state) {
+    case WEBRTC_MEDIA_PACKET_SOURCE_BUFFER_STATE_UNDERFLOW: {
+        return SourceBufferState::UNDERFLOW;
+    }
+    case WEBRTC_MEDIA_PACKET_SOURCE_BUFFER_STATE_OVERFLOW: {
+        return SourceBufferState::OVERFLOW;
+    }
+    }
+    return SourceBufferState::OVERFLOW;
+}
+
+std::string WebRtcState::SourceBufferStateToStr(WebRtcState::SourceBufferState state)
+{
+    switch (state) {
+    case (WebRtcState::SourceBufferState::UNDERFLOW): {
+        return std::string("UNDERFLOW");
+    }
+    case (WebRtcState::SourceBufferState::OVERFLOW): {
+        return std::string("OVERFLOW");
+    }
+    }
+    return std::string("");
+}
+
 }  // namespace AittWebRTCNamespace
index 48c850a24288046955964ed48da916ee5cc1bf3b..ed1816d2ed1aa3acd63131ece9764a10b79ed679 100644 (file)
@@ -64,6 +64,11 @@ class WebRtcState {
         CLOSED,
     };
 
+    enum class SourceBufferState {
+        UNDERFLOW,
+        OVERFLOW,
+    };
+
   public:
     static Stream ToStreamState(webrtc_state_e state);
     static std::string StreamToStr(WebRtcState::Stream state);
@@ -73,6 +78,8 @@ class WebRtcState {
     static std::string IceGatheringToStr(WebRtcState::IceGathering state);
     static IceConnection ToIceConnectionState(webrtc_ice_connection_state_e state);
     static std::string IceConnectionToStr(WebRtcState::IceConnection state);
+    static SourceBufferState ToSourceBufferState(webrtc_media_packet_source_buffer_state_e state);
+    static std::string SourceBufferStateToStr(WebRtcState::SourceBufferState state);
 };
 
 }  // namespace AittWebRTCNamespace
index 38dfd3c664ca7681944d362a37a976c2808feb48..8b47b0a60436d64c76d8c0bbf4c94ca0feb6b9cd 100644 (file)
 #include "WebRtcStream.h"
 
 #include <inttypes.h>
+#include <media_format.h>
 #include <webrtc_internal.h>
 
+#include <stdexcept>
+
 #include "WebRtcMessage.h"
 #include "aitt_internal.h"
 
 namespace AittWebRTCNamespace {
 
-WebRtcStream::WebRtcStream() : webrtc_handle_(nullptr), channel_(nullptr), source_id_(0)
+WebRtcStream::WebRtcStream()
+      : webrtc_handle_(nullptr),
+        source_type_(WEBRTC_MEDIA_SOURCE_TYPE_NULL),
+        channel_(nullptr),
+        source_id_(0)
 {
+    // Notice for Tizen webrtc handle
+    // This API includes file read operation, launching thread,
+    // gstreamer library initialization, and so on.
+    auto ret = webrtc_create(&webrtc_handle_);
+    if (ret != WEBRTC_ERROR_NONE)
+        throw std::runtime_error("WebRtc Handler Creation Failed");
 }
 
 WebRtcStream::~WebRtcStream()
@@ -33,42 +46,8 @@ WebRtcStream::~WebRtcStream()
     DBG("%s", __func__);
 }
 
-bool WebRtcStream::Create(bool is_source, bool need_display)
-{
-    if (webrtc_handle_) {
-        ERR("Already created %p", webrtc_handle_);
-        return false;
-    }
-
-    auto ret = webrtc_create(&webrtc_handle_);
-    if (ret != WEBRTC_ERROR_NONE) {
-        ERR("Failed to create webrtc handle");
-        return false;
-    }
-
-    if (!is_source) {
-        auto add_source_ret =
-              webrtc_add_media_source(webrtc_handle_, WEBRTC_MEDIA_SOURCE_TYPE_NULL, &source_id_);
-        if (add_source_ret != WEBRTC_ERROR_NONE)
-            ERR("Failed to add media source");
-        auto set_transceiver_codec_ret = webrtc_media_source_set_transceiver_codec(webrtc_handle_,
-              source_id_, WEBRTC_MEDIA_TYPE_VIDEO, WEBRTC_TRANSCEIVER_CODEC_VP8);
-        if (set_transceiver_codec_ret != WEBRTC_ERROR_NONE)
-            ERR("Failed to set transceiver codec");
-    }
-
-    webrtc_create_data_channel(webrtc_handle_, "label", nullptr, &channel_);
-    AttachSignals(is_source, need_display);
-
-    return true;
-}
-
 void WebRtcStream::Destroy(void)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return;
-    }
     auto stop_ret = webrtc_stop(webrtc_handle_);
     if (stop_ret != WEBRTC_ERROR_NONE)
         ERR("Failed to stop webrtc handle");
@@ -87,11 +66,6 @@ void WebRtcStream::Destroy(void)
 
 bool WebRtcStream::Start(void)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
-
     auto ret = webrtc_start(webrtc_handle_);
     if (ret != WEBRTC_ERROR_NONE)
         ERR("Failed to start webrtc handle");
@@ -101,11 +75,6 @@ bool WebRtcStream::Start(void)
 
 bool WebRtcStream::Stop(void)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
-
     auto ret = webrtc_stop(webrtc_handle_);
     if (ret != WEBRTC_ERROR_NONE)
         ERR("Failed to stop webrtc handle");
@@ -114,53 +83,44 @@ bool WebRtcStream::Stop(void)
     return ret == WEBRTC_ERROR_NONE;
 }
 
-bool WebRtcStream::AttachCameraSource(void)
+int WebRtcStream::Push(void *obj)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
-
-    if (source_id_) {
-        ERR("source already attached");
-        return false;
-    }
-
-    auto ret =
-          webrtc_add_media_source(webrtc_handle_, WEBRTC_MEDIA_SOURCE_TYPE_CAMERA, &source_id_);
+    auto ret = webrtc_media_packet_source_push_packet(webrtc_handle_, source_id_,
+          static_cast<media_packet_h>(obj));
     if (ret != WEBRTC_ERROR_NONE)
-        ERR("Failed to add media source");
+        ERR("Failed to push packet");
 
-    return ret == WEBRTC_ERROR_NONE;
+    // TODO what should be initialized?
+    return ret;
 }
 
-bool WebRtcStream::AttachMediaPacketSource(void)
+void WebRtcStream::SetSourceType(webrtc_media_source_type_e source_type)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
+    source_type_ = source_type;
+}
 
+bool WebRtcStream::ActivateSource(void)
+{
     if (source_id_) {
         ERR("source already attached");
         return false;
     }
 
-    auto ret = webrtc_add_media_source(webrtc_handle_, WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET,
-          &source_id_);
+    auto ret = webrtc_add_media_source(webrtc_handle_, source_type_, &source_id_);
     if (ret != WEBRTC_ERROR_NONE)
         ERR("Failed to add media source");
 
+    if (source_type_ == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
+        int set_buffer_cb_ret = webrtc_media_packet_source_set_buffer_state_changed_cb(
+              webrtc_handle_, source_id_, OnBufferStateChanged, this);
+        DBG("webrtc_media_packet_source_set_buffer_state_changed_cb %s",
+              set_buffer_cb_ret == WEBRTC_ERROR_NONE ? "Succeeded" : "failed");
+    }
     return ret == WEBRTC_ERROR_NONE;
 }
 
-bool WebRtcStream::DetachSource(void)
+bool WebRtcStream::DeactivateSource(void)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
-
     if (!source_id_) {
         ERR("Media source is not attached");
         return false;
@@ -169,17 +129,14 @@ bool WebRtcStream::DetachSource(void)
     auto ret = webrtc_remove_media_source(webrtc_handle_, source_id_);
     if (ret != WEBRTC_ERROR_NONE)
         ERR("Failed to remove media source");
+    else
+        source_id_ = 0;
 
     return ret == WEBRTC_ERROR_NONE;
 }
 
 bool WebRtcStream::SetVideoResolution(int width, int height)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
-
     if (!source_id_) {
         ERR("Media source is not attached");
         return false;
@@ -194,11 +151,6 @@ bool WebRtcStream::SetVideoResolution(int width, int height)
 
 bool WebRtcStream::SetVideoFrameRate(int frame_rate)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
-
     if (!source_id_) {
         ERR("Media source is not attached");
         return false;
@@ -211,12 +163,38 @@ bool WebRtcStream::SetVideoFrameRate(int frame_rate)
     return ret == WEBRTC_ERROR_NONE;
 }
 
-bool WebRtcStream::CreateOfferAsync(std::function<void(std::string)> on_created_cb)
+bool WebRtcStream::SetMediaFormat(int width, int height, int frame_rate, const std::string &format)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
+    media_format_h media_format =
+          static_cast<media_format_h>(GetMediaFormatHandler(width, height, frame_rate, format));
+    if (!media_format)
         return false;
-    }
+
+    auto ret = webrtc_media_packet_source_set_format(webrtc_handle_, source_id_, media_format);
+    if (ret != WEBRTC_ERROR_NONE)
+        ERR("Failed to set media format");
+    media_format_unref(media_format);
+
+    return ret == WEBRTC_ERROR_NONE;
+}
+
+void WebRtcStream::SetDecodeCodec(const std::string &codec)
+{
+    webrtc_transceiver_codec_e transceiver_codec = WEBRTC_TRANSCEIVER_CODEC_VP8;
+    if (codec == "VP9")
+        transceiver_codec = WEBRTC_TRANSCEIVER_CODEC_VP9;
+    else if (codec == "H264")
+        transceiver_codec = WEBRTC_TRANSCEIVER_CODEC_H264;
+    auto ret = webrtc_media_source_set_transceiver_codec(webrtc_handle_, source_id_,
+          WEBRTC_MEDIA_TYPE_VIDEO, transceiver_codec);
+    if (ret != WEBRTC_ERROR_NONE)
+        ERR("Failed to set transceiver codec");
+
+    return;
+}
+
+bool WebRtcStream::CreateOfferAsync(std::function<void(std::string)> on_created_cb)
+{
     on_offer_created_cb_ = on_created_cb;
     auto ret = webrtc_create_offer_async(webrtc_handle_, NULL, OnOfferCreated, this);
     if (ret != WEBRTC_ERROR_NONE)
@@ -237,10 +215,6 @@ void WebRtcStream::OnOfferCreated(webrtc_h webrtc, const char *description, void
 
 bool WebRtcStream::CreateAnswerAsync(std::function<void(std::string)> on_created_cb)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
     on_answer_created_cb_ = on_created_cb;
     auto ret = webrtc_create_answer_async(webrtc_handle_, NULL, OnAnswerCreated, this);
     if (ret != WEBRTC_ERROR_NONE)
@@ -261,11 +235,6 @@ void WebRtcStream::OnAnswerCreated(webrtc_h webrtc, const char *description, voi
 
 bool WebRtcStream::SetLocalDescription(const std::string &description)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
-
     auto ret = webrtc_set_local_description(webrtc_handle_, description.c_str());
     if (ret != WEBRTC_ERROR_NONE)
         ERR("Failed to set local description");
@@ -277,11 +246,6 @@ bool WebRtcStream::SetLocalDescription(const std::string &description)
 
 bool WebRtcStream::SetRemoteDescription(const std::string &description)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
-
     auto ret = webrtc_set_remote_description(webrtc_handle_, description.c_str());
     if (ret != WEBRTC_ERROR_NONE)
         ERR("Failed to set remote description");
@@ -311,11 +275,6 @@ std::string &WebRtcStream::GetPeerId(void)
 
 bool WebRtcStream::AddIceCandidateFromMessage(const std::string &ice_message)
 {
-    ERR("%s", __func__);
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return false;
-    }
     auto ret = webrtc_add_ice_candidate(webrtc_handle_, ice_message.c_str());
     if (ret != WEBRTC_ERROR_NONE)
         ERR("Failed to set add ice candidate");
@@ -478,13 +437,13 @@ void WebRtcStream::PrintStats(void)
         DBG("webrtc_foreach_stats failed");
 }
 
-void WebRtcStream::AttachSignals(bool is_source, bool need_display)
+void WebRtcStream::AddDataChannel(void)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return;
-    }
+    webrtc_create_data_channel(webrtc_handle_, "label", nullptr, &channel_);
+}
 
+void WebRtcStream::AttachSignals(bool is_source, bool need_display)
+{
     int ret = WEBRTC_ERROR_NONE;
     // TODO: ADHOC TV profile doesn't show DBG level log
     ret = webrtc_set_error_cb(webrtc_handle_, OnError, this);
@@ -521,11 +480,6 @@ void WebRtcStream::AttachSignals(bool is_source, bool need_display)
 
 void WebRtcStream::DetachSignals(void)
 {
-    if (!webrtc_handle_) {
-        ERR("WebRTC handle is not created");
-        return;
-    }
-
     webrtc_unset_error_cb(webrtc_handle_);
     webrtc_unset_state_changed_cb(webrtc_handle_);
     webrtc_unset_signaling_state_change_cb(webrtc_handle_);
@@ -631,4 +585,54 @@ void WebRtcStream::OnDataChannelOpen(webrtc_data_channel_h channel, void *user_d
     ERR("%s", __func__);
 }
 
+void WebRtcStream::OnBufferStateChanged(unsigned int id,
+      webrtc_media_packet_source_buffer_state_e state, void *user_data)
+{
+    ERR("%s", __func__);
+    auto webrtc_stream = static_cast<WebRtcStream *>(user_data);
+    RET_IF(webrtc_stream == nullptr);
+    webrtc_stream->GetEventHandler().CallOnSourceBufferStateCb(
+          WebRtcState::ToSourceBufferState(state));
+}
+
+static media_format_mimetype_e __get_video_format_enum(const std::string &format)
+{
+    if (format == "I420")
+        return MEDIA_FORMAT_I420;
+    else if (format == "NV12")
+        return MEDIA_FORMAT_NV12;
+    else if (format == "VP8")
+        return MEDIA_FORMAT_VP8;
+    else if (format == "VP9")
+        return MEDIA_FORMAT_VP9;
+    else if (format == "H264")
+        return MEDIA_FORMAT_H264_HP;
+    else if (format == "JPEG")
+        return MEDIA_FORMAT_MJPEG;
+    else
+        return MEDIA_FORMAT_MAX;
+}
+
+void *WebRtcStream::GetMediaFormatHandler(int width, int height, int frame_rate,
+      const std::string &format)
+{
+    media_format_h media_format = nullptr;
+    auto ret = media_format_create(&media_format);
+    if (ret != MEDIA_FORMAT_ERROR_NONE) {
+        DBG("failed to media_format_create()");
+        return nullptr;
+    }
+
+    ret = media_format_set_video_mime(media_format, __get_video_format_enum(format));
+    ret |= media_format_set_video_width(media_format, width);
+    ret |= media_format_set_video_height(media_format, height);
+    ret |= media_format_set_video_frame_rate(media_format, frame_rate);
+    if (ret != MEDIA_FORMAT_ERROR_NONE) {
+        DBG("failed to set video format");
+        media_format_unref(media_format);
+        return nullptr;
+    }
+
+    return media_format;
+}
 }  // namespace AittWebRTCNamespace
index f41b91a9379602b1643c3cedb81e6dbe7bfa2ff2..f610bfb41710a2ff0249658a07bf0b6c6592de2c 100644 (file)
@@ -34,15 +34,18 @@ class WebRtcStream {
   public:
     WebRtcStream();
     ~WebRtcStream();
-    bool Create(bool is_source, bool need_display);
     void Destroy(void);
     bool Start(void);
     bool Stop(void);
-    bool AttachCameraSource(void);
-    bool AttachMediaPacketSource(void);
-    bool DetachSource(void);
+    int Push(void *obj);
+    void SetSourceType(webrtc_media_source_type_e source_type);
+    bool ActivateSource(void);
+    bool DeactivateSource(void);
     bool SetVideoResolution(int width, int height);
     bool SetVideoFrameRate(int frame_rate);
+    bool SetMediaFormat(int width, int height, int frame_rate, const std::string &format);
+    void SetDecodeCodec(const std::string &codec);
+    void AddDataChannel(void);
     void AttachSignals(bool is_source, bool need_display);
     void DetachSignals(void);
     // Cautions : Event handler is not a pointer. So, change event_handle after Set Event handler
@@ -70,6 +73,7 @@ class WebRtcStream {
     std::string GetLocalDescription(void) const { return local_description_; };
 
     void PrintStats(void);
+    bool IsPlayingState(void);
 
   private:
     static void OnOfferCreated(webrtc_h webrtc, const char *description, void *user_data);
@@ -90,12 +94,16 @@ class WebRtcStream {
     static void OnTrackAdded(webrtc_h webrtc, webrtc_media_type_e type, unsigned int id,
           void *user_data);
     static void OnDataChannelOpen(webrtc_data_channel_h channel, void *user_data);
+    static void OnBufferStateChanged(unsigned int id,
+          webrtc_media_packet_source_buffer_state_e state, void *user_data);
     bool IsNegotiatingState(void);
-    bool IsPlayingState(void);
     bool IsRedundantCandidate(const std::string &candidate);
+    static void *GetMediaFormatHandler(int width, int height, int frame_rate,
+          const std::string &format);
 
   private:
     webrtc_h webrtc_handle_;
+    webrtc_media_source_type_e source_type_;
     webrtc_data_channel_h channel_;
     unsigned int source_id_;
     std::string local_description_;
index 5fed8b8c02a269877f0c94b187ab51f0ee42a920..d0aa49945ab7cb6453fc67cf91d0c51231c93d35 100644 (file)
@@ -105,14 +105,16 @@ class WebRtcStreamTest : public testing::Test {
 TEST_F(WebRtcStreamTest, test_Create_WebRtcStream_OnDevice)
 {
     WebRtcStream src_stream{};
-    EXPECT_EQ(true, src_stream.Create(true, false)) << "Failed to create source stream";
 }
 
 TEST_F(WebRtcStreamTest, test_Start_WebRtcSrcStream_OnDevice)
 {
     WebRtcStream stream{};
-    EXPECT_EQ(true, stream.Create(true, false)) << "Failed to create source stream";
-    EXPECT_EQ(true, stream.AttachCameraSource()) << "Failed to attach camera source";
+    stream.AddDataChannel();
+    stream.AttachSignals(true, false);
+
+    stream.SetSourceType(WEBRTC_MEDIA_SOURCE_TYPE_CAMERA);
+    EXPECT_EQ(true, stream.ActivateSource()) << "Failed to attach camera source";
     stream.GetEventHandler().SetOnStateChangedCb(
           std::bind(OnStreamStateChanged, std::placeholders::_1, std::ref(stream), this));
 
@@ -220,8 +222,10 @@ class WebRtcSourceOffererTest : public testing::Test {
 
 TEST_F(WebRtcSourceOffererTest, test_Start_WebRtcStream_OnDevice)
 {
-    EXPECT_EQ(true, src_stream_.Create(true, false)) << "Failed to create source stream";
-    EXPECT_EQ(true, src_stream_.AttachCameraSource()) << "Failed to attach camera source";
+    src_stream_.AddDataChannel();
+    src_stream_.AttachSignals(true, false);
+    src_stream_.SetSourceType(WEBRTC_MEDIA_SOURCE_TYPE_CAMERA);
+    EXPECT_EQ(true, src_stream_.ActivateSource()) << "Failed to attach camera source";
     src_stream_.GetEventHandler().SetOnStateChangedCb(
           std::bind(OnSrcStreamStateChanged, std::placeholders::_1, std::ref(src_stream_), this));
 
@@ -232,7 +236,8 @@ TEST_F(WebRtcSourceOffererTest, test_Start_WebRtcStream_OnDevice)
           OnSrcIceGatheringStateNotify, std::placeholders::_1, std::ref(src_stream_), this));
     src_stream_.Start();
 
-    EXPECT_EQ(true, sink_stream_.Create(false, false)) << "Failed to create sink stream";
+    sink_stream_.AddDataChannel();
+    sink_stream_.AttachSignals(false, false);
     sink_stream_.GetEventHandler().SetOnStateChangedCb(
           std::bind(OnSinkStreamStateChanged, std::placeholders::_1, std::ref(sink_stream_), this));
 
@@ -339,8 +344,10 @@ class WebRtcSinkOffererTest : public testing::Test {
 
 TEST_F(WebRtcSinkOffererTest, test_Start_WebRtcStream_OnDevice)
 {
-    EXPECT_EQ(true, src_stream_.Create(true, false)) << "Failed to create source stream";
-    EXPECT_EQ(true, src_stream_.AttachCameraSource()) << "Failed to attach camera source";
+    src_stream_.AddDataChannel();
+    src_stream_.AttachSignals(true, false);
+    src_stream_.SetSourceType(WEBRTC_MEDIA_SOURCE_TYPE_CAMERA);
+    EXPECT_EQ(true, src_stream_.ActivateSource()) << "Failed to attach camera source";
     auto on_src_stream_state_changed_cb =
           std::bind(OnSrcStreamStateChanged, std::placeholders::_1, std::ref(src_stream_), this);
     src_stream_.GetEventHandler().SetOnStateChangedCb(on_src_stream_state_changed_cb);
@@ -352,7 +359,8 @@ TEST_F(WebRtcSinkOffererTest, test_Start_WebRtcStream_OnDevice)
           OnSrcIceGatheringStateNotify, std::placeholders::_1, std::ref(src_stream_), this));
     src_stream_.Start();
 
-    EXPECT_EQ(true, sink_stream_.Create(false, false)) << "Failed to create sink stream";
+    src_stream_.AddDataChannel();
+    src_stream_.AttachSignals(false, false);
     sink_stream_.GetEventHandler().SetOnStateChangedCb(
           std::bind(OnSinkStreamStateChanged, std::placeholders::_1, std::ref(sink_stream_), this));
 
index 10b02be8903fd4bfddcdb963677418780a9afb2d..2558afa66bcc53d39b58f17a9176617f2390135e 100644 (file)
@@ -21,7 +21,6 @@ BuildRequires: pkgconfig(gmock_main)
 BuildRequires: pkgconfig(libmosquitto)
 BuildRequires: pkgconfig(openssl1.1)
 %if %{use_glib}
-BuildRequires: pkgconfig(capi-media-camera)
 BuildRequires: pkgconfig(capi-media-player)
 BuildRequires: pkgconfig(capi-media-image-util)
 BuildRequires: pkgconfig(capi-media-sound-manager)
index 6a849fcb2c2726cada5b316205d8faeb90fb80e8..1c0c91c2e0b9647f3a6837aed17170ee52ee86c5 100644 (file)
@@ -141,6 +141,37 @@ TEST_F(AITTWEBRTCTest, Set_Resolution_Frame_Rate_P)
         FAIL() << "Unexpected exception: " << e.what();
     }
 }
+
+#define MEDIA_FORMAT_I420 "I420"
+TEST_F(AITTWEBRTCTest, Set_Source_Type_Media_Packet_P)
+{
+    try {
+        publisher->SetConfig("SOURCE_TYPE", "MEDIA_PACKET");
+        publisher->SetConfig("WIDTH", std::to_string(HD_WIDTH));
+        publisher->SetConfig("HEIGHT", std::to_string(HD_HEIGHT));
+        publisher->SetConfig("FRAME_RATE", std::to_string(FRAME_RATE_10));
+        publisher->SetConfig("MEDIA_FORMAT", MEDIA_FORMAT_I420);
+
+        subscriber->SetReceiveCallback(
+              [&](AittStream *stream, void *obj, void *user_data) {
+                  if (stream == nullptr) {
+                      printf("Invalid stream\n");
+                      return;
+                  }
+
+                  DBG("ReceiveCallback Called");
+                  if (g_main_loop_is_running(main_loop))
+                      g_main_loop_quit(main_loop);
+              },
+              nullptr);
+        subscriber->Start();
+        publisher->Start();
+
+        g_main_loop_run(main_loop);
+    } catch (std::exception &e) {
+        FAIL() << "Unexpected exception: " << e.what();
+    }
+}
 #endif
 
 class AITTRTSPTest : public testing::Test {