Shaka Packager SDK
Loading...
Searching...
No Matches
webm_audio_client.cc
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <packager/media/formats/webm/webm_audio_client.h>
6
7#include <cstddef>
8#include <cstdint>
9#include <ios>
10#include <memory>
11#include <string>
12#include <vector>
13
14#include <absl/log/log.h>
15
16#include <packager/media/base/audio_stream_info.h>
17#include <packager/media/base/stream_info.h>
18#include <packager/media/formats/webm/webm_constants.h>
19
20namespace {
21// Timestamps are represented in double in WebM. Convert to int64_t in us.
22const int32_t kWebMTimeScale = 1000000;
23} // namespace
24
25namespace shaka {
26namespace media {
27
28WebMAudioClient::WebMAudioClient() {
29 Reset();
30}
31
32WebMAudioClient::~WebMAudioClient() {}
33
35 channels_ = -1;
36 samples_per_second_ = -1;
37 output_samples_per_second_ = -1;
38}
39
40std::shared_ptr<AudioStreamInfo> WebMAudioClient::GetAudioStreamInfo(
41 int64_t track_num,
42 const std::string& codec_id,
43 const std::vector<uint8_t>& codec_private,
44 int64_t seek_preroll,
45 int64_t codec_delay,
46 const std::string& language,
47 bool is_encrypted) {
48 Codec audio_codec = kUnknownCodec;
49 if (codec_id == "A_VORBIS") {
50 audio_codec = kCodecVorbis;
51 } else if (codec_id == "A_OPUS") {
52 audio_codec = kCodecOpus;
53 } else {
54 LOG(ERROR) << "Unsupported audio codec_id " << codec_id;
55 return std::shared_ptr<AudioStreamInfo>();
56 }
57
58 if (samples_per_second_ <= 0)
59 return std::shared_ptr<AudioStreamInfo>();
60
61 // Set channel layout default if a Channels element was not present.
62 if (channels_ == -1)
63 channels_ = 1;
64
65 uint32_t sampling_frequency = samples_per_second_;
66 // Always use 48kHz for OPUS. See the "Input Sample Rate" section of the
67 // spec: http://tools.ietf.org/html/draft-terriberry-oggopus-01#page-11
68 if (audio_codec == kCodecOpus) {
69 sampling_frequency = 48000;
70 }
71
72 const uint8_t* codec_config = NULL;
73 size_t codec_config_size = 0;
74 if (codec_private.size() > 0) {
75 codec_config = &codec_private[0];
76 codec_config_size = codec_private.size();
77 }
78
79 const uint8_t kSampleSizeInBits = 16u;
80 return std::make_shared<AudioStreamInfo>(
81 track_num, kWebMTimeScale, 0, audio_codec,
82 AudioStreamInfo::GetCodecString(audio_codec, 0), codec_config,
83 codec_config_size, kSampleSizeInBits, channels_, sampling_frequency,
84 seek_preroll < 0 ? 0 : seek_preroll, codec_delay < 0 ? 0 : codec_delay, 0,
85 0, language, is_encrypted);
86}
87
88bool WebMAudioClient::OnUInt(int id, int64_t val) {
89 if (id == kWebMIdChannels) {
90 if (channels_ != -1) {
91 LOG(ERROR) << "Multiple values for id " << std::hex << id
92 << " specified. (" << channels_ << " and " << val << ")";
93 return false;
94 }
95
96 channels_ = val;
97 }
98 return true;
99}
100
101bool WebMAudioClient::OnFloat(int id, double val) {
102 double* dst = NULL;
103
104 switch (id) {
105 case kWebMIdSamplingFrequency:
106 dst = &samples_per_second_;
107 break;
108 case kWebMIdOutputSamplingFrequency:
109 dst = &output_samples_per_second_;
110 break;
111 default:
112 return true;
113 }
114
115 if (val <= 0)
116 return false;
117
118 if (*dst != -1) {
119 LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified ("
120 << *dst << " and " << val << ")";
121 return false;
122 }
123
124 *dst = val;
125 return true;
126}
127
128} // namespace media
129} // namespace shaka
static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
std::shared_ptr< AudioStreamInfo > GetAudioStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, int64_t seek_preroll, int64_t codec_delay, const std::string &language, bool is_encrypted)
void Reset()
Reset this object's state so it can process a new audio track element.
All the methods that are virtual are virtual for mocking.