Revert "[M120 Migration]Fix for crash during chrome exit"
[platform/framework/web/chromium-efl.git] / media / filters / passthrough_dts_audio_decoder.cc
1 // Copyright 2022 The Chromium Authors
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 "media/filters/passthrough_dts_audio_decoder.h"
6
7 #include "base/task/bind_post_task.h"
8 #include "base/task/sequenced_task_runner.h"
9 #include "media/base/audio_buffer.h"
10 #include "media/formats/dts/dts_util.h"
11
12 namespace media {
13
14 PassthroughDTSAudioDecoder::PassthroughDTSAudioDecoder(
15     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
16     MediaLog* media_log)
17     : task_runner_(task_runner),
18       media_log_(media_log),
19       pool_(base::MakeRefCounted<AudioBufferMemoryPool>()) {
20   DETACH_FROM_SEQUENCE(sequence_checker_);
21 }
22
23 PassthroughDTSAudioDecoder::~PassthroughDTSAudioDecoder() {
24   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
25 }
26
27 AudioDecoderType PassthroughDTSAudioDecoder::GetDecoderType() const {
28   return AudioDecoderType::kPassthroughDTS;
29 }
30
31 void PassthroughDTSAudioDecoder::Initialize(const AudioDecoderConfig& config,
32                                             CdmContext* /* cdm_context */,
33                                             InitCB init_cb,
34                                             const OutputCB& output_cb,
35                                             const WaitingCB& /* waiting_cb */) {
36   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
37   DCHECK(config.IsValidConfig());
38   InitCB bound_init_cb = base::BindPostTaskToCurrentDefault(std::move(init_cb));
39   if (config.is_encrypted()) {
40     std::move(bound_init_cb)
41         .Run(DecoderStatus(DecoderStatus::Codes::kUnsupportedEncryptionMode,
42                            "PassthroughDTSAudioDecoder does not support "
43                            "encrypted content"));
44     return;
45   }
46
47   if (config.target_output_sample_format() != kSampleFormatDts) {
48     std::move(bound_init_cb)
49         .Run(
50             DecoderStatus(DecoderStatus::Codes::kUnsupportedConfig,
51                           "PassthroughDTSAudioDecoder does not support codec"));
52     return;
53   }
54
55   // Success!
56   config_ = config;
57   output_cb_ = base::BindPostTaskToCurrentDefault(output_cb);
58   std::move(bound_init_cb).Run(OkStatus());
59 }
60
61 void PassthroughDTSAudioDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
62                                         DecodeCB decode_cb) {
63   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
64   DCHECK(decode_cb);
65   DecodeCB decode_cb_bound =
66       base::BindPostTaskToCurrentDefault(std::move(decode_cb));
67
68   if (buffer->end_of_stream()) {
69     std::move(decode_cb_bound).Run(DecoderStatus::Codes::kOk);
70     return;
71   }
72
73   ProcessBuffer(*buffer, std::move(decode_cb_bound));
74 }
75
76 void PassthroughDTSAudioDecoder::Reset(base::OnceClosure closure) {
77   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
78
79   task_runner_->PostTask(FROM_HERE, std::move(closure));
80 }
81
82 void PassthroughDTSAudioDecoder::ProcessBuffer(const DecoderBuffer& buffer,
83                                                DecodeCB decode_cb) {
84   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
85
86   // Make sure we are notified if http://crbug.com/49709 returns.  Issue also
87   // occurs with some damaged files.
88   if (!buffer.end_of_stream() && buffer.timestamp() == kNoTimestamp) {
89     DVLOG(1) << "Received a buffer without timestamps!";
90     std::move(decode_cb).Run(DecoderStatus::Codes::kFailed);
91     return;
92   }
93   EncapsulateFrame(buffer);
94
95   std::move(decode_cb).Run(DecoderStatus::Codes::kOk);
96 }
97
98 void PassthroughDTSAudioDecoder::EncapsulateFrame(const DecoderBuffer& buffer) {
99   if (config_.target_output_sample_format() != kSampleFormatDts)
100     return;
101   const size_t samples_per_frame = dts::GetDTSSamplesPerFrame(config_.codec());
102   const size_t dts_frame_size = 2 * 2 * samples_per_frame;
103   std::vector<uint8_t> output_buffer(dts_frame_size);
104
105   // Encapsulated a compressed DTS frame per IEC61937
106   base::span<const uint8_t> input_data;
107   input_data = base::span<const uint8_t>(buffer.data(), buffer.data_size());
108   dts::WrapDTSWithIEC61937(input_data, output_buffer, config_.codec());
109
110   // Create a mono channel "buffer" to hold IEC encapsulated bitstream
111   uint8_t* output_channels[1] = {output_buffer.data()};
112   scoped_refptr<AudioBuffer> output = AudioBuffer::CopyBitstreamFrom(
113       kSampleFormatIECDts, CHANNEL_LAYOUT_MONO, 1, config_.samples_per_second(),
114       samples_per_frame, output_channels, dts_frame_size, buffer.timestamp());
115   output_cb_.Run(output);
116 }
117
118 }  // namespace media