OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/cast/test/fake_media_source.h" | 5 #include "media/cast/test/fake_media_source.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/scoped_file.h" | 10 #include "base/files/scoped_file.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 // AVFormatContext is owned by the glue. | 131 // AVFormatContext is owned by the glue. |
132 av_format_context_ = glue_->format_context(); | 132 av_format_context_ = glue_->format_context(); |
133 if (avformat_find_stream_info(av_format_context_, NULL) < 0) { | 133 if (avformat_find_stream_info(av_format_context_, NULL) < 0) { |
134 LOG(ERROR) << "Cannot find stream information."; | 134 LOG(ERROR) << "Cannot find stream information."; |
135 return; | 135 return; |
136 } | 136 } |
137 | 137 |
138 // Prepare FFmpeg decoders. | 138 // Prepare FFmpeg decoders. |
139 for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) { | 139 for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) { |
140 AVStream* av_stream = av_format_context_->streams[i]; | 140 AVStream* av_stream = av_format_context_->streams[i]; |
141 AVCodecContext* av_codec_context = av_stream->codec; | 141 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> av_codec_context( |
| 142 AVStreamToAVCodecContext(av_stream)); |
| 143 if (!av_codec_context) { |
| 144 LOG(ERROR) << "Cannot get a codec context for the codec: " |
| 145 << av_stream->codecpar->codec_id; |
| 146 continue; |
| 147 } |
| 148 |
142 AVCodec* av_codec = avcodec_find_decoder(av_codec_context->codec_id); | 149 AVCodec* av_codec = avcodec_find_decoder(av_codec_context->codec_id); |
143 | 150 |
144 if (!av_codec) { | 151 if (!av_codec) { |
145 LOG(ERROR) << "Cannot find decoder for the codec: " | 152 LOG(ERROR) << "Cannot find decoder for the codec: " |
146 << av_codec_context->codec_id; | 153 << av_codec_context->codec_id; |
147 continue; | 154 continue; |
148 } | 155 } |
149 | 156 |
150 // Number of threads for decoding. | 157 // Number of threads for decoding. |
151 av_codec_context->thread_count = 2; | 158 av_codec_context->thread_count = 2; |
152 av_codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; | 159 av_codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; |
153 av_codec_context->request_sample_fmt = AV_SAMPLE_FMT_S16; | 160 av_codec_context->request_sample_fmt = AV_SAMPLE_FMT_S16; |
154 | 161 |
155 if (avcodec_open2(av_codec_context, av_codec, NULL) < 0) { | 162 if (avcodec_open2(av_codec_context.get(), av_codec, nullptr) < 0) { |
156 LOG(ERROR) << "Cannot open AVCodecContext for the codec: " | 163 LOG(ERROR) << "Cannot open AVCodecContext for the codec: " |
157 << av_codec_context->codec_id; | 164 << av_codec_context->codec_id; |
158 return; | 165 return; |
159 } | 166 } |
160 | 167 |
161 if (av_codec->type == AVMEDIA_TYPE_AUDIO) { | 168 if (av_codec->type == AVMEDIA_TYPE_AUDIO) { |
162 if (av_codec_context->sample_fmt == AV_SAMPLE_FMT_S16P) { | 169 if (av_codec_context->sample_fmt == AV_SAMPLE_FMT_S16P) { |
163 LOG(ERROR) << "Audio format not supported."; | 170 LOG(ERROR) << "Audio format not supported."; |
164 continue; | 171 continue; |
165 } | 172 } |
166 ChannelLayout layout = ChannelLayoutToChromeChannelLayout( | 173 ChannelLayout layout = ChannelLayoutToChromeChannelLayout( |
167 av_codec_context->channel_layout, | 174 av_codec_context->channel_layout, |
168 av_codec_context->channels); | 175 av_codec_context->channels); |
169 if (layout == CHANNEL_LAYOUT_UNSUPPORTED) { | 176 if (layout == CHANNEL_LAYOUT_UNSUPPORTED) { |
170 LOG(ERROR) << "Unsupported audio channels layout."; | 177 LOG(ERROR) << "Unsupported audio channels layout."; |
171 continue; | 178 continue; |
172 } | 179 } |
173 if (audio_stream_index_ != -1) { | 180 if (audio_stream_index_ != -1) { |
174 LOG(WARNING) << "Found multiple audio streams."; | 181 LOG(WARNING) << "Found multiple audio streams."; |
175 } | 182 } |
176 audio_stream_index_ = static_cast<int>(i); | 183 audio_stream_index_ = static_cast<int>(i); |
| 184 av_audio_context_ = std::move(av_codec_context); |
177 source_audio_params_.Reset( | 185 source_audio_params_.Reset( |
178 AudioParameters::AUDIO_PCM_LINEAR, | 186 AudioParameters::AUDIO_PCM_LINEAR, layout, |
179 layout, | 187 av_audio_context_->sample_rate, |
180 av_codec_context->sample_rate, | 188 8 * av_get_bytes_per_sample(av_audio_context_->sample_fmt), |
181 8 * av_get_bytes_per_sample(av_codec_context->sample_fmt), | 189 av_audio_context_->sample_rate / kAudioPacketsPerSecond); |
182 av_codec_context->sample_rate / kAudioPacketsPerSecond); | |
183 source_audio_params_.set_channels_for_discrete( | 190 source_audio_params_.set_channels_for_discrete( |
184 av_codec_context->channels); | 191 av_audio_context_->channels); |
185 CHECK(source_audio_params_.IsValid()); | 192 CHECK(source_audio_params_.IsValid()); |
186 LOG(INFO) << "Source file has audio."; | 193 LOG(INFO) << "Source file has audio."; |
187 } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) { | 194 } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) { |
188 VideoPixelFormat format = | 195 VideoPixelFormat format = |
189 AVPixelFormatToVideoPixelFormat(av_codec_context->pix_fmt); | 196 AVPixelFormatToVideoPixelFormat(av_codec_context->pix_fmt); |
190 if (format != PIXEL_FORMAT_YV12) { | 197 if (format != PIXEL_FORMAT_YV12) { |
191 LOG(ERROR) << "Cannot handle non YV12 video format: " << format; | 198 LOG(ERROR) << "Cannot handle non YV12 video format: " << format; |
192 continue; | 199 continue; |
193 } | 200 } |
194 if (video_stream_index_ != -1) { | 201 if (video_stream_index_ != -1) { |
195 LOG(WARNING) << "Found multiple video streams."; | 202 LOG(WARNING) << "Found multiple video streams."; |
196 } | 203 } |
197 video_stream_index_ = static_cast<int>(i); | 204 video_stream_index_ = static_cast<int>(i); |
| 205 av_video_context_ = std::move(av_codec_context); |
198 if (final_fps > 0) { | 206 if (final_fps > 0) { |
199 // If video is played at a manual speed audio needs to match. | 207 // If video is played at a manual speed audio needs to match. |
200 playback_rate_ = 1.0 * final_fps * | 208 playback_rate_ = 1.0 * final_fps * |
201 av_stream->r_frame_rate.den / av_stream->r_frame_rate.num; | 209 av_stream->r_frame_rate.den / av_stream->r_frame_rate.num; |
202 video_frame_rate_numerator_ = final_fps; | 210 video_frame_rate_numerator_ = final_fps; |
203 video_frame_rate_denominator_ = 1; | 211 video_frame_rate_denominator_ = 1; |
204 } else { | 212 } else { |
205 playback_rate_ = 1.0; | 213 playback_rate_ = 1.0; |
206 video_frame_rate_numerator_ = av_stream->r_frame_rate.num; | 214 video_frame_rate_numerator_ = av_stream->r_frame_rate.num; |
207 video_frame_rate_denominator_ = av_stream->r_frame_rate.den; | 215 video_frame_rate_denominator_ = av_stream->r_frame_rate.den; |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 void FakeMediaSource::DecodeAudio(ScopedAVPacket packet) { | 457 void FakeMediaSource::DecodeAudio(ScopedAVPacket packet) { |
450 // Audio. | 458 // Audio. |
451 AVFrame* avframe = av_frame_alloc(); | 459 AVFrame* avframe = av_frame_alloc(); |
452 | 460 |
453 // Make a shallow copy of packet so we can slide packet.data as frames are | 461 // Make a shallow copy of packet so we can slide packet.data as frames are |
454 // decoded from the packet; otherwise av_packet_unref() will corrupt memory. | 462 // decoded from the packet; otherwise av_packet_unref() will corrupt memory. |
455 AVPacket packet_temp = *packet.get(); | 463 AVPacket packet_temp = *packet.get(); |
456 | 464 |
457 do { | 465 do { |
458 int frame_decoded = 0; | 466 int frame_decoded = 0; |
459 int result = avcodec_decode_audio4( | 467 int result = avcodec_decode_audio4(av_audio_context_.get(), avframe, |
460 av_audio_context(), avframe, &frame_decoded, &packet_temp); | 468 &frame_decoded, &packet_temp); |
461 CHECK(result >= 0) << "Failed to decode audio."; | 469 CHECK(result >= 0) << "Failed to decode audio."; |
462 packet_temp.size -= result; | 470 packet_temp.size -= result; |
463 packet_temp.data += result; | 471 packet_temp.data += result; |
464 if (!frame_decoded) | 472 if (!frame_decoded) |
465 continue; | 473 continue; |
466 | 474 |
467 int frames_read = avframe->nb_samples; | 475 int frames_read = avframe->nb_samples; |
468 if (frames_read < 0) | 476 if (frames_read < 0) |
469 break; | 477 break; |
470 | 478 |
471 if (!audio_sent_ts_) { | 479 if (!audio_sent_ts_) { |
472 // Initialize the base time to the first packet in the file. | 480 // Initialize the base time to the first packet in the file. |
473 // This is set to the frequency we send to the receiver. | 481 // This is set to the frequency we send to the receiver. |
474 // Not the frequency of the source file. This is because we | 482 // Not the frequency of the source file. This is because we |
475 // increment the frame count by samples we sent. | 483 // increment the frame count by samples we sent. |
476 audio_sent_ts_.reset( | 484 audio_sent_ts_.reset( |
477 new AudioTimestampHelper(output_audio_params_.sample_rate())); | 485 new AudioTimestampHelper(output_audio_params_.sample_rate())); |
478 // For some files this is an invalid value. | 486 // For some files this is an invalid value. |
479 base::TimeDelta base_ts; | 487 base::TimeDelta base_ts; |
480 audio_sent_ts_->SetBaseTimestamp(base_ts); | 488 audio_sent_ts_->SetBaseTimestamp(base_ts); |
481 } | 489 } |
482 | 490 |
483 scoped_refptr<AudioBuffer> buffer = AudioBuffer::CopyFrom( | 491 scoped_refptr<AudioBuffer> buffer = AudioBuffer::CopyFrom( |
484 AVSampleFormatToSampleFormat(av_audio_context()->sample_fmt, | 492 AVSampleFormatToSampleFormat(av_audio_context_->sample_fmt, |
485 av_audio_context()->codec_id), | 493 av_audio_context_->codec_id), |
486 ChannelLayoutToChromeChannelLayout(av_audio_context()->channel_layout, | 494 ChannelLayoutToChromeChannelLayout(av_audio_context_->channel_layout, |
487 av_audio_context()->channels), | 495 av_audio_context_->channels), |
488 av_audio_context()->channels, av_audio_context()->sample_rate, | 496 av_audio_context_->channels, av_audio_context_->sample_rate, |
489 frames_read, &avframe->data[0], | 497 frames_read, &avframe->data[0], |
490 PtsToTimeDelta(avframe->pkt_pts, av_audio_stream()->time_base)); | 498 PtsToTimeDelta(avframe->pts, av_audio_stream()->time_base)); |
491 audio_algo_.EnqueueBuffer(buffer); | 499 audio_algo_.EnqueueBuffer(buffer); |
492 av_frame_unref(avframe); | 500 av_frame_unref(avframe); |
493 } while (packet_temp.size > 0); | 501 } while (packet_temp.size > 0); |
494 av_frame_free(&avframe); | 502 av_frame_free(&avframe); |
495 | 503 |
496 const int frames_needed_to_scale = | 504 const int frames_needed_to_scale = |
497 playback_rate_ * av_audio_context()->sample_rate / | 505 playback_rate_ * av_audio_context_->sample_rate / kAudioPacketsPerSecond; |
498 kAudioPacketsPerSecond; | |
499 while (frames_needed_to_scale <= audio_algo_.frames_buffered()) { | 506 while (frames_needed_to_scale <= audio_algo_.frames_buffered()) { |
500 if (!audio_algo_.FillBuffer(audio_fifo_input_bus_.get(), 0, | 507 if (!audio_algo_.FillBuffer(audio_fifo_input_bus_.get(), 0, |
501 audio_fifo_input_bus_->frames(), | 508 audio_fifo_input_bus_->frames(), |
502 playback_rate_)) { | 509 playback_rate_)) { |
503 // Nothing can be scaled. Decode some more. | 510 // Nothing can be scaled. Decode some more. |
504 return; | 511 return; |
505 } | 512 } |
506 | 513 |
507 // Prevent overflow of audio data in the FIFO. | 514 // Prevent overflow of audio data in the FIFO. |
508 if (audio_fifo_input_bus_->frames() + audio_fifo_->frames() | 515 if (audio_fifo_input_bus_->frames() + audio_fifo_->frames() |
(...skipping 14 matching lines...) Expand all Loading... |
523 output_audio_params_.sample_rate() / kAudioPacketsPerSecond)); | 530 output_audio_params_.sample_rate() / kAudioPacketsPerSecond)); |
524 audio_converter_->Convert(resampled_bus.get()); | 531 audio_converter_->Convert(resampled_bus.get()); |
525 audio_bus_queue_.push(resampled_bus.release()); | 532 audio_bus_queue_.push(resampled_bus.release()); |
526 } | 533 } |
527 } | 534 } |
528 | 535 |
529 void FakeMediaSource::DecodeVideo(ScopedAVPacket packet) { | 536 void FakeMediaSource::DecodeVideo(ScopedAVPacket packet) { |
530 // Video. | 537 // Video. |
531 int got_picture; | 538 int got_picture; |
532 AVFrame* avframe = av_frame_alloc(); | 539 AVFrame* avframe = av_frame_alloc(); |
533 CHECK(avcodec_decode_video2( | 540 CHECK(avcodec_decode_video2(av_video_context_.get(), avframe, &got_picture, |
534 av_video_context(), avframe, &got_picture, packet.get()) >= 0) | 541 packet.get()) >= 0) |
535 << "Video decode error."; | 542 << "Video decode error."; |
536 if (!got_picture) { | 543 if (!got_picture) { |
537 av_frame_free(&avframe); | 544 av_frame_free(&avframe); |
538 return; | 545 return; |
539 } | 546 } |
540 gfx::Size size(av_video_context()->width, av_video_context()->height); | 547 gfx::Size size(av_video_context_->width, av_video_context_->height); |
541 | 548 |
542 if (!video_first_pts_set_) { | 549 if (!video_first_pts_set_) { |
543 video_first_pts_ = avframe->pkt_pts; | 550 video_first_pts_ = avframe->pts; |
544 video_first_pts_set_ = true; | 551 video_first_pts_set_ = true; |
545 } | 552 } |
546 const AVRational& time_base = av_video_stream()->time_base; | 553 const AVRational& time_base = av_video_stream()->time_base; |
547 base::TimeDelta timestamp = | 554 base::TimeDelta timestamp = |
548 PtsToTimeDelta(avframe->pkt_pts - video_first_pts_, time_base); | 555 PtsToTimeDelta(avframe->pts - video_first_pts_, time_base); |
549 if (timestamp < last_video_frame_timestamp_) { | 556 if (timestamp < last_video_frame_timestamp_) { |
550 // Stream has rewound. Rebase |video_first_pts_|. | 557 // Stream has rewound. Rebase |video_first_pts_|. |
551 const AVRational& frame_rate = av_video_stream()->r_frame_rate; | 558 const AVRational& frame_rate = av_video_stream()->r_frame_rate; |
552 timestamp = last_video_frame_timestamp_ + | 559 timestamp = last_video_frame_timestamp_ + |
553 (base::TimeDelta::FromSeconds(1) * frame_rate.den / frame_rate.num); | 560 (base::TimeDelta::FromSeconds(1) * frame_rate.den / frame_rate.num); |
554 const int64_t adjustment_pts = TimeDeltaToPts(timestamp, time_base); | 561 const int64_t adjustment_pts = TimeDeltaToPts(timestamp, time_base); |
555 video_first_pts_ = avframe->pkt_pts - adjustment_pts; | 562 video_first_pts_ = avframe->pts - adjustment_pts; |
556 } | 563 } |
557 | 564 |
558 scoped_refptr<media::VideoFrame> video_frame = | 565 scoped_refptr<media::VideoFrame> video_frame = |
559 VideoFrame::WrapExternalYuvData( | 566 VideoFrame::WrapExternalYuvData( |
560 media::PIXEL_FORMAT_YV12, size, gfx::Rect(size), size, | 567 media::PIXEL_FORMAT_YV12, size, gfx::Rect(size), size, |
561 avframe->linesize[0], avframe->linesize[1], avframe->linesize[2], | 568 avframe->linesize[0], avframe->linesize[1], avframe->linesize[2], |
562 avframe->data[0], avframe->data[1], avframe->data[2], timestamp); | 569 avframe->data[0], avframe->data[1], avframe->data[2], timestamp); |
563 if (!video_frame) | 570 if (!video_frame) |
564 return; | 571 return; |
565 video_frame_queue_.push(video_frame); | 572 video_frame_queue_.push(video_frame); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 } | 619 } |
613 | 620 |
614 AVStream* FakeMediaSource::av_audio_stream() { | 621 AVStream* FakeMediaSource::av_audio_stream() { |
615 return av_format_context_->streams[audio_stream_index_]; | 622 return av_format_context_->streams[audio_stream_index_]; |
616 } | 623 } |
617 | 624 |
618 AVStream* FakeMediaSource::av_video_stream() { | 625 AVStream* FakeMediaSource::av_video_stream() { |
619 return av_format_context_->streams[video_stream_index_]; | 626 return av_format_context_->streams[video_stream_index_]; |
620 } | 627 } |
621 | 628 |
622 AVCodecContext* FakeMediaSource::av_audio_context() { | |
623 return av_audio_stream()->codec; | |
624 } | |
625 | |
626 AVCodecContext* FakeMediaSource::av_video_context() { | |
627 return av_video_stream()->codec; | |
628 } | |
629 | |
630 } // namespace cast | 629 } // namespace cast |
631 } // namespace media | 630 } // namespace media |
OLD | NEW |