| 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 "media/filters/media_source_state.h" | 5 #include "media/filters/media_source_state.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/stl_util.h" | |
| 12 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 13 #include "media/base/media_switches.h" | 12 #include "media/base/media_switches.h" |
| 14 #include "media/base/media_track.h" | 13 #include "media/base/media_track.h" |
| 15 #include "media/base/media_tracks.h" | 14 #include "media/base/media_tracks.h" |
| 16 #include "media/base/mime_util.h" | 15 #include "media/base/mime_util.h" |
| 17 #include "media/filters/chunk_demuxer.h" | 16 #include "media/filters/chunk_demuxer.h" |
| 18 #include "media/filters/frame_processor.h" | 17 #include "media/filters/frame_processor.h" |
| 19 #include "media/filters/source_buffer_stream.h" | 18 #include "media/filters/source_buffer_stream.h" |
| 20 | 19 |
| 21 namespace media { | 20 namespace media { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 } // namespace | 58 } // namespace |
| 60 | 59 |
| 61 // List of time ranges for each SourceBuffer. | 60 // List of time ranges for each SourceBuffer. |
| 62 // static | 61 // static |
| 63 Ranges<TimeDelta> MediaSourceState::ComputeRangesIntersection( | 62 Ranges<TimeDelta> MediaSourceState::ComputeRangesIntersection( |
| 64 const RangesList& active_ranges, | 63 const RangesList& active_ranges, |
| 65 bool ended) { | 64 bool ended) { |
| 66 // TODO(servolk): Perhaps this can be removed in favor of blink implementation | 65 // TODO(servolk): Perhaps this can be removed in favor of blink implementation |
| 67 // (MediaSource::buffered)? Currently this is only used on Android and for | 66 // (MediaSource::buffered)? Currently this is only used on Android and for |
| 68 // updating DemuxerHost's buffered ranges during AppendData() as well as | 67 // updating DemuxerHost's buffered ranges during AppendData() as well as |
| 69 // SourceBuffer.buffered property implemetation. | 68 // SourceBuffer.buffered property implementation. |
| 70 // Implementation of HTMLMediaElement.buffered algorithm in MSE spec. | 69 // Implementation of HTMLMediaElement.buffered algorithm in MSE spec. |
| 71 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sourc
e.html#dom-htmlmediaelement.buffered | 70 // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-sourc
e.html#dom-htmlmediaelement.buffered |
| 72 | 71 |
| 73 // Step 1: If activeSourceBuffers.length equals 0 then return an empty | 72 // Step 1: If activeSourceBuffers.length equals 0 then return an empty |
| 74 // TimeRanges object and abort these steps. | 73 // TimeRanges object and abort these steps. |
| 75 if (active_ranges.empty()) | 74 if (active_ranges.empty()) |
| 76 return Ranges<TimeDelta>(); | 75 return Ranges<TimeDelta>(); |
| 77 | 76 |
| 78 // Step 2: Let active ranges be the ranges returned by buffered for each | 77 // Step 2: Let active ranges be the ranges returned by buffered for each |
| 79 // SourceBuffer object in activeSourceBuffers. | 78 // SourceBuffer object in activeSourceBuffers. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 frame_processor_(frame_processor.release()), | 127 frame_processor_(frame_processor.release()), |
| 129 media_log_(media_log), | 128 media_log_(media_log), |
| 130 state_(UNINITIALIZED), | 129 state_(UNINITIALIZED), |
| 131 auto_update_timestamp_offset_(false) { | 130 auto_update_timestamp_offset_(false) { |
| 132 DCHECK(!create_demuxer_stream_cb_.is_null()); | 131 DCHECK(!create_demuxer_stream_cb_.is_null()); |
| 133 DCHECK(frame_processor_); | 132 DCHECK(frame_processor_); |
| 134 } | 133 } |
| 135 | 134 |
| 136 MediaSourceState::~MediaSourceState() { | 135 MediaSourceState::~MediaSourceState() { |
| 137 Shutdown(); | 136 Shutdown(); |
| 138 | |
| 139 base::STLDeleteValues(&text_stream_map_); | |
| 140 } | 137 } |
| 141 | 138 |
| 142 void MediaSourceState::Init( | 139 void MediaSourceState::Init( |
| 143 const StreamParser::InitCB& init_cb, | 140 const StreamParser::InitCB& init_cb, |
| 144 const std::string& expected_codecs, | 141 const std::string& expected_codecs, |
| 145 const StreamParser::EncryptedMediaInitDataCB& encrypted_media_init_data_cb, | 142 const StreamParser::EncryptedMediaInitDataCB& encrypted_media_init_data_cb, |
| 146 const NewTextTrackCB& new_text_track_cb) { | 143 const NewTextTrackCB& new_text_track_cb) { |
| 147 DCHECK_EQ(state_, UNINITIALIZED); | 144 DCHECK_EQ(state_, UNINITIALIZED); |
| 148 new_text_track_cb_ = new_text_track_cb; | 145 new_text_track_cb_ = new_text_track_cb; |
| 149 init_cb_ = init_cb; | 146 init_cb_ = init_cb; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 TimeDelta end, | 244 TimeDelta end, |
| 248 TimeDelta duration) { | 245 TimeDelta duration) { |
| 249 for (const auto& it : audio_streams_) { | 246 for (const auto& it : audio_streams_) { |
| 250 it.second->Remove(start, end, duration); | 247 it.second->Remove(start, end, duration); |
| 251 } | 248 } |
| 252 | 249 |
| 253 for (const auto& it : video_streams_) { | 250 for (const auto& it : video_streams_) { |
| 254 it.second->Remove(start, end, duration); | 251 it.second->Remove(start, end, duration); |
| 255 } | 252 } |
| 256 | 253 |
| 257 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 254 for (const auto& it : text_streams_) { |
| 258 itr != text_stream_map_.end(); ++itr) { | 255 it.second->Remove(start, end, duration); |
| 259 itr->second->Remove(start, end, duration); | |
| 260 } | 256 } |
| 261 } | 257 } |
| 262 | 258 |
| 263 bool MediaSourceState::EvictCodedFrames(DecodeTimestamp media_time, | 259 bool MediaSourceState::EvictCodedFrames(DecodeTimestamp media_time, |
| 264 size_t newDataSize) { | 260 size_t newDataSize) { |
| 265 size_t total_buffered_size = 0; | 261 size_t total_buffered_size = 0; |
| 266 for (const auto& it : audio_streams_) | 262 for (const auto& it : audio_streams_) |
| 267 total_buffered_size += it.second->GetBufferedSize(); | 263 total_buffered_size += it.second->GetBufferedSize(); |
| 268 for (const auto& it : video_streams_) | 264 for (const auto& it : video_streams_) |
| 269 total_buffered_size += it.second->GetBufferedSize(); | 265 total_buffered_size += it.second->GetBufferedSize(); |
| 270 for (const auto& it : text_stream_map_) | 266 for (const auto& it : text_streams_) |
| 271 total_buffered_size += it.second->GetBufferedSize(); | 267 total_buffered_size += it.second->GetBufferedSize(); |
| 272 | 268 |
| 273 DVLOG(3) << __func__ << " media_time=" << media_time.InSecondsF() | 269 DVLOG(3) << __func__ << " media_time=" << media_time.InSecondsF() |
| 274 << " newDataSize=" << newDataSize | 270 << " newDataSize=" << newDataSize |
| 275 << " total_buffered_size=" << total_buffered_size; | 271 << " total_buffered_size=" << total_buffered_size; |
| 276 | 272 |
| 277 if (total_buffered_size == 0) | 273 if (total_buffered_size == 0) |
| 278 return true; | 274 return true; |
| 279 | 275 |
| 280 bool success = true; | 276 bool success = true; |
| 281 for (const auto& it : audio_streams_) { | 277 for (const auto& it : audio_streams_) { |
| 282 uint64_t curr_size = it.second->GetBufferedSize(); | 278 uint64_t curr_size = it.second->GetBufferedSize(); |
| 283 if (curr_size == 0) | 279 if (curr_size == 0) |
| 284 continue; | 280 continue; |
| 285 uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size; | 281 uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size; |
| 286 DCHECK_LE(estimated_new_size, SIZE_MAX); | 282 DCHECK_LE(estimated_new_size, SIZE_MAX); |
| 287 success &= it.second->EvictCodedFrames( | 283 success &= it.second->EvictCodedFrames( |
| 288 media_time, static_cast<size_t>(estimated_new_size)); | 284 media_time, static_cast<size_t>(estimated_new_size)); |
| 289 } | 285 } |
| 290 for (const auto& it : video_streams_) { | 286 for (const auto& it : video_streams_) { |
| 291 uint64_t curr_size = it.second->GetBufferedSize(); | 287 uint64_t curr_size = it.second->GetBufferedSize(); |
| 292 if (curr_size == 0) | 288 if (curr_size == 0) |
| 293 continue; | 289 continue; |
| 294 uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size; | 290 uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size; |
| 295 DCHECK_LE(estimated_new_size, SIZE_MAX); | 291 DCHECK_LE(estimated_new_size, SIZE_MAX); |
| 296 success &= it.second->EvictCodedFrames( | 292 success &= it.second->EvictCodedFrames( |
| 297 media_time, static_cast<size_t>(estimated_new_size)); | 293 media_time, static_cast<size_t>(estimated_new_size)); |
| 298 } | 294 } |
| 299 for (const auto& it : text_stream_map_) { | 295 for (const auto& it : text_streams_) { |
| 300 uint64_t curr_size = it.second->GetBufferedSize(); | 296 uint64_t curr_size = it.second->GetBufferedSize(); |
| 301 if (curr_size == 0) | 297 if (curr_size == 0) |
| 302 continue; | 298 continue; |
| 303 uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size; | 299 uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size; |
| 304 DCHECK_LE(estimated_new_size, SIZE_MAX); | 300 DCHECK_LE(estimated_new_size, SIZE_MAX); |
| 305 success &= it.second->EvictCodedFrames( | 301 success &= it.second->EvictCodedFrames( |
| 306 media_time, static_cast<size_t>(estimated_new_size)); | 302 media_time, static_cast<size_t>(estimated_new_size)); |
| 307 } | 303 } |
| 308 | 304 |
| 309 DVLOG(3) << __func__ << " success=" << success; | 305 DVLOG(3) << __func__ << " success=" << success; |
| 310 return success; | 306 return success; |
| 311 } | 307 } |
| 312 | 308 |
| 313 Ranges<TimeDelta> MediaSourceState::GetBufferedRanges(TimeDelta duration, | 309 Ranges<TimeDelta> MediaSourceState::GetBufferedRanges(TimeDelta duration, |
| 314 bool ended) const { | 310 bool ended) const { |
| 315 RangesList ranges_list; | 311 RangesList ranges_list; |
| 316 for (const auto& it : audio_streams_) | 312 for (const auto& it : audio_streams_) |
| 317 ranges_list.push_back(it.second->GetBufferedRanges(duration)); | 313 ranges_list.push_back(it.second->GetBufferedRanges(duration)); |
| 318 | 314 |
| 319 for (const auto& it : video_streams_) | 315 for (const auto& it : video_streams_) |
| 320 ranges_list.push_back(it.second->GetBufferedRanges(duration)); | 316 ranges_list.push_back(it.second->GetBufferedRanges(duration)); |
| 321 | 317 |
| 322 for (TextStreamMap::const_iterator itr = text_stream_map_.begin(); | 318 for (const auto& it : text_streams_) |
| 323 itr != text_stream_map_.end(); ++itr) { | 319 ranges_list.push_back(it.second->GetBufferedRanges(duration)); |
| 324 ranges_list.push_back(itr->second->GetBufferedRanges(duration)); | |
| 325 } | |
| 326 | 320 |
| 327 return ComputeRangesIntersection(ranges_list, ended); | 321 return ComputeRangesIntersection(ranges_list, ended); |
| 328 } | 322 } |
| 329 | 323 |
| 330 TimeDelta MediaSourceState::GetHighestPresentationTimestamp() const { | 324 TimeDelta MediaSourceState::GetHighestPresentationTimestamp() const { |
| 331 TimeDelta max_pts; | 325 TimeDelta max_pts; |
| 332 | 326 |
| 333 for (const auto& it : audio_streams_) { | 327 for (const auto& it : audio_streams_) { |
| 334 max_pts = std::max(max_pts, it.second->GetHighestPresentationTimestamp()); | 328 max_pts = std::max(max_pts, it.second->GetHighestPresentationTimestamp()); |
| 335 } | 329 } |
| 336 | 330 |
| 337 for (const auto& it : video_streams_) { | 331 for (const auto& it : video_streams_) { |
| 338 max_pts = std::max(max_pts, it.second->GetHighestPresentationTimestamp()); | 332 max_pts = std::max(max_pts, it.second->GetHighestPresentationTimestamp()); |
| 339 } | 333 } |
| 340 | 334 |
| 341 for (TextStreamMap::const_iterator itr = text_stream_map_.begin(); | 335 for (const auto& it : text_streams_) { |
| 342 itr != text_stream_map_.end(); ++itr) { | 336 max_pts = std::max(max_pts, it.second->GetHighestPresentationTimestamp()); |
| 343 max_pts = std::max(max_pts, itr->second->GetHighestPresentationTimestamp()); | |
| 344 } | 337 } |
| 345 | 338 |
| 346 return max_pts; | 339 return max_pts; |
| 347 } | 340 } |
| 348 | 341 |
| 349 TimeDelta MediaSourceState::GetMaxBufferedDuration() const { | 342 TimeDelta MediaSourceState::GetMaxBufferedDuration() const { |
| 350 TimeDelta max_duration; | 343 TimeDelta max_duration; |
| 351 | 344 |
| 352 for (const auto& it : audio_streams_) { | 345 for (const auto& it : audio_streams_) { |
| 353 max_duration = std::max(max_duration, it.second->GetBufferedDuration()); | 346 max_duration = std::max(max_duration, it.second->GetBufferedDuration()); |
| 354 } | 347 } |
| 355 | 348 |
| 356 for (const auto& it : video_streams_) { | 349 for (const auto& it : video_streams_) { |
| 357 max_duration = std::max(max_duration, it.second->GetBufferedDuration()); | 350 max_duration = std::max(max_duration, it.second->GetBufferedDuration()); |
| 358 } | 351 } |
| 359 | 352 |
| 360 for (TextStreamMap::const_iterator itr = text_stream_map_.begin(); | 353 for (const auto& it : text_streams_) { |
| 361 itr != text_stream_map_.end(); ++itr) { | 354 max_duration = std::max(max_duration, it.second->GetBufferedDuration()); |
| 362 max_duration = std::max(max_duration, itr->second->GetBufferedDuration()); | |
| 363 } | 355 } |
| 364 | 356 |
| 365 return max_duration; | 357 return max_duration; |
| 366 } | 358 } |
| 367 | 359 |
| 368 void MediaSourceState::StartReturningData() { | 360 void MediaSourceState::StartReturningData() { |
| 369 for (const auto& it : audio_streams_) { | 361 for (const auto& it : audio_streams_) { |
| 370 it.second->StartReturningData(); | 362 it.second->StartReturningData(); |
| 371 } | 363 } |
| 372 | 364 |
| 373 for (const auto& it : video_streams_) { | 365 for (const auto& it : video_streams_) { |
| 374 it.second->StartReturningData(); | 366 it.second->StartReturningData(); |
| 375 } | 367 } |
| 376 | 368 |
| 377 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 369 for (const auto& it : text_streams_) { |
| 378 itr != text_stream_map_.end(); ++itr) { | 370 it.second->StartReturningData(); |
| 379 itr->second->StartReturningData(); | |
| 380 } | 371 } |
| 381 } | 372 } |
| 382 | 373 |
| 383 void MediaSourceState::AbortReads() { | 374 void MediaSourceState::AbortReads() { |
| 384 for (const auto& it : audio_streams_) { | 375 for (const auto& it : audio_streams_) { |
| 385 it.second->AbortReads(); | 376 it.second->AbortReads(); |
| 386 } | 377 } |
| 387 | 378 |
| 388 for (const auto& it : video_streams_) { | 379 for (const auto& it : video_streams_) { |
| 389 it.second->AbortReads(); | 380 it.second->AbortReads(); |
| 390 } | 381 } |
| 391 | 382 |
| 392 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 383 for (const auto& it : text_streams_) { |
| 393 itr != text_stream_map_.end(); ++itr) { | 384 it.second->AbortReads(); |
| 394 itr->second->AbortReads(); | |
| 395 } | 385 } |
| 396 } | 386 } |
| 397 | 387 |
| 398 void MediaSourceState::Seek(TimeDelta seek_time) { | 388 void MediaSourceState::Seek(TimeDelta seek_time) { |
| 399 for (const auto& it : audio_streams_) { | 389 for (const auto& it : audio_streams_) { |
| 400 it.second->Seek(seek_time); | 390 it.second->Seek(seek_time); |
| 401 } | 391 } |
| 402 | 392 |
| 403 for (const auto& it : video_streams_) { | 393 for (const auto& it : video_streams_) { |
| 404 it.second->Seek(seek_time); | 394 it.second->Seek(seek_time); |
| 405 } | 395 } |
| 406 | 396 |
| 407 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 397 for (const auto& it : text_streams_) { |
| 408 itr != text_stream_map_.end(); ++itr) { | 398 it.second->Seek(seek_time); |
| 409 itr->second->Seek(seek_time); | |
| 410 } | 399 } |
| 411 } | 400 } |
| 412 | 401 |
| 413 void MediaSourceState::CompletePendingReadIfPossible() { | 402 void MediaSourceState::CompletePendingReadIfPossible() { |
| 414 for (const auto& it : audio_streams_) { | 403 for (const auto& it : audio_streams_) { |
| 415 it.second->CompletePendingReadIfPossible(); | 404 it.second->CompletePendingReadIfPossible(); |
| 416 } | 405 } |
| 417 | 406 |
| 418 for (const auto& it : video_streams_) { | 407 for (const auto& it : video_streams_) { |
| 419 it.second->CompletePendingReadIfPossible(); | 408 it.second->CompletePendingReadIfPossible(); |
| 420 } | 409 } |
| 421 | 410 |
| 422 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 411 for (const auto& it : text_streams_) { |
| 423 itr != text_stream_map_.end(); ++itr) { | 412 it.second->CompletePendingReadIfPossible(); |
| 424 itr->second->CompletePendingReadIfPossible(); | |
| 425 } | 413 } |
| 426 } | 414 } |
| 427 | 415 |
| 428 void MediaSourceState::OnSetDuration(TimeDelta duration) { | 416 void MediaSourceState::OnSetDuration(TimeDelta duration) { |
| 429 for (const auto& it : audio_streams_) { | 417 for (const auto& it : audio_streams_) { |
| 430 it.second->OnSetDuration(duration); | 418 it.second->OnSetDuration(duration); |
| 431 } | 419 } |
| 432 | 420 |
| 433 for (const auto& it : video_streams_) { | 421 for (const auto& it : video_streams_) { |
| 434 it.second->OnSetDuration(duration); | 422 it.second->OnSetDuration(duration); |
| 435 } | 423 } |
| 436 | 424 |
| 437 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 425 for (const auto& it : text_streams_) { |
| 438 itr != text_stream_map_.end(); ++itr) { | 426 it.second->OnSetDuration(duration); |
| 439 itr->second->OnSetDuration(duration); | |
| 440 } | 427 } |
| 441 } | 428 } |
| 442 | 429 |
| 443 void MediaSourceState::MarkEndOfStream() { | 430 void MediaSourceState::MarkEndOfStream() { |
| 444 for (const auto& it : audio_streams_) { | 431 for (const auto& it : audio_streams_) { |
| 445 it.second->MarkEndOfStream(); | 432 it.second->MarkEndOfStream(); |
| 446 } | 433 } |
| 447 | 434 |
| 448 for (const auto& it : video_streams_) { | 435 for (const auto& it : video_streams_) { |
| 449 it.second->MarkEndOfStream(); | 436 it.second->MarkEndOfStream(); |
| 450 } | 437 } |
| 451 | 438 |
| 452 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 439 for (const auto& it : text_streams_) { |
| 453 itr != text_stream_map_.end(); ++itr) { | 440 it.second->MarkEndOfStream(); |
| 454 itr->second->MarkEndOfStream(); | |
| 455 } | 441 } |
| 456 } | 442 } |
| 457 | 443 |
| 458 void MediaSourceState::UnmarkEndOfStream() { | 444 void MediaSourceState::UnmarkEndOfStream() { |
| 459 for (const auto& it : audio_streams_) { | 445 for (const auto& it : audio_streams_) { |
| 460 it.second->UnmarkEndOfStream(); | 446 it.second->UnmarkEndOfStream(); |
| 461 } | 447 } |
| 462 | 448 |
| 463 for (const auto& it : video_streams_) { | 449 for (const auto& it : video_streams_) { |
| 464 it.second->UnmarkEndOfStream(); | 450 it.second->UnmarkEndOfStream(); |
| 465 } | 451 } |
| 466 | 452 |
| 467 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 453 for (const auto& it : text_streams_) { |
| 468 itr != text_stream_map_.end(); ++itr) { | 454 it.second->UnmarkEndOfStream(); |
| 469 itr->second->UnmarkEndOfStream(); | |
| 470 } | 455 } |
| 471 } | 456 } |
| 472 | 457 |
| 473 void MediaSourceState::Shutdown() { | 458 void MediaSourceState::Shutdown() { |
| 474 for (const auto& it : audio_streams_) { | 459 for (const auto& it : audio_streams_) { |
| 475 it.second->Shutdown(); | 460 it.second->Shutdown(); |
| 476 } | 461 } |
| 477 | 462 |
| 478 for (const auto& it : video_streams_) { | 463 for (const auto& it : video_streams_) { |
| 479 it.second->Shutdown(); | 464 it.second->Shutdown(); |
| 480 } | 465 } |
| 481 | 466 |
| 482 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 467 for (const auto& it : text_streams_) { |
| 483 itr != text_stream_map_.end(); ++itr) { | 468 it.second->Shutdown(); |
| 484 itr->second->Shutdown(); | |
| 485 } | 469 } |
| 486 } | 470 } |
| 487 | 471 |
| 488 void MediaSourceState::SetMemoryLimits(DemuxerStream::Type type, | 472 void MediaSourceState::SetMemoryLimits(DemuxerStream::Type type, |
| 489 size_t memory_limit) { | 473 size_t memory_limit) { |
| 490 switch (type) { | 474 switch (type) { |
| 491 case DemuxerStream::AUDIO: | 475 case DemuxerStream::AUDIO: |
| 492 for (const auto& it : audio_streams_) { | 476 for (const auto& it : audio_streams_) { |
| 493 it.second->SetStreamMemoryLimit(memory_limit); | 477 it.second->SetStreamMemoryLimit(memory_limit); |
| 494 } | 478 } |
| 495 break; | 479 break; |
| 496 case DemuxerStream::VIDEO: | 480 case DemuxerStream::VIDEO: |
| 497 for (const auto& it : video_streams_) { | 481 for (const auto& it : video_streams_) { |
| 498 it.second->SetStreamMemoryLimit(memory_limit); | 482 it.second->SetStreamMemoryLimit(memory_limit); |
| 499 } | 483 } |
| 500 break; | 484 break; |
| 501 case DemuxerStream::TEXT: | 485 case DemuxerStream::TEXT: |
| 502 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 486 for (const auto& it : text_streams_) { |
| 503 itr != text_stream_map_.end(); ++itr) { | 487 it.second->SetStreamMemoryLimit(memory_limit); |
| 504 itr->second->SetStreamMemoryLimit(memory_limit); | |
| 505 } | 488 } |
| 506 break; | 489 break; |
| 507 case DemuxerStream::UNKNOWN: | 490 case DemuxerStream::UNKNOWN: |
| 508 case DemuxerStream::NUM_TYPES: | 491 case DemuxerStream::NUM_TYPES: |
| 509 NOTREACHED(); | 492 NOTREACHED(); |
| 510 break; | 493 break; |
| 511 } | 494 } |
| 512 } | 495 } |
| 513 | 496 |
| 514 bool MediaSourceState::IsSeekWaitingForData() const { | 497 bool MediaSourceState::IsSeekWaitingForData() const { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 media_log_->SetBooleanProperty("found_audio_stream", true); | 577 media_log_->SetBooleanProperty("found_audio_stream", true); |
| 595 media_log_->SetStringProperty("audio_codec_name", | 578 media_log_->SetStringProperty("audio_codec_name", |
| 596 GetCodecName(audio_config.codec())); | 579 GetCodecName(audio_config.codec())); |
| 597 } else { | 580 } else { |
| 598 if (audio_streams_.size() > 1) { | 581 if (audio_streams_.size() > 1) { |
| 599 auto it = audio_streams_.find(track_id); | 582 auto it = audio_streams_.find(track_id); |
| 600 if (it != audio_streams_.end()) | 583 if (it != audio_streams_.end()) |
| 601 stream = it->second; | 584 stream = it->second; |
| 602 } else { | 585 } else { |
| 603 // If there is only one audio track then bytestream id might change in | 586 // If there is only one audio track then bytestream id might change in |
| 604 // a new init segment. So update our state and nofity frame processor. | 587 // a new init segment. So update our state and notify frame processor. |
| 605 const auto& it = audio_streams_.begin(); | 588 const auto& it = audio_streams_.begin(); |
| 606 if (it != audio_streams_.end()) { | 589 if (it != audio_streams_.end()) { |
| 607 stream = it->second; | 590 stream = it->second; |
| 608 if (it->first != track_id) { | 591 if (it->first != track_id) { |
| 609 frame_processor_->UpdateTrack(it->first, track_id); | 592 frame_processor_->UpdateTrack(it->first, track_id); |
| 610 audio_streams_[track_id] = stream; | 593 audio_streams_[track_id] = stream; |
| 611 audio_streams_.erase(it->first); | 594 audio_streams_.erase(it->first); |
| 612 } | 595 } |
| 613 } | 596 } |
| 614 } | 597 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 media_log_->SetBooleanProperty("found_video_stream", true); | 633 media_log_->SetBooleanProperty("found_video_stream", true); |
| 651 media_log_->SetStringProperty("video_codec_name", | 634 media_log_->SetStringProperty("video_codec_name", |
| 652 GetCodecName(video_config.codec())); | 635 GetCodecName(video_config.codec())); |
| 653 } else { | 636 } else { |
| 654 if (video_streams_.size() > 1) { | 637 if (video_streams_.size() > 1) { |
| 655 auto it = video_streams_.find(track_id); | 638 auto it = video_streams_.find(track_id); |
| 656 if (it != video_streams_.end()) | 639 if (it != video_streams_.end()) |
| 657 stream = it->second; | 640 stream = it->second; |
| 658 } else { | 641 } else { |
| 659 // If there is only one video track then bytestream id might change in | 642 // If there is only one video track then bytestream id might change in |
| 660 // a new init segment. So update our state and nofity frame processor. | 643 // a new init segment. So update our state and notify frame processor. |
| 661 const auto& it = video_streams_.begin(); | 644 const auto& it = video_streams_.begin(); |
| 662 if (it != video_streams_.end()) { | 645 if (it != video_streams_.end()) { |
| 663 stream = it->second; | 646 stream = it->second; |
| 664 if (it->first != track_id) { | 647 if (it->first != track_id) { |
| 665 frame_processor_->UpdateTrack(it->first, track_id); | 648 frame_processor_->UpdateTrack(it->first, track_id); |
| 666 video_streams_[track_id] = stream; | 649 video_streams_[track_id] = stream; |
| 667 video_streams_.erase(it->first); | 650 video_streams_.erase(it->first); |
| 668 } | 651 } |
| 669 } | 652 } |
| 670 } | 653 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 689 MEDIA_LOG(ERROR, media_log_) << "Initialization segment misses expected " | 672 MEDIA_LOG(ERROR, media_log_) << "Initialization segment misses expected " |
| 690 << GetCodecName(acodec) << " track."; | 673 << GetCodecName(acodec) << " track."; |
| 691 } | 674 } |
| 692 for (const auto& vcodec : expected_vcodecs) { | 675 for (const auto& vcodec : expected_vcodecs) { |
| 693 MEDIA_LOG(ERROR, media_log_) << "Initialization segment misses expected " | 676 MEDIA_LOG(ERROR, media_log_) << "Initialization segment misses expected " |
| 694 << GetCodecName(vcodec) << " track."; | 677 << GetCodecName(vcodec) << " track."; |
| 695 } | 678 } |
| 696 return false; | 679 return false; |
| 697 } | 680 } |
| 698 | 681 |
| 699 typedef StreamParser::TextTrackConfigMap::const_iterator TextConfigItr; | 682 if (text_streams_.empty()) { |
| 700 if (text_stream_map_.empty()) { | 683 for (auto itr = text_configs.begin(); itr != text_configs.end(); ++itr) { |
| 701 for (TextConfigItr itr = text_configs.begin(); itr != text_configs.end(); | |
| 702 ++itr) { | |
| 703 ChunkDemuxerStream* const text_stream = | 684 ChunkDemuxerStream* const text_stream = |
| 704 create_demuxer_stream_cb_.Run(DemuxerStream::TEXT); | 685 create_demuxer_stream_cb_.Run(DemuxerStream::TEXT); |
| 705 if (!frame_processor_->AddTrack(itr->first, text_stream)) { | 686 if (!frame_processor_->AddTrack(itr->first, text_stream)) { |
| 706 success &= false; | 687 success &= false; |
| 707 MEDIA_LOG(ERROR, media_log_) << "Failed to add text track ID " | 688 MEDIA_LOG(ERROR, media_log_) << "Failed to add text track ID " |
| 708 << itr->first << " to frame processor."; | 689 << itr->first << " to frame processor."; |
| 709 break; | 690 break; |
| 710 } | 691 } |
| 711 text_stream->UpdateTextConfig(itr->second, media_log_); | 692 text_stream->UpdateTextConfig(itr->second, media_log_); |
| 712 text_stream_map_[itr->first] = text_stream; | 693 text_streams_[itr->first] = text_stream; |
| 713 new_text_track_cb_.Run(text_stream, itr->second); | 694 new_text_track_cb_.Run(text_stream, itr->second); |
| 714 } | 695 } |
| 715 } else { | 696 } else { |
| 716 const size_t text_count = text_stream_map_.size(); | 697 const size_t text_count = text_streams_.size(); |
| 717 if (text_configs.size() != text_count) { | 698 if (text_configs.size() != text_count) { |
| 718 success &= false; | 699 success &= false; |
| 719 MEDIA_LOG(ERROR, media_log_) | 700 MEDIA_LOG(ERROR, media_log_) |
| 720 << "The number of text track configs changed."; | 701 << "The number of text track configs changed."; |
| 721 } else if (text_count == 1) { | 702 } else if (text_count == 1) { |
| 722 TextConfigItr config_itr = text_configs.begin(); | 703 auto config_itr = text_configs.begin(); |
| 723 TextStreamMap::iterator stream_itr = text_stream_map_.begin(); | 704 auto stream_itr = text_streams_.begin(); |
| 724 ChunkDemuxerStream* text_stream = stream_itr->second; | 705 ChunkDemuxerStream* text_stream = stream_itr->second; |
| 725 TextTrackConfig old_config = text_stream->text_track_config(); | 706 TextTrackConfig old_config = text_stream->text_track_config(); |
| 726 TextTrackConfig new_config( | 707 TextTrackConfig new_config( |
| 727 config_itr->second.kind(), config_itr->second.label(), | 708 config_itr->second.kind(), config_itr->second.label(), |
| 728 config_itr->second.language(), old_config.id()); | 709 config_itr->second.language(), old_config.id()); |
| 729 if (!new_config.Matches(old_config)) { | 710 if (!new_config.Matches(old_config)) { |
| 730 success &= false; | 711 success &= false; |
| 731 MEDIA_LOG(ERROR, media_log_) | 712 MEDIA_LOG(ERROR, media_log_) |
| 732 << "New text track config does not match old one."; | 713 << "New text track config does not match old one."; |
| 733 } else { | 714 } else { |
| 734 StreamParser::TrackId old_id = stream_itr->first; | 715 StreamParser::TrackId old_id = stream_itr->first; |
| 735 StreamParser::TrackId new_id = config_itr->first; | 716 StreamParser::TrackId new_id = config_itr->first; |
| 736 if (new_id != old_id) { | 717 if (new_id != old_id) { |
| 737 if (frame_processor_->UpdateTrack(old_id, new_id)) { | 718 if (frame_processor_->UpdateTrack(old_id, new_id)) { |
| 738 text_stream_map_.clear(); | 719 text_streams_.clear(); |
| 739 text_stream_map_[config_itr->first] = text_stream; | 720 text_streams_[config_itr->first] = text_stream; |
| 740 } else { | 721 } else { |
| 741 success &= false; | 722 success &= false; |
| 742 MEDIA_LOG(ERROR, media_log_) | 723 MEDIA_LOG(ERROR, media_log_) |
| 743 << "Error remapping single text track number"; | 724 << "Error remapping single text track number"; |
| 744 } | 725 } |
| 745 } | 726 } |
| 746 } | 727 } |
| 747 } else { | 728 } else { |
| 748 for (TextConfigItr config_itr = text_configs.begin(); | 729 for (auto config_itr = text_configs.begin(); |
| 749 config_itr != text_configs.end(); ++config_itr) { | 730 config_itr != text_configs.end(); ++config_itr) { |
| 750 TextStreamMap::iterator stream_itr = | 731 auto stream_itr = text_streams_.find(config_itr->first); |
| 751 text_stream_map_.find(config_itr->first); | 732 if (stream_itr == text_streams_.end()) { |
| 752 if (stream_itr == text_stream_map_.end()) { | |
| 753 success &= false; | 733 success &= false; |
| 754 MEDIA_LOG(ERROR, media_log_) | 734 MEDIA_LOG(ERROR, media_log_) |
| 755 << "Unexpected text track configuration for track ID " | 735 << "Unexpected text track configuration for track ID " |
| 756 << config_itr->first; | 736 << config_itr->first; |
| 757 break; | 737 break; |
| 758 } | 738 } |
| 759 | 739 |
| 760 const TextTrackConfig& new_config = config_itr->second; | 740 const TextTrackConfig& new_config = config_itr->second; |
| 761 ChunkDemuxerStream* stream = stream_itr->second; | 741 ChunkDemuxerStream* stream = stream_itr->second; |
| 762 TextTrackConfig old_config = stream->text_track_config(); | 742 TextTrackConfig old_config = stream->text_track_config(); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 } | 888 } |
| 909 void MediaSourceState::OnSourceInitDone( | 889 void MediaSourceState::OnSourceInitDone( |
| 910 const StreamParser::InitParameters& params) { | 890 const StreamParser::InitParameters& params) { |
| 911 DCHECK_EQ(state_, PENDING_PARSER_INIT); | 891 DCHECK_EQ(state_, PENDING_PARSER_INIT); |
| 912 state_ = PARSER_INITIALIZED; | 892 state_ = PARSER_INITIALIZED; |
| 913 auto_update_timestamp_offset_ = params.auto_update_timestamp_offset; | 893 auto_update_timestamp_offset_ = params.auto_update_timestamp_offset; |
| 914 base::ResetAndReturn(&init_cb_).Run(params); | 894 base::ResetAndReturn(&init_cb_).Run(params); |
| 915 } | 895 } |
| 916 | 896 |
| 917 } // namespace media | 897 } // namespace media |
| OLD | NEW |