Example Injector Implementation

Below are the header and cpp files for a Media Injector Implementation. In order for this injector to be used by the C++ SDK, it must be passed to the conference service using the dolbyio::comms::services::conference::set_media_source() method. Now when a conference is joined and audio/video is started, this injector is part of the media injection pipeline.

The interfaces inherited by this custom_injector example must be implemented by any custom injector intended to inject video and audio frames to a conference.

If you want to use a custom injector module instead of the default injector module, you can replace the CMakeLists.txt in the Server sample application section with the sample below. The paths in this CMakeLists.txt are assuming that the file is located in the same place as in the Writing Application portion of the Getting Started.

custom_injector.h

/***************************************************************************
 * This program is licensed by the accompanying "license" file. This file is
 * distributed "AS IS" AND WITHOUT WARRANTY OF ANY KIND WHATSOEVER, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 *                Copyright (C) 2022 by Dolby Laboratories.
 ***************************************************************************/

#include <dolbyio/comms/media_engine/media_engine.h>

#include <memory>
#include <mutex>

class custom_injector_impl : public dolbyio::comms::media_source_interface,
                             public dolbyio::comms::video_source,
                             public dolbyio::comms::audio_source {
 public:
  custom_injector_impl();
  ~custom_injector_impl();

  bool inject_audio_frame(std::unique_ptr<dolbyio::comms::audio_frame>&& frame);
  bool inject_video_frame(std::unique_ptr<dolbyio::comms::video_frame>&& frame);

  // media_source_interface
  dolbyio::comms::video_source* video() override { return this; }
  dolbyio::comms::audio_source* audio() override { return this; }

  // audio_source interface
  void register_audio_frame_rtc_source(dolbyio::comms::rtc_audio_source* source) override;
  void deregister_audio_frame_rtc_source() override;

  // video_source interface
  void register_video_frame_rtc_source(dolbyio::comms::rtc_video_source* source) override;
  void deregister_video_frame_rtc_source() override;

 private:
  // These are essentially audio/video sinks from the POV of the injector
  // providing the connection in the respective media pipelines to Webrtc
  dolbyio::comms::rtc_audio_source* rtc_audio_ = nullptr;
  dolbyio::comms::rtc_video_source* rtc_video_ = nullptr;

  std::mutex audio_lock_;
  std::mutex video_lock_;
};

custom_injector.cc

/***************************************************************************
 * This program is licensed by the accompanying "license" file. This file is
 * distributed "AS IS" AND WITHOUT WARRANTY OF ANY KIND WHATSOEVER, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 *                Copyright (C) 2022 by Dolby Laboratories.
 ***************************************************************************/

#include "custom_injector.h"

custom_injector_impl::custom_injector_impl() = default;
custom_injector_impl::~custom_injector_impl() = default;

bool custom_injector_impl::inject_audio_frame(std::unique_ptr<dolbyio::comms::audio_frame>&& frame) {
  std::lock_guard<std::mutex> lock(audio_lock_);
  if (frame && rtc_audio_) {
    rtc_audio_->on_data(frame->data(), 16, frame->sample_rate(), frame->channels(), frame->samples());
    return true;
  }
  return false;
}

bool custom_injector_impl::inject_video_frame(std::unique_ptr<dolbyio::comms::video_frame>&& frame) {
  std::lock_guard<std::mutex> lock(video_lock_);
  if (frame && rtc_video_) {
    rtc_video_->handle_frame(std::move(frame));
    return true;
  }
  return false;
}

// audio_source interface
void custom_injector_impl::register_audio_frame_rtc_source(dolbyio::comms::rtc_audio_source* source) {
  std::lock_guard<std::mutex> lock(audio_lock_);
  rtc_audio_ = source;
}

void custom_injector_impl::deregister_audio_frame_rtc_source() {
  std::lock_guard<std::mutex> lock(audio_lock_);
  rtc_audio_ = nullptr;
}

// video_source interface
void custom_injector_impl::register_video_frame_rtc_source(dolbyio::comms::rtc_video_source* source) {
  std::lock_guard<std::mutex> lock(video_lock_);
  rtc_video_ = source;
}
void custom_injector_impl::deregister_video_frame_rtc_source() {
  std::lock_guard<std::mutex> lock(video_lock_);
  rtc_video_ = nullptr;
}

main.cc

/***************************************************************************
 * This program is licensed by the accompanying "license" file. This file is
 * distributed "AS IS" AND WITHOUT WARRANTY OF ANY KIND WHATSOEVER, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 *                Copyright (C) 2022 by Dolby Laboratories.
 ***************************************************************************/

#include <dolbyio/comms/sdk.h>

#include "custom_injector.h"

int main(int, char**) {
  auto sdk = dolbyio::comms::sdk::create(std::string(), [](std::unique_ptr<dolbyio::comms::refresh_token>&&) {});
  auto injector = custom_injector_impl();

  return 0;
}

Injector CMakeLists.txt

cmake_minimum_required(VERSION 3.0...3.21)

add_executable(custom_injector
	main.cc
	custom_injector.h
	custom_injector.cc
)

target_link_libraries(custom_injector
  DolbyioComms::sdk
)