1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/renderer/media/android/media_source_delegate.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <limits>
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <string>
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <vector>
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/renderer/media/android/renderer_demuxer_android.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/android/demuxer_stream_player_params.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/base/bind_to_current_loop.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/demuxer_stream.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/media_log.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/webmediaplayer_util.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/webmediasource_impl.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/filters/chunk_demuxer.h"
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "media/filters/decrypting_demuxer_stream.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using media::DemuxerStream;
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using media::DemuxerConfigs;
27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using media::DemuxerData;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebMediaPlayer;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString;
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The size of the access unit to transfer in an IPC in case of MediaSource.
3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// 4: approximately 64ms of content in 60 fps movies.
3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const size_t kAccessUnitSizeForMediaSource = 4;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const uint8 kVorbisPadding[] = { 0xff, 0xff, 0xff, 0xff };
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content {
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log,
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                const std::string& error) {
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error));
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)MediaSourceDelegate::MediaSourceDelegate(
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    RendererDemuxerAndroid* demuxer_client,
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int demuxer_client_id,
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<media::MediaLog> media_log)
5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    : demuxer_client_(demuxer_client),
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      demuxer_client_id_(demuxer_client_id),
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      media_log_(media_log),
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      is_demuxer_ready_(false),
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      audio_stream_(NULL),
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      video_stream_(NULL),
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      seeking_(false),
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      is_video_encrypted_(false),
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      doing_browser_seek_(false),
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      browser_seek_time_(media::kNoTimestamp()),
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      expecting_regular_seek_(false),
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      access_unit_size_(0),
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      main_task_runner_(base::MessageLoopProxy::current()),
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      media_task_runner_(media_task_runner),
6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      main_weak_factory_(this),
6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      media_weak_factory_(this),
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      main_weak_this_(main_weak_factory_.GetWeakPtr()) {
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaSourceDelegate::~MediaSourceDelegate() {
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_;
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!chunk_demuxer_);
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(!demuxer_client_);
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!audio_decrypting_demuxer_stream_);
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!video_decrypting_demuxer_stream_);
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!audio_stream_);
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!video_stream_);
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MediaSourceDelegate::Stop(const base::Closure& stop_cb) {
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_;
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!chunk_demuxer_) {
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(!demuxer_client_);
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  duration_change_cb_.Reset();
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  update_network_state_cb_.Reset();
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  media_source_opened_cb_.Reset();
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  main_weak_factory_.InvalidateWeakPtrs();
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!main_weak_factory_.HasWeakPtrs());
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chunk_demuxer_->Shutdown();
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Continue to stop objects on the media thread.
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  media_task_runner_->PostTask(
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FROM_HERE,
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &MediaSourceDelegate::StopDemuxer, base::Unretained(this), stop_cb));
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaSourceDelegate::IsVideoEncrypted() {
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::AutoLock auto_lock(is_video_encrypted_lock_);
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return is_video_encrypted_;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::Time MediaSourceDelegate::GetTimelineOffset() const {
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!chunk_demuxer_)
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return base::Time();
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return chunk_demuxer_->GetTimelineOffset();
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MediaSourceDelegate::StopDemuxer(const base::Closure& stop_cb) {
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(2) << __FUNCTION__;
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(chunk_demuxer_);
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  demuxer_client_->RemoveDelegate(demuxer_client_id_);
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  demuxer_client_ = NULL;
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  audio_stream_ = NULL;
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  video_stream_ = NULL;
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(xhwang): Figure out if we need to Reset the DDSs after Seeking or
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // before destroying them.
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  audio_decrypting_demuxer_stream_.reset();
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  video_decrypting_demuxer_stream_.reset();
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  media_weak_factory_.InvalidateWeakPtrs();
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!media_weak_factory_.HasWeakPtrs());
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  chunk_demuxer_->Stop();
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  chunk_demuxer_.reset();
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |this| may be destroyed at this point in time as a result of running
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |stop_cb|.
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  stop_cb.Run();
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaSourceDelegate::InitializeMediaSource(
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const MediaSourceOpenedCB& media_source_opened_cb,
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const media::Demuxer::NeedKeyCB& need_key_cb,
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const media::SetDecryptorReadyCB& set_decryptor_ready_cb,
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const UpdateNetworkStateCB& update_network_state_cb,
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const DurationChangeCB& duration_change_cb) {
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!media_source_opened_cb.is_null());
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  media_source_opened_cb_ = media_source_opened_cb;
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  need_key_cb_ = need_key_cb;
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  set_decryptor_ready_cb_ = set_decryptor_ready_cb;
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb);
161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  duration_change_cb_ = duration_change_cb;
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  access_unit_size_ = kAccessUnitSizeForMediaSource;
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  chunk_demuxer_.reset(new media::ChunkDemuxer(
165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      media::BindToCurrentLoop(
166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          base::Bind(&MediaSourceDelegate::OnDemuxerOpened, main_weak_this_)),
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      media::BindToCurrentLoop(
168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          base::Bind(&MediaSourceDelegate::OnNeedKey, main_weak_this_)),
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::Bind(&LogMediaSourceError, media_log_),
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      false));
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // |this| will be retained until StopDemuxer() is posted, so Unretained() is
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // safe here.
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  media_task_runner_->PostTask(FROM_HERE,
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        base::Bind(&MediaSourceDelegate::InitializeDemuxer,
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        base::Unretained(this)));
1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaSourceDelegate::InitializeDemuxer() {
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  demuxer_client_->AddDelegate(demuxer_client_id_, this);
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chunk_demuxer_->Initialize(this,
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             base::Bind(&MediaSourceDelegate::OnDemuxerInitDone,
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        media_weak_factory_.GetWeakPtr()),
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             false);
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)blink::WebTimeRanges MediaSourceDelegate::Buffered() const {
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return media::ConvertToWebTimeRanges(buffered_time_ranges_);
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t MediaSourceDelegate::DecodedFrameCount() const {
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return statistics_.video_frames_decoded;
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t MediaSourceDelegate::DroppedFrameCount() const {
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return statistics_.video_frames_dropped;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t MediaSourceDelegate::AudioDecodedByteCount() const {
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return statistics_.audio_bytes_decoded;
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)size_t MediaSourceDelegate::VideoDecodedByteCount() const {
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return statistics_.video_bytes_decoded;
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourceDelegate::CancelPendingSeek(const base::TimeDelta& seek_time) {
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ") : "
211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)           << demuxer_client_id_;
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!chunk_demuxer_)
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Remember to trivially finish any newly arriving browser seek requests
2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // that may arrive prior to the next regular seek request.
2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::AutoLock auto_lock(seeking_lock_);
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    expecting_regular_seek_ = true;
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Cancel any previously expected or in-progress regular or browser seek.
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // It is possible that we have just finished the seek, but caller does
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // not know this yet. It is still safe to cancel in this case because the
2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // caller will always call StartWaitingForSeek() when it is notified of
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the finished seek.
2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  chunk_demuxer_->CancelPendingSeek(seek_time);
22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourceDelegate::StartWaitingForSeek(
23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::TimeDelta& seek_time) {
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ") : "
23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)           << demuxer_client_id_;
23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!chunk_demuxer_)
2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool cancel_browser_seek = false;
2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Remember to trivially finish any newly arriving browser seek requests
2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // that may arrive prior to the next regular seek request.
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::AutoLock auto_lock(seeking_lock_);
2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    expecting_regular_seek_ = true;
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Remember to cancel any in-progress browser seek.
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (seeking_) {
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DCHECK(doing_browser_seek_);
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      cancel_browser_seek = true;
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (cancel_browser_seek)
2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    chunk_demuxer_->CancelPendingSeek(seek_time);
2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  chunk_demuxer_->StartWaitingForSeek(seek_time);
25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaSourceDelegate::Seek(
2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const base::TimeDelta& seek_time, bool is_browser_seek) {
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ", "
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)           << (is_browser_seek ? "browser seek" : "regular seek") << ") : "
26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)           << demuxer_client_id_;
26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::TimeDelta internal_seek_time = seek_time;
2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::AutoLock auto_lock(seeking_lock_);
2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(!seeking_);
2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    seeking_ = true;
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    doing_browser_seek_ = is_browser_seek;
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (doing_browser_seek_ && (!chunk_demuxer_ || expecting_regular_seek_)) {
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // Trivially finish the browser seek without actually doing it. Reads will
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // continue to be |kAborted| until the next regular seek is done. Browser
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // seeking is not supported unless using a ChunkDemuxer; browser seeks are
2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // trivially finished if |chunk_demuxer_| is NULL.
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      seeking_ = false;
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      doing_browser_seek_ = false;
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      demuxer_client_->DemuxerSeekDone(demuxer_client_id_, seek_time);
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return;
2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (doing_browser_seek_) {
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      internal_seek_time = FindBufferedBrowserSeekTime_Locked(seek_time);
2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      browser_seek_time_ = internal_seek_time;
2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else {
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      expecting_regular_seek_ = false;
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      browser_seek_time_ = media::kNoTimestamp();
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Prepare |chunk_demuxer_| for browser seek.
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (is_browser_seek) {
2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    chunk_demuxer_->CancelPendingSeek(internal_seek_time);
2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    chunk_demuxer_->StartWaitingForSeek(internal_seek_time);
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SeekInternal(internal_seek_time);
30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourceDelegate::SeekInternal(const base::TimeDelta& seek_time) {
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(IsSeeking());
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chunk_demuxer_->Seek(seek_time, base::Bind(
30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      &MediaSourceDelegate::OnDemuxerSeekDone,
30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      media_weak_factory_.GetWeakPtr()));
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start,
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               base::TimeDelta end) {
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  buffered_time_ranges_.Add(start, end);
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaSourceDelegate::SetDuration(base::TimeDelta duration) {
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << duration.InSecondsF() << ") : "
318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)           << demuxer_client_id_;
319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Force duration change notification to be async to avoid reentrancy into
321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // ChunkDemxuer.
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  main_task_runner_->PostTask(FROM_HERE, base::Bind(
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      &MediaSourceDelegate::OnDurationChanged, main_weak_this_, duration));
324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void MediaSourceDelegate::OnDurationChanged(const base::TimeDelta& duration) {
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (demuxer_client_)
329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    demuxer_client_->DurationChanged(demuxer_client_id_, duration);
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!duration_change_cb_.is_null())
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    duration_change_cb_.Run(duration);
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) {
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << type << ") : " << demuxer_client_id_;
3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsSeeking())
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;  // Drop the request during seeking.
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO);
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The access unit size should have been initialized properly at this stage.
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GT(access_unit_size_, 0u);
343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<DemuxerData> data(new DemuxerData());
344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  data->type = type;
345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  data->access_units.resize(access_unit_size_);
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ReadFromDemuxerStream(type, data.Pass(), 0);
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaSourceDelegate::ReadFromDemuxerStream(media::DemuxerStream::Type type,
350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                                scoped_ptr<DemuxerData> data,
351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                                size_t index) {
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // DemuxerStream::Read() always returns the read callback asynchronously.
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DemuxerStream* stream =
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      (type == DemuxerStream::AUDIO) ? audio_stream_ : video_stream_;
3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  stream->Read(base::Bind(
3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &MediaSourceDelegate::OnBufferReady,
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      media_weak_factory_.GetWeakPtr(), type, base::Passed(&data), index));
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaSourceDelegate::OnBufferReady(
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    media::DemuxerStream::Type type,
363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<DemuxerData> data,
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    size_t index,
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream::Status status,
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const scoped_refptr<media::DecoderBuffer>& buffer) {
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
368d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << index << ", " << status << ", "
369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           << ((!buffer || buffer->end_of_stream()) ?
370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)               -1 : buffer->timestamp().InMilliseconds())
371d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)           << ") : " << demuxer_client_id_;
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(chunk_demuxer_);
373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // No new OnReadFromDemuxer() will be called during seeking. So this callback
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // must be from previous OnReadFromDemuxer() call and should be ignored.
3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsSeeking()) {
377d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DVLOG(1) << __FUNCTION__ << ": Ignore previous read during seeking.";
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool is_audio = (type == DemuxerStream::AUDIO);
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (status != DemuxerStream::kAborted &&
383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      index >= data->access_units.size()) {
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LOG(ERROR) << "The internal state inconsistency onBufferReady: "
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               << (is_audio ? "Audio" : "Video") << ", index " << index
386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)               << ", size " << data->access_units.size()
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               << ", status " << static_cast<int>(status);
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NOTREACHED();
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (status) {
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case DemuxerStream::kAborted:
394d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      DVLOG(1) << __FUNCTION__ << " : Aborted";
395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      data->access_units[index].status = status;
396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      data->access_units.resize(index + 1);
397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      break;
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case DemuxerStream::kConfigChanged:
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CHECK((is_audio && audio_stream_) || (!is_audio && video_stream_));
401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      data->demuxer_configs.resize(1);
402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CHECK(GetDemuxerConfigFromStream(&data->demuxer_configs[0], is_audio));
403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (!is_audio) {
404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        gfx::Size size = data->demuxer_configs[0].video_size;
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        DVLOG(1) << "Video config is changed: " << size.width() << "x"
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 << size.height();
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      data->access_units[index].status = status;
409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      data->access_units.resize(index + 1);
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case DemuxerStream::kOk:
413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      data->access_units[index].status = status;
414ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (buffer->end_of_stream()) {
415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        data->access_units[index].end_of_stream = true;
416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        data->access_units.resize(index + 1);
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // TODO(ycheo): We assume that the inputed stream will be decoded
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // right away.
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Need to implement this properly using MediaPlayer.OnInfoListener.
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (is_audio) {
423ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        statistics_.audio_bytes_decoded += buffer->data_size();
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
425ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        statistics_.video_bytes_decoded += buffer->data_size();
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        statistics_.video_frames_decoded++;
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      data->access_units[index].timestamp = buffer->timestamp();
4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      data->access_units[index].data.assign(
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          buffer->data(), buffer->data() + buffer->data_size());
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // Vorbis needs 4 extra bytes padding on Android. Check
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // NuMediaExtractor.cpp in Android source code.
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (is_audio && media::kCodecVorbis ==
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          audio_stream_->audio_decoder_config().codec()) {
436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        data->access_units[index].data.insert(
437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)            data->access_units[index].data.end(), kVorbisPadding,
43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            kVorbisPadding + 4);
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (buffer->decrypt_config()) {
441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        data->access_units[index].key_id = std::vector<char>(
442ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            buffer->decrypt_config()->key_id().begin(),
443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            buffer->decrypt_config()->key_id().end());
444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        data->access_units[index].iv = std::vector<char>(
445ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            buffer->decrypt_config()->iv().begin(),
446ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            buffer->decrypt_config()->iv().end());
447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        data->access_units[index].subsamples =
448ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            buffer->decrypt_config()->subsamples();
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      if (++index < data->access_units.size()) {
451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        ReadFromDemuxerStream(type, data.Pass(), index);
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED();
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
460d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!IsSeeking() && demuxer_client_)
461d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    demuxer_client_->ReadFromDemuxerAck(demuxer_client_id_, *data);
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnDemuxerError(media::PipelineStatus status) {
465d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_;
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // |update_network_state_cb_| is bound to the main thread.
46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (status != media::PIPELINE_OK && !update_network_state_cb_.is_null())
46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    update_network_state_cb_.Run(PipelineErrorToNetworkState(status));
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaSourceDelegate::AddTextStream(
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    media::DemuxerStream* /* text_stream */ ,
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const media::TextTrackConfig& /* config */ ) {
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(matthewjheaney): add text stream (http://crbug/322115).
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTIMPLEMENTED();
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaSourceDelegate::RemoveTextStream(
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    media::DemuxerStream* /* text_stream */ ) {
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(matthewjheaney): remove text stream (http://crbug/322115).
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTIMPLEMENTED();
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) {
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_;
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(chunk_demuxer_);
488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (status != media::PIPELINE_OK) {
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    OnDemuxerError(status);
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  audio_stream_ = chunk_demuxer_->GetStream(DemuxerStream::AUDIO);
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  video_stream_ = chunk_demuxer_->GetStream(DemuxerStream::VIDEO);
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (audio_stream_ && audio_stream_->audio_decoder_config().is_encrypted() &&
4987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      !set_decryptor_ready_cb_.is_null()) {
499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    InitAudioDecryptingDemuxerStream();
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // InitVideoDecryptingDemuxerStream() will be called in
501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // OnAudioDecryptingDemuxerStreamInitDone().
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (video_stream_ && video_stream_->video_decoder_config().is_encrypted() &&
5067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      !set_decryptor_ready_cb_.is_null()) {
507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    InitVideoDecryptingDemuxerStream();
508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Notify demuxer ready when both streams are not encrypted.
512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  is_demuxer_ready_ = true;
513f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NotifyDemuxerReady();
514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::InitAudioDecryptingDemuxerStream() {
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_;
5197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!set_decryptor_ready_cb_.is_null());
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream(
5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      media_task_runner_, set_decryptor_ready_cb_));
523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  audio_decrypting_demuxer_stream_->Initialize(
524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      audio_stream_,
5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      base::Bind(&MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone,
52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 media_weak_factory_.GetWeakPtr()));
527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::InitVideoDecryptingDemuxerStream() {
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
531d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_;
5327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!set_decryptor_ready_cb_.is_null());
5337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream(
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      media_task_runner_, set_decryptor_ready_cb_));
536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  video_decrypting_demuxer_stream_->Initialize(
537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      video_stream_,
5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      base::Bind(&MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone,
53958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 media_weak_factory_.GetWeakPtr()));
540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone(
543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    media::PipelineStatus status) {
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
545d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_;
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(chunk_demuxer_);
547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (status != media::PIPELINE_OK)
549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    audio_decrypting_demuxer_stream_.reset();
550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  else
551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    audio_stream_ = audio_decrypting_demuxer_stream_.get();
552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (video_stream_ && video_stream_->video_decoder_config().is_encrypted()) {
554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    InitVideoDecryptingDemuxerStream();
555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Try to notify demuxer ready when audio DDS initialization finished and
559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // video is not encrypted.
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  is_demuxer_ready_ = true;
561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NotifyDemuxerReady();
562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone(
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    media::PipelineStatus status) {
5661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
567d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_;
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(chunk_demuxer_);
569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (status != media::PIPELINE_OK)
571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    video_decrypting_demuxer_stream_.reset();
572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  else
573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    video_stream_ = video_decrypting_demuxer_stream_.get();
574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Try to notify demuxer ready when video DDS initialization finished.
576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  is_demuxer_ready_ = true;
577f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NotifyDemuxerReady();
578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
58068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaSourceDelegate::OnDemuxerSeekDone(media::PipelineStatus status) {
5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
582d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_;
5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(IsSeeking());
584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (status != media::PIPELINE_OK) {
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnDemuxerError(status);
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ResetAudioDecryptingDemuxerStream();
591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() {
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
595d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_;
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (audio_decrypting_demuxer_stream_) {
597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    audio_decrypting_demuxer_stream_->Reset(
598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::Bind(&MediaSourceDelegate::ResetVideoDecryptingDemuxerStream,
59958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   media_weak_factory_.GetWeakPtr()));
60058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
60258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ResetVideoDecryptingDemuxerStream();
604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() {
6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
608d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_;
609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (video_decrypting_demuxer_stream_) {
61058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    video_decrypting_demuxer_stream_->Reset(base::Bind(
61158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams,
61258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        media_weak_factory_.GetWeakPtr()));
61358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
61558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
61658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FinishResettingDecryptingDemuxerStreams();
61758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
61858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
61958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams() {
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
621d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_;
6221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::AutoLock auto_lock(seeking_lock_);
6241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(seeking_);
6251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  seeking_ = false;
6261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  doing_browser_seek_ = false;
6271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  demuxer_client_->DemuxerSeekDone(demuxer_client_id_, browser_seek_time_);
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaSourceDelegate::NotifyDemuxerReady() {
6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
632d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_;
633f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(is_demuxer_ready_);
634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
635424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<DemuxerConfigs> configs(new DemuxerConfigs());
636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetDemuxerConfigFromStream(configs.get(), true);
637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetDemuxerConfigFromStream(configs.get(), false);
6380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  configs->duration = GetDuration();
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
640d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (demuxer_client_)
641d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    demuxer_client_->DemuxerReady(demuxer_client_id_, *configs);
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::AutoLock auto_lock(is_video_encrypted_lock_);
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  is_video_encrypted_ = configs->is_video_encrypted;
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::TimeDelta MediaSourceDelegate::GetDuration() const {
6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!chunk_demuxer_)
6500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return media::kNoTimestamp();
651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  double duration = chunk_demuxer_->GetDuration();
6530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (duration == std::numeric_limits<double>::infinity())
6540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return media::kInfiniteDuration();
6550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return media::ConvertSecondsToTimestamp(duration);
657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaSourceDelegate::OnDemuxerOpened() {
6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
6613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (media_source_opened_cb_.is_null())
66290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
66390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  media_source_opened_cb_.Run(new media::WebMediaSourceImpl(
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_)));
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MediaSourceDelegate::OnNeedKey(const std::string& type,
669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                    const std::vector<uint8>& init_data) {
6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(main_task_runner_->BelongsToCurrentThread());
671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (need_key_cb_.is_null())
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  need_key_cb_.Run(type, init_data);
67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaSourceDelegate::IsSeeking() const {
6783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::AutoLock auto_lock(seeking_lock_);
6793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return seeking_;
6803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::TimeDelta MediaSourceDelegate::FindBufferedBrowserSeekTime_Locked(
6831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const base::TimeDelta& seek_time) const {
6841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  seeking_lock_.AssertAcquired();
6851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(seeking_);
6861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(doing_browser_seek_);
6871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(chunk_demuxer_) << "Browser seek requested, but no chunk demuxer";
6881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  media::Ranges<base::TimeDelta> buffered =
6901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      chunk_demuxer_->GetBufferedRanges();
6911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < buffered.size(); ++i) {
6931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::TimeDelta range_start = buffered.start(i);
6941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::TimeDelta range_end = buffered.end(i);
6951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (range_start <= seek_time) {
6961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (range_end >= seek_time)
6971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        return seek_time;
6981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      continue;
6991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
7001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // If the start of the next buffered range after |seek_time| is too far
7021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // into the future, do not jump forward.
7031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if ((range_start - seek_time) > base::TimeDelta::FromMilliseconds(100))
7041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      break;
7051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // TODO(wolenetz): Remove possibility that this browser seek jumps
7071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // into future when the requested range is unbuffered but there is some
7081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // other buffered range after it. See http://crbug.com/304234.
7091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return range_start;
7101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
7111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // We found no range containing |seek_time| or beginning shortly after
7131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // |seek_time|. While possible that such data at and beyond the player's
7141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // current time have been garbage collected or removed by the web app, this is
7151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // unlikely. This may cause unexpected playback stall due to seek pending an
7161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // append for a GOP prior to the last GOP demuxed.
7171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(wolenetz): Remove the possibility for this seek to cause unexpected
7181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // player stall by replaying cached data since last keyframe in browser player
7191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // rather than issuing browser seek. See http://crbug.com/304234.
7201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return seek_time;
7211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
7221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool MediaSourceDelegate::GetDemuxerConfigFromStream(
724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    media::DemuxerConfigs* configs, bool is_audio) {
7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(media_task_runner_->BelongsToCurrentThread());
726f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!is_demuxer_ready_)
727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (is_audio && audio_stream_) {
729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    media::AudioDecoderConfig config = audio_stream_->audio_decoder_config();
730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->audio_codec = config.codec();
731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->audio_channels =
732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        media::ChannelLayoutToChannelCount(config.channel_layout());
733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->audio_sampling_rate = config.samples_per_second();
734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->is_audio_encrypted = config.is_encrypted();
735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->audio_extra_data = std::vector<uint8>(
736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        config.extra_data(), config.extra_data() + config.extra_data_size());
737cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!is_audio && video_stream_) {
740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    media::VideoDecoderConfig config = video_stream_->video_decoder_config();
741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->video_codec = config.codec();
742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->video_size = config.natural_size();
743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->is_video_encrypted = config.is_encrypted();
744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    configs->video_extra_data = std::vector<uint8>(
745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        config.extra_data(), config.extra_data() + config.extra_data_size());
746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return false;
749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace content
752