1 /* 2 * Copyright (c) 2024, Alliance for Open Media. All rights reserved 3 * 4 * This source code is subject to the terms of the BSD 3-Clause Clear License 5 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear 6 * License was not distributed with this source code in the LICENSE file, you 7 * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the 8 * Alliance for Open Media Patent License 1.0 was not distributed with this 9 * source code in the PATENTS file, you can obtain it at 10 * www.aomedia.org/license/patent. 11 */ 12 #ifndef CLI_RENDERER_AUDIO_ELEMENT_RENDERER_PASSTHROUGH_H_ 13 #define CLI_RENDERER_AUDIO_ELEMENT_RENDERER_PASSTHROUGH_H_ 14 #include <cstddef> 15 #include <memory> 16 #include <vector> 17 18 #include "absl/base/thread_annotations.h" 19 #include "absl/status/status.h" 20 #include "absl/types/span.h" 21 #include "iamf/cli/channel_label.h" 22 #include "iamf/cli/renderer/audio_element_renderer_base.h" 23 #include "iamf/obu/audio_element.h" 24 #include "iamf/obu/mix_presentation.h" 25 #include "iamf/obu/types.h" 26 27 namespace iamf_tools { 28 /*!\brief Passthrough demixed channels corresponding with output layout. 29 * 30 * This class represents a renderer which is suitable for use when the 31 * associated audio element has a layer which matches the playback layout 32 * according to IAMF Spec 7.3.2.1 33 * (https://aomediacodec.github.io/iamf/#processing-mixpresentation-rendering-m2l). 34 * 35 * - Call `RenderAudioFrame()` to render a labeled frame. The rendering may 36 * happen asynchronously. 37 * - Call `SamplesAvailable()` to see if there are samples available. 38 * - Call `Flush()` to retrieve finished frames, in the order they were 39 * received by `RenderLabeledFrame()`. 40 * - Call `Finalize()` to close the renderer, telling it to finish rendering 41 * any remaining frames, which can be retrieved one last time via `Flush()`. 42 * After calling `Finalize()`, any subsequent call to `RenderAudioFrame()` 43 * may fail. 44 */ 45 class AudioElementRendererPassThrough : public AudioElementRendererBase { 46 public: 47 /*!\brief Creates a passthrough renderer from a channel-based config. 48 * 49 * Creates a passthrough renderer if it is suitable for use according to IAMF 50 * Spec 7.3.2.1. In particular when either of these conditions are true: 51 * - "If num_layers = 1, use the loudspeaker_layout of the Audio Element." 52 * - "Else, if there is an Audio Element with a loudspeaker_layout that 53 * matches the playback layout, use it." 54 * 55 * \param scalable_channel_layout_config Config for the scalable channel 56 * layout. 57 * \param playback_layout Layout of the audio element to be rendered 58 * \param num_samples_per_frame Number of samples per frame. 59 * \return Render to use or `nullptr` if it would not be suitable for use. 60 */ 61 static std::unique_ptr<AudioElementRendererPassThrough> 62 CreateFromScalableChannelLayoutConfig( 63 const ScalableChannelLayoutConfig& scalable_channel_layout_config, 64 const Layout& playback_layout, size_t num_samples_per_frame); 65 66 /*!\brief Destructor. */ 67 ~AudioElementRendererPassThrough() override = default; 68 69 private: 70 /*!\brief Constructor. 71 * 72 * \param ordered_labels Ordered list of channel labels to render. 73 */ AudioElementRendererPassThrough(const std::vector<ChannelLabel::Label> & ordered_labels,size_t num_samples_per_frame)74 AudioElementRendererPassThrough( 75 const std::vector<ChannelLabel::Label>& ordered_labels, 76 size_t num_samples_per_frame) 77 : AudioElementRendererBase( 78 ordered_labels, 79 // For a passthrough renderer, (number of output channels) 80 // is the same as (number of input channels). 81 num_samples_per_frame, 82 /*num_output_channels=*/ordered_labels.size()) {} 83 84 /*!\brief Renders samples. 85 * 86 * \param samples_to_render Samples to render arranged in (time, channel). 87 * \param rendered_samples Output rendered samples. 88 * \return `absl::OkStatus()` on success. A specific status on failure. 89 */ 90 absl::Status RenderSamples( 91 absl::Span<const std::vector<InternalSampleType>> samples_to_render, 92 std::vector<InternalSampleType>& rendered_samples) 93 ABSL_SHARED_LOCKS_REQUIRED(mutex_) override; 94 }; 95 96 } // namespace iamf_tools 97 #endif // CLI_RENDERER_AUDIO_ELEMENT_RENDERER_PASSTHROUGH_H_ 98