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.

At the bottom of the page is a sample CMakeLists.txt which shows how to create a library for this custom injector, then the library can be linked against the executable shown in the

Sample application section if you want to use a custom injector module.

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-2023 by Dolby Laboratories.
 ***************************************************************************/

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

#include <memory>
#include <mutex>

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

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

  // 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 set_sink(const std::shared_ptr<dolbyio::comms::video_sink>& sink,
                const dolbyio::comms::video_source::config& config) 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;
  std::shared_ptr<dolbyio::comms::video_sink> video_sink_{};

  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-2023 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(
    const dolbyio::comms::video_frame& frame) {
  std::lock_guard<std::mutex> lock(video_lock_);
  if (video_sink_) {
    video_sink_->handle_frame(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::set_sink(
    const std::shared_ptr<dolbyio::comms::video_sink>& sink,
    const config&) {
  std::lock_guard<std::mutex> lock(video_lock_);
  video_sink_ = sink;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0...3.21)

add_library(custom_injector STATIC
	custom_injector.h
	custom_injector.cc
)

target_link_libraries(custom_injector
  DolbyioComms::sdk
)