| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/cdm/cdm_adapter.h" | 5 #include "media/cdm/cdm_adapter.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 } | 326 } |
| 327 } | 327 } |
| 328 | 328 |
| 329 } // namespace | 329 } // namespace |
| 330 | 330 |
| 331 // static | 331 // static |
| 332 void CdmAdapter::Create( | 332 void CdmAdapter::Create( |
| 333 const std::string& key_system, | 333 const std::string& key_system, |
| 334 const base::FilePath& cdm_path, | 334 const base::FilePath& cdm_path, |
| 335 const CdmConfig& cdm_config, | 335 const CdmConfig& cdm_config, |
| 336 scoped_ptr<CdmAllocator> allocator, | 336 std::unique_ptr<CdmAllocator> allocator, |
| 337 const CreateCdmFileIOCB& create_cdm_file_io_cb, | 337 const CreateCdmFileIOCB& create_cdm_file_io_cb, |
| 338 const SessionMessageCB& session_message_cb, | 338 const SessionMessageCB& session_message_cb, |
| 339 const SessionClosedCB& session_closed_cb, | 339 const SessionClosedCB& session_closed_cb, |
| 340 const LegacySessionErrorCB& legacy_session_error_cb, | 340 const LegacySessionErrorCB& legacy_session_error_cb, |
| 341 const SessionKeysChangeCB& session_keys_change_cb, | 341 const SessionKeysChangeCB& session_keys_change_cb, |
| 342 const SessionExpirationUpdateCB& session_expiration_update_cb, | 342 const SessionExpirationUpdateCB& session_expiration_update_cb, |
| 343 const CdmCreatedCB& cdm_created_cb) { | 343 const CdmCreatedCB& cdm_created_cb) { |
| 344 DCHECK(!key_system.empty()); | 344 DCHECK(!key_system.empty()); |
| 345 DCHECK(!session_message_cb.is_null()); | 345 DCHECK(!session_message_cb.is_null()); |
| 346 DCHECK(!session_closed_cb.is_null()); | 346 DCHECK(!session_closed_cb.is_null()); |
| 347 DCHECK(!legacy_session_error_cb.is_null()); | 347 DCHECK(!legacy_session_error_cb.is_null()); |
| 348 DCHECK(!session_keys_change_cb.is_null()); | 348 DCHECK(!session_keys_change_cb.is_null()); |
| 349 DCHECK(!session_expiration_update_cb.is_null()); | 349 DCHECK(!session_expiration_update_cb.is_null()); |
| 350 | 350 |
| 351 scoped_refptr<CdmAdapter> cdm = new CdmAdapter( | 351 scoped_refptr<CdmAdapter> cdm = new CdmAdapter( |
| 352 key_system, cdm_config, std::move(allocator), create_cdm_file_io_cb, | 352 key_system, cdm_config, std::move(allocator), create_cdm_file_io_cb, |
| 353 session_message_cb, session_closed_cb, legacy_session_error_cb, | 353 session_message_cb, session_closed_cb, legacy_session_error_cb, |
| 354 session_keys_change_cb, session_expiration_update_cb); | 354 session_keys_change_cb, session_expiration_update_cb); |
| 355 | 355 |
| 356 // |cdm| ownership passed to the promise. | 356 // |cdm| ownership passed to the promise. |
| 357 scoped_ptr<CdmInitializedPromise> cdm_created_promise( | 357 std::unique_ptr<CdmInitializedPromise> cdm_created_promise( |
| 358 new CdmInitializedPromise(cdm_created_cb, cdm)); | 358 new CdmInitializedPromise(cdm_created_cb, cdm)); |
| 359 | 359 |
| 360 cdm->Initialize(cdm_path, std::move(cdm_created_promise)); | 360 cdm->Initialize(cdm_path, std::move(cdm_created_promise)); |
| 361 } | 361 } |
| 362 | 362 |
| 363 CdmAdapter::CdmAdapter( | 363 CdmAdapter::CdmAdapter( |
| 364 const std::string& key_system, | 364 const std::string& key_system, |
| 365 const CdmConfig& cdm_config, | 365 const CdmConfig& cdm_config, |
| 366 scoped_ptr<CdmAllocator> allocator, | 366 std::unique_ptr<CdmAllocator> allocator, |
| 367 const CreateCdmFileIOCB& create_cdm_file_io_cb, | 367 const CreateCdmFileIOCB& create_cdm_file_io_cb, |
| 368 const SessionMessageCB& session_message_cb, | 368 const SessionMessageCB& session_message_cb, |
| 369 const SessionClosedCB& session_closed_cb, | 369 const SessionClosedCB& session_closed_cb, |
| 370 const LegacySessionErrorCB& legacy_session_error_cb, | 370 const LegacySessionErrorCB& legacy_session_error_cb, |
| 371 const SessionKeysChangeCB& session_keys_change_cb, | 371 const SessionKeysChangeCB& session_keys_change_cb, |
| 372 const SessionExpirationUpdateCB& session_expiration_update_cb) | 372 const SessionExpirationUpdateCB& session_expiration_update_cb) |
| 373 : key_system_(key_system), | 373 : key_system_(key_system), |
| 374 cdm_config_(cdm_config), | 374 cdm_config_(cdm_config), |
| 375 session_message_cb_(session_message_cb), | 375 session_message_cb_(session_message_cb), |
| 376 session_closed_cb_(session_closed_cb), | 376 session_closed_cb_(session_closed_cb), |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 | 418 |
| 419 CdmWrapper* cdm = CdmWrapper::Create(create_cdm_func, key_system.data(), | 419 CdmWrapper* cdm = CdmWrapper::Create(create_cdm_func, key_system.data(), |
| 420 key_system.size(), GetCdmHost, this); | 420 key_system.size(), GetCdmHost, this); |
| 421 | 421 |
| 422 DVLOG(1) << "CDM instance for " + key_system + (cdm ? "" : " could not be") + | 422 DVLOG(1) << "CDM instance for " + key_system + (cdm ? "" : " could not be") + |
| 423 " created."; | 423 " created."; |
| 424 return cdm; | 424 return cdm; |
| 425 } | 425 } |
| 426 | 426 |
| 427 void CdmAdapter::Initialize(const base::FilePath& cdm_path, | 427 void CdmAdapter::Initialize(const base::FilePath& cdm_path, |
| 428 scoped_ptr<media::SimpleCdmPromise> promise) { | 428 std::unique_ptr<media::SimpleCdmPromise> promise) { |
| 429 cdm_.reset(CreateCdmInstance(key_system_, cdm_path)); | 429 cdm_.reset(CreateCdmInstance(key_system_, cdm_path)); |
| 430 if (!cdm_) { | 430 if (!cdm_) { |
| 431 promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, | 431 promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, |
| 432 "Unable to create CDM."); | 432 "Unable to create CDM."); |
| 433 return; | 433 return; |
| 434 } | 434 } |
| 435 | 435 |
| 436 cdm_->Initialize(cdm_config_.allow_distinctive_identifier, | 436 cdm_->Initialize(cdm_config_.allow_distinctive_identifier, |
| 437 cdm_config_.allow_persistent_state); | 437 cdm_config_.allow_persistent_state); |
| 438 promise->resolve(); | 438 promise->resolve(); |
| 439 } | 439 } |
| 440 | 440 |
| 441 void CdmAdapter::SetServerCertificate(const std::vector<uint8_t>& certificate, | 441 void CdmAdapter::SetServerCertificate( |
| 442 scoped_ptr<SimpleCdmPromise> promise) { | 442 const std::vector<uint8_t>& certificate, |
| 443 std::unique_ptr<SimpleCdmPromise> promise) { |
| 443 DCHECK(task_runner_->BelongsToCurrentThread()); | 444 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 444 | 445 |
| 445 if (certificate.size() < limits::kMinCertificateLength || | 446 if (certificate.size() < limits::kMinCertificateLength || |
| 446 certificate.size() > limits::kMaxCertificateLength) { | 447 certificate.size() > limits::kMaxCertificateLength) { |
| 447 promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, | 448 promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, |
| 448 "Incorrect certificate."); | 449 "Incorrect certificate."); |
| 449 return; | 450 return; |
| 450 } | 451 } |
| 451 | 452 |
| 452 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 453 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
| 453 cdm_->SetServerCertificate(promise_id, certificate.data(), | 454 cdm_->SetServerCertificate(promise_id, certificate.data(), |
| 454 certificate.size()); | 455 certificate.size()); |
| 455 } | 456 } |
| 456 | 457 |
| 457 void CdmAdapter::CreateSessionAndGenerateRequest( | 458 void CdmAdapter::CreateSessionAndGenerateRequest( |
| 458 SessionType session_type, | 459 SessionType session_type, |
| 459 EmeInitDataType init_data_type, | 460 EmeInitDataType init_data_type, |
| 460 const std::vector<uint8_t>& init_data, | 461 const std::vector<uint8_t>& init_data, |
| 461 scoped_ptr<NewSessionCdmPromise> promise) { | 462 std::unique_ptr<NewSessionCdmPromise> promise) { |
| 462 DCHECK(task_runner_->BelongsToCurrentThread()); | 463 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 463 | 464 |
| 464 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 465 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
| 465 cdm_->CreateSessionAndGenerateRequest( | 466 cdm_->CreateSessionAndGenerateRequest( |
| 466 promise_id, ToCdmSessionType(session_type), | 467 promise_id, ToCdmSessionType(session_type), |
| 467 ToCdmInitDataType(init_data_type), init_data.data(), init_data.size()); | 468 ToCdmInitDataType(init_data_type), init_data.data(), init_data.size()); |
| 468 } | 469 } |
| 469 | 470 |
| 470 void CdmAdapter::LoadSession(SessionType session_type, | 471 void CdmAdapter::LoadSession(SessionType session_type, |
| 471 const std::string& session_id, | 472 const std::string& session_id, |
| 472 scoped_ptr<NewSessionCdmPromise> promise) { | 473 std::unique_ptr<NewSessionCdmPromise> promise) { |
| 473 DCHECK(task_runner_->BelongsToCurrentThread()); | 474 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 474 | 475 |
| 475 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 476 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
| 476 cdm_->LoadSession(promise_id, ToCdmSessionType(session_type), | 477 cdm_->LoadSession(promise_id, ToCdmSessionType(session_type), |
| 477 session_id.data(), session_id.size()); | 478 session_id.data(), session_id.size()); |
| 478 } | 479 } |
| 479 | 480 |
| 480 void CdmAdapter::UpdateSession(const std::string& session_id, | 481 void CdmAdapter::UpdateSession(const std::string& session_id, |
| 481 const std::vector<uint8_t>& response, | 482 const std::vector<uint8_t>& response, |
| 482 scoped_ptr<SimpleCdmPromise> promise) { | 483 std::unique_ptr<SimpleCdmPromise> promise) { |
| 483 DCHECK(task_runner_->BelongsToCurrentThread()); | 484 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 484 DCHECK(!session_id.empty()); | 485 DCHECK(!session_id.empty()); |
| 485 DCHECK(!response.empty()); | 486 DCHECK(!response.empty()); |
| 486 | 487 |
| 487 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 488 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
| 488 cdm_->UpdateSession(promise_id, session_id.data(), session_id.size(), | 489 cdm_->UpdateSession(promise_id, session_id.data(), session_id.size(), |
| 489 response.data(), response.size()); | 490 response.data(), response.size()); |
| 490 } | 491 } |
| 491 | 492 |
| 492 void CdmAdapter::CloseSession(const std::string& session_id, | 493 void CdmAdapter::CloseSession(const std::string& session_id, |
| 493 scoped_ptr<SimpleCdmPromise> promise) { | 494 std::unique_ptr<SimpleCdmPromise> promise) { |
| 494 DCHECK(task_runner_->BelongsToCurrentThread()); | 495 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 495 DCHECK(!session_id.empty()); | 496 DCHECK(!session_id.empty()); |
| 496 | 497 |
| 497 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 498 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
| 498 cdm_->CloseSession(promise_id, session_id.data(), session_id.size()); | 499 cdm_->CloseSession(promise_id, session_id.data(), session_id.size()); |
| 499 } | 500 } |
| 500 | 501 |
| 501 void CdmAdapter::RemoveSession(const std::string& session_id, | 502 void CdmAdapter::RemoveSession(const std::string& session_id, |
| 502 scoped_ptr<SimpleCdmPromise> promise) { | 503 std::unique_ptr<SimpleCdmPromise> promise) { |
| 503 DCHECK(task_runner_->BelongsToCurrentThread()); | 504 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 504 DCHECK(!session_id.empty()); | 505 DCHECK(!session_id.empty()); |
| 505 | 506 |
| 506 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); | 507 uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise)); |
| 507 cdm_->RemoveSession(promise_id, session_id.data(), session_id.size()); | 508 cdm_->RemoveSession(promise_id, session_id.data(), session_id.size()); |
| 508 } | 509 } |
| 509 | 510 |
| 510 CdmContext* CdmAdapter::GetCdmContext() { | 511 CdmContext* CdmAdapter::GetCdmContext() { |
| 511 DCHECK(task_runner_->BelongsToCurrentThread()); | 512 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 512 return this; | 513 return this; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 537 NOTREACHED() << "Unexpected StreamType " << stream_type; | 538 NOTREACHED() << "Unexpected StreamType " << stream_type; |
| 538 } | 539 } |
| 539 | 540 |
| 540 void CdmAdapter::Decrypt(StreamType stream_type, | 541 void CdmAdapter::Decrypt(StreamType stream_type, |
| 541 const scoped_refptr<DecoderBuffer>& encrypted, | 542 const scoped_refptr<DecoderBuffer>& encrypted, |
| 542 const DecryptCB& decrypt_cb) { | 543 const DecryptCB& decrypt_cb) { |
| 543 DCHECK(task_runner_->BelongsToCurrentThread()); | 544 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 544 | 545 |
| 545 cdm::InputBuffer input_buffer; | 546 cdm::InputBuffer input_buffer; |
| 546 std::vector<cdm::SubsampleEntry> subsamples; | 547 std::vector<cdm::SubsampleEntry> subsamples; |
| 547 scoped_ptr<DecryptedBlockImpl> decrypted_block(new DecryptedBlockImpl()); | 548 std::unique_ptr<DecryptedBlockImpl> decrypted_block(new DecryptedBlockImpl()); |
| 548 | 549 |
| 549 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); | 550 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); |
| 550 cdm::Status status = cdm_->Decrypt(input_buffer, decrypted_block.get()); | 551 cdm::Status status = cdm_->Decrypt(input_buffer, decrypted_block.get()); |
| 551 | 552 |
| 552 if (status != cdm::kSuccess) { | 553 if (status != cdm::kSuccess) { |
| 553 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; | 554 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; |
| 554 decrypt_cb.Run(ToMediaDecryptorStatus(status), nullptr); | 555 decrypt_cb.Run(ToMediaDecryptorStatus(status), nullptr); |
| 555 return; | 556 return; |
| 556 } | 557 } |
| 557 | 558 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 init_cb.Run(true); | 638 init_cb.Run(true); |
| 638 } | 639 } |
| 639 | 640 |
| 640 void CdmAdapter::DecryptAndDecodeAudio( | 641 void CdmAdapter::DecryptAndDecodeAudio( |
| 641 const scoped_refptr<DecoderBuffer>& encrypted, | 642 const scoped_refptr<DecoderBuffer>& encrypted, |
| 642 const AudioDecodeCB& audio_decode_cb) { | 643 const AudioDecodeCB& audio_decode_cb) { |
| 643 DCHECK(task_runner_->BelongsToCurrentThread()); | 644 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 644 | 645 |
| 645 cdm::InputBuffer input_buffer; | 646 cdm::InputBuffer input_buffer; |
| 646 std::vector<cdm::SubsampleEntry> subsamples; | 647 std::vector<cdm::SubsampleEntry> subsamples; |
| 647 scoped_ptr<AudioFramesImpl> audio_frames(new AudioFramesImpl()); | 648 std::unique_ptr<AudioFramesImpl> audio_frames(new AudioFramesImpl()); |
| 648 | 649 |
| 649 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); | 650 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); |
| 650 cdm::Status status = | 651 cdm::Status status = |
| 651 cdm_->DecryptAndDecodeSamples(input_buffer, audio_frames.get()); | 652 cdm_->DecryptAndDecodeSamples(input_buffer, audio_frames.get()); |
| 652 | 653 |
| 653 const Decryptor::AudioFrames empty_frames; | 654 const Decryptor::AudioFrames empty_frames; |
| 654 if (status != cdm::kSuccess) { | 655 if (status != cdm::kSuccess) { |
| 655 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; | 656 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; |
| 656 audio_decode_cb.Run(ToMediaDecryptorStatus(status), empty_frames); | 657 audio_decode_cb.Run(ToMediaDecryptorStatus(status), empty_frames); |
| 657 return; | 658 return; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 671 | 672 |
| 672 void CdmAdapter::DecryptAndDecodeVideo( | 673 void CdmAdapter::DecryptAndDecodeVideo( |
| 673 const scoped_refptr<DecoderBuffer>& encrypted, | 674 const scoped_refptr<DecoderBuffer>& encrypted, |
| 674 const VideoDecodeCB& video_decode_cb) { | 675 const VideoDecodeCB& video_decode_cb) { |
| 675 DCHECK(task_runner_->BelongsToCurrentThread()); | 676 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 676 DVLOG(3) << __FUNCTION__ | 677 DVLOG(3) << __FUNCTION__ |
| 677 << " encrypted: " << encrypted->AsHumanReadableString(); | 678 << " encrypted: " << encrypted->AsHumanReadableString(); |
| 678 | 679 |
| 679 cdm::InputBuffer input_buffer; | 680 cdm::InputBuffer input_buffer; |
| 680 std::vector<cdm::SubsampleEntry> subsamples; | 681 std::vector<cdm::SubsampleEntry> subsamples; |
| 681 scoped_ptr<VideoFrameImpl> video_frame = allocator_->CreateCdmVideoFrame(); | 682 std::unique_ptr<VideoFrameImpl> video_frame = |
| 683 allocator_->CreateCdmVideoFrame(); |
| 682 | 684 |
| 683 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); | 685 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); |
| 684 cdm::Status status = | 686 cdm::Status status = |
| 685 cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); | 687 cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); |
| 686 | 688 |
| 687 if (status != cdm::kSuccess) { | 689 if (status != cdm::kSuccess) { |
| 688 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; | 690 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; |
| 689 video_decode_cb.Run(ToMediaDecryptorStatus(status), nullptr); | 691 video_decode_cb.Run(ToMediaDecryptorStatus(status), nullptr); |
| 690 return; | 692 return; |
| 691 } | 693 } |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 DCHECK(task_runner_->BelongsToCurrentThread()); | 901 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 900 | 902 |
| 901 std::unique_ptr<CdmFileIO> file_io = create_cdm_file_io_cb_.Run(client); | 903 std::unique_ptr<CdmFileIO> file_io = create_cdm_file_io_cb_.Run(client); |
| 902 | 904 |
| 903 // The CDM owns the returned object and must call FileIO::Close() | 905 // The CDM owns the returned object and must call FileIO::Close() |
| 904 // to release it. | 906 // to release it. |
| 905 return file_io.release(); | 907 return file_io.release(); |
| 906 } | 908 } |
| 907 | 909 |
| 908 bool CdmAdapter::AudioFramesDataToAudioFrames( | 910 bool CdmAdapter::AudioFramesDataToAudioFrames( |
| 909 scoped_ptr<AudioFramesImpl> audio_frames, | 911 std::unique_ptr<AudioFramesImpl> audio_frames, |
| 910 Decryptor::AudioFrames* result_frames) { | 912 Decryptor::AudioFrames* result_frames) { |
| 911 const uint8_t* data = audio_frames->FrameBuffer()->Data(); | 913 const uint8_t* data = audio_frames->FrameBuffer()->Data(); |
| 912 const size_t data_size = audio_frames->FrameBuffer()->Size(); | 914 const size_t data_size = audio_frames->FrameBuffer()->Size(); |
| 913 size_t bytes_left = data_size; | 915 size_t bytes_left = data_size; |
| 914 const SampleFormat sample_format = | 916 const SampleFormat sample_format = |
| 915 ToMediaSampleFormat(audio_frames->Format()); | 917 ToMediaSampleFormat(audio_frames->Format()); |
| 916 const int audio_channel_count = | 918 const int audio_channel_count = |
| 917 ChannelLayoutToChannelCount(audio_channel_layout_); | 919 ChannelLayoutToChannelCount(audio_channel_layout_); |
| 918 const int audio_bytes_per_frame = | 920 const int audio_bytes_per_frame = |
| 919 SampleFormatToBytesPerChannel(sample_format) * audio_channel_count; | 921 SampleFormatToBytesPerChannel(sample_format) * audio_channel_count; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 958 result_frames->push_back(frame); | 960 result_frames->push_back(frame); |
| 959 | 961 |
| 960 data += frame_size; | 962 data += frame_size; |
| 961 bytes_left -= frame_size; | 963 bytes_left -= frame_size; |
| 962 } while (bytes_left > 0); | 964 } while (bytes_left > 0); |
| 963 | 965 |
| 964 return true; | 966 return true; |
| 965 } | 967 } |
| 966 | 968 |
| 967 } // namespace media | 969 } // namespace media |
| OLD | NEW |