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

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

Issue 165482: Merge 23038 - Updated decode logic to estimate timestamps if the demuxer has ... (Closed) Base URL: svn://chrome-svn/chrome/branches/195/src/
Patch Set: Created 11 years, 4 months 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 | Annotate | Revision Log
« no previous file with comments | « media/filters/ffmpeg_audio_decoder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:mergeinfo
Merged /branches/chrome_webkit_merge_branch/media/filters/ffmpeg_audio_decoder.cc:r69-2775
Merged /trunk/src/media/filters/ffmpeg_audio_decoder.cc:r23038
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "media/filters/ffmpeg_audio_decoder.h"
6
5 #include "media/base/data_buffer.h" 7 #include "media/base/data_buffer.h"
6 #include "media/filters/ffmpeg_audio_decoder.h"
7 #include "media/filters/ffmpeg_common.h" 8 #include "media/filters/ffmpeg_common.h"
8 #include "media/filters/ffmpeg_demuxer.h" 9 #include "media/filters/ffmpeg_demuxer.h"
9 10
10 namespace media { 11 namespace media {
11 12
12 // Size of the decoded audio buffer. 13 // Size of the decoded audio buffer.
13 const size_t FFmpegAudioDecoder::kOutputBufferSize = 14 const size_t FFmpegAudioDecoder::kOutputBufferSize =
14 AVCODEC_MAX_AUDIO_FRAME_SIZE; 15 AVCODEC_MAX_AUDIO_FRAME_SIZE;
15 16
16 FFmpegAudioDecoder::FFmpegAudioDecoder() 17 FFmpegAudioDecoder::FFmpegAudioDecoder()
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 67
67 // Prepare the output buffer. 68 // Prepare the output buffer.
68 output_buffer_.reset(static_cast<uint8*>(av_malloc(kOutputBufferSize))); 69 output_buffer_.reset(static_cast<uint8*>(av_malloc(kOutputBufferSize)));
69 if (!output_buffer_.get()) { 70 if (!output_buffer_.get()) {
70 host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY); 71 host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
71 return false; 72 return false;
72 } 73 }
73 return true; 74 return true;
74 } 75 }
75 76
77 void FFmpegAudioDecoder::OnSeek(base::TimeDelta time) {
78 avcodec_flush_buffers(codec_context_);
79 estimated_next_timestamp_ = base::TimeDelta();
80 }
81
76 void FFmpegAudioDecoder::OnStop() { 82 void FFmpegAudioDecoder::OnStop() {
77 } 83 }
78 84
79 void FFmpegAudioDecoder::OnDecode(Buffer* input) { 85 void FFmpegAudioDecoder::OnDecode(Buffer* input) {
80 // Check for discontinuous buffer. If we receive a discontinuous buffer here,
81 // flush the internal buffer of FFmpeg.
82 if (input->IsDiscontinuous()) {
83 avcodec_flush_buffers(codec_context_);
84 }
85
86 // Due to FFmpeg API changes we no longer have const read-only pointers. 86 // Due to FFmpeg API changes we no longer have const read-only pointers.
87 AVPacket packet; 87 AVPacket packet;
88 av_init_packet(&packet); 88 av_init_packet(&packet);
89 packet.data = const_cast<uint8*>(input->GetData()); 89 packet.data = const_cast<uint8*>(input->GetData());
90 packet.size = input->GetDataSize(); 90 packet.size = input->GetDataSize();
91 91
92 int16_t* output_buffer = reinterpret_cast<int16_t*>(output_buffer_.get()); 92 int16_t* output_buffer = reinterpret_cast<int16_t*>(output_buffer_.get());
93 int output_buffer_size = kOutputBufferSize; 93 int output_buffer_size = kOutputBufferSize;
94 int result = avcodec_decode_audio3(codec_context_, 94 int result = avcodec_decode_audio3(codec_context_,
95 output_buffer, 95 output_buffer,
(...skipping 17 matching lines...) Expand all
113 memcpy(data, output_buffer, output_buffer_size); 113 memcpy(data, output_buffer, output_buffer_size);
114 114
115 // Determine the duration if the demuxer couldn't figure it out, otherwise 115 // Determine the duration if the demuxer couldn't figure it out, otherwise
116 // copy it over. 116 // copy it over.
117 if (input->GetDuration().InMicroseconds() == 0) { 117 if (input->GetDuration().InMicroseconds() == 0) {
118 result_buffer->SetDuration(CalculateDuration(output_buffer_size)); 118 result_buffer->SetDuration(CalculateDuration(output_buffer_size));
119 } else { 119 } else {
120 result_buffer->SetDuration(input->GetDuration()); 120 result_buffer->SetDuration(input->GetDuration());
121 } 121 }
122 122
123 // Copy over the timestamp. 123 // Use our estimate for the timestamp if |input| does not have one.
124 result_buffer->SetTimestamp(input->GetTimestamp()); 124 // Otherwise, copy over the timestamp.
125 if (input->GetTimestamp().InMicroseconds() == 0) {
126 result_buffer->SetTimestamp(estimated_next_timestamp_);
127 } else {
128 result_buffer->SetTimestamp(input->GetTimestamp());
129 }
130
131 // Update our estimated timestamp for the next packet.
132 estimated_next_timestamp_ = result_buffer->GetTimestamp() +
133 result_buffer->GetDuration();
125 134
126 EnqueueResult(result_buffer); 135 EnqueueResult(result_buffer);
127 return; 136 return;
128 } 137 }
129 138
130 // Three conditions to meet to declare end of stream for this decoder: 139 // Three conditions to meet to declare end of stream for this decoder:
131 // 1. FFmpeg didn't read anything. 140 // 1. FFmpeg didn't read anything.
132 // 2. FFmpeg didn't output anything. 141 // 2. FFmpeg didn't output anything.
133 // 3. An end of stream buffer is received. 142 // 3. An end of stream buffer is received.
134 if (result == 0 && output_buffer_size == 0 && input->IsEndOfStream()) { 143 if (result == 0 && output_buffer_size == 0 && input->IsEndOfStream()) {
135 DataBuffer* result_buffer = new DataBuffer(0); 144 DataBuffer* result_buffer = new DataBuffer(0);
136 result_buffer->SetTimestamp(input->GetTimestamp()); 145 result_buffer->SetTimestamp(input->GetTimestamp());
137 result_buffer->SetDuration(input->GetDuration()); 146 result_buffer->SetDuration(input->GetDuration());
138 EnqueueResult(result_buffer); 147 EnqueueResult(result_buffer);
139 } 148 }
140 } 149 }
141 150
142 base::TimeDelta FFmpegAudioDecoder::CalculateDuration(size_t size) { 151 base::TimeDelta FFmpegAudioDecoder::CalculateDuration(size_t size) {
143 int64 denominator = codec_context_->channels * 152 int64 denominator = codec_context_->channels *
144 av_get_bits_per_sample_format(codec_context_->sample_fmt) / 8 * 153 av_get_bits_per_sample_format(codec_context_->sample_fmt) / 8 *
145 codec_context_->sample_rate; 154 codec_context_->sample_rate;
146 double microseconds = size / 155 double microseconds = size /
147 (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond)); 156 (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond));
148 return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)); 157 return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds));
149 } 158 }
150 159
151 } // namespace 160 } // namespace
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_audio_decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698