| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "services/media/framework_ffmpeg/ffmpeg_audio_decoder.h" | 6 #include "services/media/framework_ffmpeg/ffmpeg_audio_decoder.h" |
| 7 | 7 |
| 8 namespace mojo { | 8 namespace mojo { |
| 9 namespace media { | 9 namespace media { |
| 10 | 10 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 DCHECK(allocator); | 70 DCHECK(allocator); |
| 71 | 71 |
| 72 int64_t pts = av_frame.pts; | 72 int64_t pts = av_frame.pts; |
| 73 if (pts == AV_NOPTS_VALUE) { | 73 if (pts == AV_NOPTS_VALUE) { |
| 74 pts = next_pts_; | 74 pts = next_pts_; |
| 75 next_pts_ += av_frame.nb_samples; | 75 next_pts_ += av_frame.nb_samples; |
| 76 } else { | 76 } else { |
| 77 next_pts_ = pts; | 77 next_pts_ = pts; |
| 78 } | 78 } |
| 79 | 79 |
| 80 uint64_t payload_size; | |
| 81 void* payload_buffer; | |
| 82 | |
| 83 AvBufferContext* av_buffer_context = | |
| 84 reinterpret_cast<AvBufferContext*>(av_buffer_get_opaque(av_frame.buf[0])); | |
| 85 | |
| 86 if (lpcm_util_) { | 80 if (lpcm_util_) { |
| 87 // We need to interleave. The non-interleaved frames are in a buffer that | 81 // We need to interleave. The non-interleaved frames are in a buffer that |
| 88 // was allocated from the default allocator. That buffer will get released | 82 // was allocated from the default allocator. That buffer will get released |
| 89 // later in ReleaseBufferForAvFrame. We need a new buffer for the | 83 // later in ReleaseBufferForAvFrame. We need a new buffer for the |
| 90 // interleaved frames, which we get from the provided allocator. | 84 // interleaved frames, which we get from the provided allocator. |
| 91 DCHECK(stream_type_); | 85 DCHECK(stream_type_); |
| 92 DCHECK(stream_type_->audio()); | 86 DCHECK(stream_type_->audio()); |
| 93 payload_size = stream_type_->audio()->min_buffer_size(av_frame.nb_samples); | 87 uint64_t payload_size = |
| 94 payload_buffer = allocator->AllocatePayloadBuffer(payload_size); | 88 stream_type_->audio()->min_buffer_size(av_frame.nb_samples); |
| 89 void* payload_buffer = allocator->AllocatePayloadBuffer(payload_size); |
| 95 | 90 |
| 96 lpcm_util_->Interleave(av_buffer_context->buffer(), | 91 lpcm_util_->Interleave(av_frame.buf[0]->data, av_frame.buf[0]->size, |
| 97 av_buffer_context->size(), payload_buffer, | 92 payload_buffer, av_frame.nb_samples); |
| 98 av_frame.nb_samples); | 93 |
| 94 return Packet::Create( |
| 95 pts, |
| 96 false, // The base class is responsible for end-of-stream. |
| 97 payload_size, payload_buffer, allocator); |
| 99 } else { | 98 } else { |
| 100 // We don't need to interleave. The interleaved frames are in a buffer that | 99 // We don't need to interleave. The interleaved frames are in a buffer that |
| 101 // was allocated from the correct allocator. We take ownership of the buffer | 100 // was allocated from the correct allocator. |
| 102 // by calling Release here so that ReleaseBufferForAvFrame won't release it. | 101 return DecoderPacket::Create(pts, av_buffer_ref(av_frame.buf[0])); |
| 103 payload_size = av_buffer_context->size(); | |
| 104 payload_buffer = av_buffer_context->Release(); | |
| 105 } | 102 } |
| 106 | |
| 107 return Packet::Create( | |
| 108 pts, | |
| 109 false, // The base class is responsible for end-of-stream. | |
| 110 payload_size, payload_buffer, allocator); | |
| 111 } | 103 } |
| 112 | 104 |
| 113 PacketPtr FfmpegAudioDecoder::CreateOutputEndOfStreamPacket() { | 105 PacketPtr FfmpegAudioDecoder::CreateOutputEndOfStreamPacket() { |
| 114 return Packet::CreateEndOfStream(next_pts_); | 106 return Packet::CreateEndOfStream(next_pts_); |
| 115 } | 107 } |
| 116 | 108 |
| 117 int FfmpegAudioDecoder::AllocateBufferForAvFrame( | 109 int FfmpegAudioDecoder::AllocateBufferForAvFrame( |
| 118 AVCodecContext* av_codec_context, | 110 AVCodecContext* av_codec_context, |
| 119 AVFrame* av_frame, | 111 AVFrame* av_frame, |
| 120 int flags) { | 112 int flags) { |
| 121 // CODEC_CAP_DR1 is required in order to do allocation this way. | 113 // CODEC_CAP_DR1 is required in order to do allocation this way. |
| 122 DCHECK(av_codec_context->codec->capabilities & CODEC_CAP_DR1); | 114 DCHECK(av_codec_context->codec->capabilities & CODEC_CAP_DR1); |
| 123 | 115 |
| 124 FfmpegAudioDecoder* self = | 116 FfmpegAudioDecoder* self = |
| 125 reinterpret_cast<FfmpegAudioDecoder*>(av_codec_context->opaque); | 117 reinterpret_cast<FfmpegAudioDecoder*>(av_codec_context->opaque); |
| 126 DCHECK(self); | 118 DCHECK(self); |
| 127 DCHECK(self->allocator_); | 119 DCHECK(self->allocator_); |
| 128 | 120 |
| 129 AVSampleFormat av_sample_format = | 121 AVSampleFormat av_sample_format = |
| 130 static_cast<AVSampleFormat>(av_frame->format); | 122 static_cast<AVSampleFormat>(av_frame->format); |
| 131 | 123 |
| 132 int buffer_size = av_samples_get_buffer_size( | 124 int buffer_size = av_samples_get_buffer_size( |
| 133 &av_frame->linesize[0], av_codec_context->channels, av_frame->nb_samples, | 125 &av_frame->linesize[0], av_codec_context->channels, av_frame->nb_samples, |
| 134 av_sample_format, FfmpegAudioDecoder::kChannelAlign); | 126 av_sample_format, FfmpegAudioDecoder::kChannelAlign); |
| 135 if (buffer_size < 0) { | 127 if (buffer_size < 0) { |
| 136 LOG(WARNING) << "av_samples_get_buffer_size failed"; | 128 LOG(WARNING) << "av_samples_get_buffer_size failed"; |
| 137 return buffer_size; | 129 return buffer_size; |
| 138 } | 130 } |
| 139 | 131 |
| 140 AvBufferContext* av_buffer_context = | 132 uint8_t* buffer = static_cast<uint8_t*>( |
| 141 new AvBufferContext(buffer_size, self->allocator_); | 133 self->allocator_->AllocatePayloadBuffer(buffer_size)); |
| 142 uint8_t* buffer = av_buffer_context->buffer(); | |
| 143 | 134 |
| 144 if (!av_sample_fmt_is_planar(av_sample_format)) { | 135 if (!av_sample_fmt_is_planar(av_sample_format)) { |
| 145 // Samples are interleaved. There's just one buffer. | 136 // Samples are interleaved. There's just one buffer. |
| 146 av_frame->data[0] = buffer; | 137 av_frame->data[0] = buffer; |
| 147 } else { | 138 } else { |
| 148 // Samples are not interleaved. There's one buffer per channel. | 139 // Samples are not interleaved. There's one buffer per channel. |
| 149 int channels = av_codec_context->channels; | 140 int channels = av_codec_context->channels; |
| 150 int bytes_per_channel = buffer_size / channels; | 141 int bytes_per_channel = buffer_size / channels; |
| 151 uint8_t* channel_buffer = buffer; | 142 uint8_t* channel_buffer = buffer; |
| 152 | 143 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 174 } | 165 } |
| 175 | 166 |
| 176 // The rest go only in extended_data. | 167 // The rest go only in extended_data. |
| 177 for (; channel < channels; ++channel) { | 168 for (; channel < channels; ++channel) { |
| 178 av_frame->extended_data[channel] = channel_buffer; | 169 av_frame->extended_data[channel] = channel_buffer; |
| 179 channel_buffer += bytes_per_channel; | 170 channel_buffer += bytes_per_channel; |
| 180 } | 171 } |
| 181 } | 172 } |
| 182 } | 173 } |
| 183 | 174 |
| 184 av_frame->buf[0] = av_buffer_create( | 175 av_frame->buf[0] = av_buffer_create(buffer, buffer_size, |
| 185 buffer, buffer_size, ReleaseBufferForAvFrame, av_buffer_context, | 176 ReleaseBufferForAvFrame, self->allocator_, |
| 186 0); // flags | 177 0); // flags |
| 187 | 178 |
| 188 return 0; | 179 return 0; |
| 189 } | 180 } |
| 190 | 181 |
| 191 void FfmpegAudioDecoder::ReleaseBufferForAvFrame(void* opaque, | 182 void FfmpegAudioDecoder::ReleaseBufferForAvFrame(void* opaque, |
| 192 uint8_t* buffer) { | 183 uint8_t* buffer) { |
| 193 AvBufferContext* av_buffer_context = | 184 DCHECK(opaque); |
| 194 reinterpret_cast<AvBufferContext*>(opaque); | 185 DCHECK(buffer); |
| 195 DCHECK(av_buffer_context); | 186 PayloadAllocator* allocator = reinterpret_cast<PayloadAllocator*>(opaque); |
| 196 // Either this buffer has already been released to someone else's ownership, | 187 allocator->ReleasePayloadBuffer(buffer); |
| 197 // or it's the same as the buffer parameter. | |
| 198 DCHECK(av_buffer_context->buffer() == nullptr || | |
| 199 av_buffer_context->buffer() == buffer); | |
| 200 delete av_buffer_context; | |
| 201 } | 188 } |
| 202 | 189 |
| 203 } // namespace media | 190 } // namespace media |
| 204 } // namespace mojo | 191 } // namespace mojo |
| OLD | NEW |