Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: media/filters/ffmpeg_demuxer.cc

Issue 691233002: Added aac bitstream converter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Figured it out Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/filters/ffmpeg_demuxer.h" 5 #include "media/filters/ffmpeg_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
(...skipping 10 matching lines...) Expand all
21 #include "base/task_runner_util.h" 21 #include "base/task_runner_util.h"
22 #include "base/time/time.h" 22 #include "base/time/time.h"
23 #include "media/base/audio_decoder_config.h" 23 #include "media/base/audio_decoder_config.h"
24 #include "media/base/bind_to_current_loop.h" 24 #include "media/base/bind_to_current_loop.h"
25 #include "media/base/decoder_buffer.h" 25 #include "media/base/decoder_buffer.h"
26 #include "media/base/decrypt_config.h" 26 #include "media/base/decrypt_config.h"
27 #include "media/base/limits.h" 27 #include "media/base/limits.h"
28 #include "media/base/media_log.h" 28 #include "media/base/media_log.h"
29 #include "media/base/video_decoder_config.h" 29 #include "media/base/video_decoder_config.h"
30 #include "media/ffmpeg/ffmpeg_common.h" 30 #include "media/ffmpeg/ffmpeg_common.h"
31 #include "media/filters/ffmpeg_aac_bitstream_converter.h"
32 #include "media/filters/ffmpeg_bitstream_converter.h"
31 #include "media/filters/ffmpeg_glue.h" 33 #include "media/filters/ffmpeg_glue.h"
32 #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h" 34 #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h"
33 #include "media/filters/webvtt_util.h" 35 #include "media/filters/webvtt_util.h"
34 #include "media/formats/webm/webm_crypto_helpers.h" 36 #include "media/formats/webm/webm_crypto_helpers.h"
35 37
36 namespace media { 38 namespace media {
37 39
38 static base::Time ExtractTimelineOffset(AVFormatContext* format_context) { 40 static base::Time ExtractTimelineOffset(AVFormatContext* format_context) {
39 if (strstr(format_context->iformat->name, "webm") || 41 if (strstr(format_context->iformat->name, "webm") ||
40 strstr(format_context->iformat->name, "matroska")) { 42 strstr(format_context->iformat->name, "matroska")) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer, 90 FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer,
89 AVStream* stream) 91 AVStream* stream)
90 : demuxer_(demuxer), 92 : demuxer_(demuxer),
91 task_runner_(base::MessageLoopProxy::current()), 93 task_runner_(base::MessageLoopProxy::current()),
92 stream_(stream), 94 stream_(stream),
93 type_(UNKNOWN), 95 type_(UNKNOWN),
94 end_of_stream_(false), 96 end_of_stream_(false),
95 last_packet_timestamp_(kNoTimestamp()), 97 last_packet_timestamp_(kNoTimestamp()),
96 last_packet_duration_(kNoTimestamp()), 98 last_packet_duration_(kNoTimestamp()),
97 video_rotation_(VIDEO_ROTATION_0), 99 video_rotation_(VIDEO_ROTATION_0),
98 bitstream_converter_enabled_(false),
99 fixup_negative_ogg_timestamps_(false) { 100 fixup_negative_ogg_timestamps_(false) {
100 DCHECK(demuxer_); 101 DCHECK(demuxer_);
101 102
102 bool is_encrypted = false; 103 bool is_encrypted = false;
103 int rotation = 0; 104 int rotation = 0;
104 AVDictionaryEntry* rotation_entry = NULL; 105 AVDictionaryEntry* rotation_entry = NULL;
105 106
106 // Determine our media format. 107 // Determine our media format.
107 switch (stream->codec->codec_type) { 108 switch (stream->codec->codec_type) {
108 case AVMEDIA_TYPE_AUDIO: 109 case AVMEDIA_TYPE_AUDIO:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 type_ = TEXT; 142 type_ = TEXT;
142 break; 143 break;
143 default: 144 default:
144 NOTREACHED(); 145 NOTREACHED();
145 break; 146 break;
146 } 147 }
147 148
148 // Calculate the duration. 149 // Calculate the duration.
149 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration); 150 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
150 151
151 #if defined(USE_PROPRIETARY_CODECS)
152 if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
153 bitstream_converter_.reset(
154 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
155 }
156 #endif
157
158 if (is_encrypted) { 152 if (is_encrypted) {
159 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL, 153 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL,
160 0); 154 0);
161 DCHECK(key); 155 DCHECK(key);
162 DCHECK(key->value); 156 DCHECK(key->value);
163 if (!key || !key->value) 157 if (!key || !key->value)
164 return; 158 return;
165 base::StringPiece base64_key_id(key->value); 159 base::StringPiece base64_key_id(key->value);
166 std::string enc_key_id; 160 std::string enc_key_id;
167 base::Base64Decode(base64_key_id, &enc_key_id); 161 base::Base64Decode(base64_key_id, &enc_key_id);
168 DCHECK(!enc_key_id.empty()); 162 DCHECK(!enc_key_id.empty());
169 if (enc_key_id.empty()) 163 if (enc_key_id.empty())
170 return; 164 return;
171 165
172 encryption_key_id_.assign(enc_key_id); 166 encryption_key_id_.assign(enc_key_id);
173 demuxer_->FireNeedKey(kWebMInitDataType, enc_key_id); 167 demuxer_->FireNeedKey(kWebMInitDataType, enc_key_id);
174 } 168 }
175 } 169 }
176 170
177 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) { 171 void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
178 DCHECK(task_runner_->BelongsToCurrentThread()); 172 DCHECK(task_runner_->BelongsToCurrentThread());
179 173
180 if (!demuxer_ || end_of_stream_) { 174 if (!demuxer_ || end_of_stream_) {
181 NOTREACHED() << "Attempted to enqueue packet on a stopped stream"; 175 NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
182 return; 176 return;
183 } 177 }
184 178
185 #if defined(USE_PROPRIETARY_CODECS) 179 #if defined(USE_PROPRIETARY_CODECS)
186 // Convert the packet if there is a bitstream filter. 180 // Convert the packet if there is a bitstream filter.
187 if (packet->data && bitstream_converter_enabled_ && 181 if (packet->data && bitstream_converter_ &&
188 !bitstream_converter_->ConvertPacket(packet.get())) { 182 !bitstream_converter_->ConvertPacket(packet.get())) {
189 LOG(ERROR) << "Format conversion failed."; 183 LOG(ERROR) << "Format conversion failed.";
190 } 184 }
191 #endif 185 #endif
192 186
193 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We 187 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
194 // keep this generic so that other side_data types in the future can be 188 // keep this generic so that other side_data types in the future can be
195 // handled the same way as well. 189 // handled the same way as well.
196 av_packet_split_side_data(packet.get()); 190 av_packet_split_side_data(packet.get());
197 191
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 void FFmpegDemuxerStream::SetEndOfStream() { 370 void FFmpegDemuxerStream::SetEndOfStream() {
377 DCHECK(task_runner_->BelongsToCurrentThread()); 371 DCHECK(task_runner_->BelongsToCurrentThread());
378 end_of_stream_ = true; 372 end_of_stream_ = true;
379 SatisfyPendingRead(); 373 SatisfyPendingRead();
380 } 374 }
381 375
382 void FFmpegDemuxerStream::FlushBuffers() { 376 void FFmpegDemuxerStream::FlushBuffers() {
383 DCHECK(task_runner_->BelongsToCurrentThread()); 377 DCHECK(task_runner_->BelongsToCurrentThread());
384 DCHECK(read_cb_.is_null()) << "There should be no pending read"; 378 DCHECK(read_cb_.is_null()) << "There should be no pending read";
385 379
386 // H264 requires that we resend the header after flush. 380 // H264 and AAC require that we resend the header after flush.
387 // Reset its bitstream for converter to do so. 381 // Reset bitstream for converter to do so.
388 // This is related to chromium issue 140371 (http://crbug.com/140371). 382 // This is related to chromium issue 140371 (http://crbug.com/140371).
389 ResetBitstreamConverter(); 383 ResetBitstreamConverter();
390 384
391 buffer_queue_.Clear(); 385 buffer_queue_.Clear();
392 end_of_stream_ = false; 386 end_of_stream_ = false;
393 last_packet_timestamp_ = kNoTimestamp(); 387 last_packet_timestamp_ = kNoTimestamp();
394 last_packet_duration_ = kNoTimestamp(); 388 last_packet_duration_ = kNoTimestamp();
395 } 389 }
396 390
397 void FFmpegDemuxerStream::Stop() { 391 void FFmpegDemuxerStream::Stop() {
(...skipping 28 matching lines...) Expand all
426 return; 420 return;
427 } 421 }
428 422
429 SatisfyPendingRead(); 423 SatisfyPendingRead();
430 } 424 }
431 425
432 void FFmpegDemuxerStream::EnableBitstreamConverter() { 426 void FFmpegDemuxerStream::EnableBitstreamConverter() {
433 DCHECK(task_runner_->BelongsToCurrentThread()); 427 DCHECK(task_runner_->BelongsToCurrentThread());
434 428
435 #if defined(USE_PROPRIETARY_CODECS) 429 #if defined(USE_PROPRIETARY_CODECS)
436 CHECK(bitstream_converter_.get()); 430 InitBitstreamConverter();
437 bitstream_converter_enabled_ = true;
438 #else 431 #else
439 NOTREACHED() << "Proprietary codecs not enabled."; 432 NOTREACHED() << "Proprietary codecs not enabled.";
440 #endif 433 #endif
441 } 434 }
442 435
443 void FFmpegDemuxerStream::ResetBitstreamConverter() { 436 void FFmpegDemuxerStream::ResetBitstreamConverter() {
444 #if defined(USE_PROPRIETARY_CODECS) 437 #if defined(USE_PROPRIETARY_CODECS)
445 if (!bitstream_converter_enabled_ || !bitstream_converter_) 438 if (bitstream_converter_)
446 return; 439 InitBitstreamConverter();
447
448 bitstream_converter_.reset(
449 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
450 #endif // defined(USE_PROPRIETARY_CODECS) 440 #endif // defined(USE_PROPRIETARY_CODECS)
451 } 441 }
452 442
443 void FFmpegDemuxerStream::InitBitstreamConverter() {
444 #if defined(USE_PROPRIETARY_CODECS)
445 if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
446 bitstream_converter_.reset(
447 new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
448 } else if (stream_->codec->codec_id == AV_CODEC_ID_AAC) {
449 bitstream_converter_.reset(
450 new FFmpegAACBitstreamConverter(stream_->codec));
451 }
452 #endif // defined(USE_PROPRIETARY_CODECS)
453 }
454
453 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; } 455 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
454 456
455 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() { 457 AudioDecoderConfig FFmpegDemuxerStream::audio_decoder_config() {
456 DCHECK(task_runner_->BelongsToCurrentThread()); 458 DCHECK(task_runner_->BelongsToCurrentThread());
457 CHECK_EQ(type_, AUDIO); 459 CHECK_EQ(type_, AUDIO);
458 return audio_config_; 460 return audio_config_;
459 } 461 }
460 462
461 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() { 463 VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {
462 DCHECK(task_runner_->BelongsToCurrentThread()); 464 DCHECK(task_runner_->BelongsToCurrentThread());
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 } 1266 }
1265 for (size_t i = 0; i < buffered.size(); ++i) 1267 for (size_t i = 0; i < buffered.size(); ++i)
1266 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); 1268 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
1267 } 1269 }
1268 1270
1269 void FFmpegDemuxer::OnDataSourceError() { 1271 void FFmpegDemuxer::OnDataSourceError() {
1270 host_->OnDemuxerError(PIPELINE_ERROR_READ); 1272 host_->OnDemuxerError(PIPELINE_ERROR_READ);
1271 } 1273 }
1272 1274
1273 } // namespace media 1275 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698