OLD | NEW |
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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 LOG(ERROR) << "Format conversion failed."; | 189 LOG(ERROR) << "Format conversion failed."; |
190 } | 190 } |
191 #endif | 191 #endif |
192 | 192 |
193 // Get side data if any. For now, the only type of side_data is VP8 Alpha. We | 193 // 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 | 194 // keep this generic so that other side_data types in the future can be |
195 // handled the same way as well. | 195 // handled the same way as well. |
196 av_packet_split_side_data(packet.get()); | 196 av_packet_split_side_data(packet.get()); |
197 | 197 |
198 scoped_refptr<DecoderBuffer> buffer; | 198 scoped_refptr<DecoderBuffer> buffer; |
| 199 bool is_keyframe = packet.get()->flags & AV_PKT_FLAG_KEY; |
199 | 200 |
200 if (type() == DemuxerStream::TEXT) { | 201 if (type() == DemuxerStream::TEXT) { |
201 int id_size = 0; | 202 int id_size = 0; |
202 uint8* id_data = av_packet_get_side_data( | 203 uint8* id_data = av_packet_get_side_data( |
203 packet.get(), | 204 packet.get(), |
204 AV_PKT_DATA_WEBVTT_IDENTIFIER, | 205 AV_PKT_DATA_WEBVTT_IDENTIFIER, |
205 &id_size); | 206 &id_size); |
206 | 207 |
207 int settings_size = 0; | 208 int settings_size = 0; |
208 uint8* settings_data = av_packet_get_side_data( | 209 uint8* settings_data = av_packet_get_side_data( |
209 packet.get(), | 210 packet.get(), |
210 AV_PKT_DATA_WEBVTT_SETTINGS, | 211 AV_PKT_DATA_WEBVTT_SETTINGS, |
211 &settings_size); | 212 &settings_size); |
212 | 213 |
213 std::vector<uint8> side_data; | 214 std::vector<uint8> side_data; |
214 MakeSideData(id_data, id_data + id_size, | 215 MakeSideData(id_data, id_data + id_size, |
215 settings_data, settings_data + settings_size, | 216 settings_data, settings_data + settings_size, |
216 &side_data); | 217 &side_data); |
217 | 218 |
218 buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size, | 219 buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size, |
219 side_data.data(), side_data.size()); | 220 side_data.data(), side_data.size(), |
| 221 is_keyframe); |
220 } else { | 222 } else { |
221 int side_data_size = 0; | 223 int side_data_size = 0; |
222 uint8* side_data = av_packet_get_side_data( | 224 uint8* side_data = av_packet_get_side_data( |
223 packet.get(), | 225 packet.get(), |
224 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, | 226 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, |
225 &side_data_size); | 227 &side_data_size); |
226 | 228 |
227 scoped_ptr<DecryptConfig> decrypt_config; | 229 scoped_ptr<DecryptConfig> decrypt_config; |
228 int data_offset = 0; | 230 int data_offset = 0; |
229 if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) || | 231 if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) || |
230 (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) { | 232 (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) { |
231 if (!WebMCreateDecryptConfig( | 233 if (!WebMCreateDecryptConfig( |
232 packet->data, packet->size, | 234 packet->data, packet->size, |
233 reinterpret_cast<const uint8*>(encryption_key_id_.data()), | 235 reinterpret_cast<const uint8*>(encryption_key_id_.data()), |
234 encryption_key_id_.size(), | 236 encryption_key_id_.size(), |
235 &decrypt_config, | 237 &decrypt_config, |
236 &data_offset)) { | 238 &data_offset)) { |
237 LOG(ERROR) << "Creation of DecryptConfig failed."; | 239 LOG(ERROR) << "Creation of DecryptConfig failed."; |
238 } | 240 } |
239 } | 241 } |
240 | 242 |
241 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will | 243 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will |
242 // reference inner memory of FFmpeg. As such we should transfer the packet | 244 // reference inner memory of FFmpeg. As such we should transfer the packet |
243 // into memory we control. | 245 // into memory we control. |
244 if (side_data_size > 0) { | 246 if (side_data_size > 0) { |
245 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset, | 247 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset, |
246 packet.get()->size - data_offset, | 248 packet.get()->size - data_offset, |
247 side_data, side_data_size); | 249 side_data, side_data_size, |
| 250 is_keyframe); |
248 } else { | 251 } else { |
249 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset, | 252 buffer = DecoderBuffer::CopyFrom(packet.get()->data + data_offset, |
250 packet.get()->size - data_offset); | 253 packet.get()->size - data_offset, |
| 254 is_keyframe); |
251 } | 255 } |
252 | 256 |
253 int skip_samples_size = 0; | 257 int skip_samples_size = 0; |
254 const uint32* skip_samples_ptr = | 258 const uint32* skip_samples_ptr = |
255 reinterpret_cast<const uint32*>(av_packet_get_side_data( | 259 reinterpret_cast<const uint32*>(av_packet_get_side_data( |
256 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size)); | 260 packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size)); |
257 const int kSkipSamplesValidSize = 10; | 261 const int kSkipSamplesValidSize = 10; |
258 const int kSkipEndSamplesOffset = 1; | 262 const int kSkipEndSamplesOffset = 1; |
259 if (skip_samples_size >= kSkipSamplesValidSize) { | 263 if (skip_samples_size >= kSkipSamplesValidSize) { |
260 // Because FFmpeg rolls codec delay and skip samples into one we can only | 264 // Because FFmpeg rolls codec delay and skip samples into one we can only |
(...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 } | 1268 } |
1265 for (size_t i = 0; i < buffered.size(); ++i) | 1269 for (size_t i = 0; i < buffered.size(); ++i) |
1266 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); | 1270 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); |
1267 } | 1271 } |
1268 | 1272 |
1269 void FFmpegDemuxer::OnDataSourceError() { | 1273 void FFmpegDemuxer::OnDataSourceError() { |
1270 host_->OnDemuxerError(PIPELINE_ERROR_READ); | 1274 host_->OnDemuxerError(PIPELINE_ERROR_READ); |
1271 } | 1275 } |
1272 | 1276 |
1273 } // namespace media | 1277 } // namespace media |
OLD | NEW |