Skip to content

Commit

Permalink
Revert of Revert of Chromecast: Play audio streams not supported by C…
Browse files Browse the repository at this point in the history
…MA via default renderer (patchset chromium#1 id:1 of https://codereview.chromium.org/981473003/)

Reason for revert:
Hmmm... My revert did not fix the test, so I'm undoing it. :/

Original issue's description:
> Revert of Chromecast: Play audio streams not supported by CMA via default renderer (patchset chromium#5 id:70001 of https://codereview.chromium.org/973633002/)
>
> Reason for revert:
> Audio tests started failing consistently in the next build after this was checked in. See:
> https://build.chromium.org/p/chromium.mac/builders/Mac10.9%20Tests/builds/3762
>
> Not sure if this CL is the culprit, but seems the most likely one, so attempting a revert to see if it fixes the problem.
>
> Error:
> [ RUN      ] AudioRecorderTest.BasicRecordAndStop
> ../../components/audio_modem/audio_recorder_unittest.cc:203: Failure
> Value of: IsRecording()
> Actual: false
> Expected: true
> ../../components/audio_modem/audio_recorder_unittest.cc:208: Failure
> Value of: IsRecording()
> Actual: false
> Expected: true
> ../../components/audio_modem/audio_recorder_unittest.cc:213: Failure
> Value of: IsRecording()
> Actual: false
> Expected: true
> [  FAILED  ] AudioRecorderTest.BasicRecordAndStop (1292 ms)
>
> Original issue's description:
> > Chromecast: Play audio streams not supported by CMA via default renderer
> >
> > For Chromecast we want to choose which media renderer to use based on
> > the types of input content streams. We will use CMA media renderer for
> > media types that are supported by our hardware (H264, AAC, etc) and
> > will use the default media renderer for audio streams other than AAC
> > or Vorbis. This will allow us support software decoding of FLAC and
> > Opus via the default Chrome audio path.
> >
> > BUG=457959
> >
> > Committed: https://crrev.com/2e583073b996e66d62f709dd2ffde9e1ef58b276
> > Cr-Commit-Position: refs/heads/master@{#318941}
>
> TBR=gunsch@chromium.org,lcwu@chromium.org,dalecurtis@chromium.org,servolk@chromium.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=457959
>
> Committed: https://crrev.com/ee687fd9c6c2bc41642cd8b65de87fe548a3cf75
> Cr-Commit-Position: refs/heads/master@{#319033}

TBR=gunsch@chromium.org,lcwu@chromium.org,dalecurtis@chromium.org,servolk@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=457959

Review URL: https://codereview.chromium.org/967933003

Cr-Commit-Position: refs/heads/master@{#319046}
  • Loading branch information
finnurbreki authored and Commit bot committed Mar 4, 2015
1 parent 7626cca commit e67565c
Show file tree
Hide file tree
Showing 10 changed files with 292 additions and 74 deletions.
4 changes: 2 additions & 2 deletions chromecast/chromecast.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,8 @@
'common/media/shared_memory_chunk.h',
'renderer/media/audio_pipeline_proxy.cc',
'renderer/media/audio_pipeline_proxy.h',
'renderer/media/cma_media_renderer_factory.cc',
'renderer/media/cma_media_renderer_factory.h',
'renderer/media/chromecast_media_renderer_factory.cc',
'renderer/media/chromecast_media_renderer_factory.h',
'renderer/media/cma_message_filter_proxy.cc',
'renderer/media/cma_message_filter_proxy.h',
'renderer/media/media_channel_proxy.cc',
Expand Down
102 changes: 102 additions & 0 deletions chromecast/media/base/switching_media_renderer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromecast/media/base/switching_media_renderer.h"

#include "base/logging.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/demuxer_stream.h"
#include "media/base/demuxer_stream_provider.h"

namespace chromecast {
namespace media {

SwitchingMediaRenderer::SwitchingMediaRenderer(
scoped_ptr<::media::Renderer> default_renderer,
scoped_ptr<::media::Renderer> cma_renderer)
: default_renderer_(default_renderer.Pass()),
cma_renderer_(cma_renderer.Pass()) {
DCHECK(default_renderer_);
DCHECK(cma_renderer_);
}

SwitchingMediaRenderer::~SwitchingMediaRenderer() {
}

void SwitchingMediaRenderer::Initialize(
::media::DemuxerStreamProvider* demuxer_stream_provider,
const base::Closure& init_cb,
const ::media::StatisticsCB& statistics_cb,
const ::media::BufferingStateCB& buffering_state_cb,
const ::media::Renderer::PaintCB& paint_cb,
const base::Closure& ended_cb,
const ::media::PipelineStatusCB& error_cb) {
// At this point the DemuxerStreamProvider should be fully initialized, so we
// have enough information to decide which renderer to use.
demuxer_stream_provider_ = demuxer_stream_provider;
DCHECK(demuxer_stream_provider_);
::media::DemuxerStream* audio_stream =
demuxer_stream_provider_->GetStream(::media::DemuxerStream::AUDIO);
::media::DemuxerStream* video_stream =
demuxer_stream_provider_->GetStream(::media::DemuxerStream::VIDEO);
if (audio_stream && !video_stream &&
audio_stream->audio_decoder_config().codec() != ::media::kCodecAAC &&
audio_stream->audio_decoder_config().codec() != ::media::kCodecVorbis) {
// We'll use the default Chrome media renderer with software audio decoding
cma_renderer_.reset();
} else {
// We'll use the CMA-based rendering with hardware decoding
default_renderer_.reset();
}

return GetRenderer()->Initialize(demuxer_stream_provider,
init_cb, statistics_cb, buffering_state_cb,
paint_cb, ended_cb, error_cb);
}

::media::Renderer* SwitchingMediaRenderer::GetRenderer() const {
DCHECK(default_renderer_ || cma_renderer_);
if (cma_renderer_)
return cma_renderer_.get();

DCHECK(default_renderer_);
return default_renderer_.get();
}

void SwitchingMediaRenderer::SetCdm(
::media::CdmContext* cdm_context,
const ::media::CdmAttachedCB& cdm_attached_cb) {
GetRenderer()->SetCdm(cdm_context, cdm_attached_cb);
}

void SwitchingMediaRenderer::Flush(const base::Closure& flush_cb) {
GetRenderer()->Flush(flush_cb);
}

void SwitchingMediaRenderer::StartPlayingFrom(base::TimeDelta time) {
GetRenderer()->StartPlayingFrom(time);
}

void SwitchingMediaRenderer::SetPlaybackRate(float playback_rate) {
GetRenderer()->SetPlaybackRate(playback_rate);
}

void SwitchingMediaRenderer::SetVolume(float volume) {
GetRenderer()->SetVolume(volume);
}

base::TimeDelta SwitchingMediaRenderer::GetMediaTime() {
return GetRenderer()->GetMediaTime();
}

bool SwitchingMediaRenderer::HasAudio() {
return GetRenderer()->HasAudio();
}

bool SwitchingMediaRenderer::HasVideo() {
return GetRenderer()->HasVideo();
}

} // namespace media
} // namespace chromecast
66 changes: 66 additions & 0 deletions chromecast/media/base/switching_media_renderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMECAST_MEDIA_BASE_SWITCHING_MEDIA_RENDERER_H_
#define CHROMECAST_MEDIA_BASE_SWITCHING_MEDIA_RENDERER_H_

#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/renderer.h"

namespace media {
class DemuxerStreamProvider;
}

namespace chromecast {
namespace media {

// Chromecast's custom media renderer which is capable of selecting an
// appropriate media renderer at runtime depending on the content.
// We'll look at media types of media streams present in DemuxerStreamProvider
// and will use either CMA-based renderer (for media types that are supported by
// our hardware decoder - H264 and VP8 video, AAC and Vorbis audio) or the
// default Chrome media renderer (this will allow us to support audio codecs
// like FLAC and Opus, which are decoded in software).
class SwitchingMediaRenderer : public ::media::Renderer {
public:
SwitchingMediaRenderer(
scoped_ptr<::media::Renderer> default_renderer,
scoped_ptr<::media::Renderer> cma_renderer);
~SwitchingMediaRenderer() override;

// ::media::Renderer implementation:
void Initialize(
::media::DemuxerStreamProvider* demuxer_stream_provider,
const base::Closure& init_cb,
const ::media::StatisticsCB& statistics_cb,
const ::media::BufferingStateCB& buffering_state_cb,
const ::media::Renderer::PaintCB& paint_cb,
const base::Closure& ended_cb,
const ::media::PipelineStatusCB& error_cb) override;
void SetCdm(::media::CdmContext* cdm_context,
const ::media::CdmAttachedCB& cdm_attached_cb) override;
void Flush(const base::Closure& flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(float playback_rate) override;
void SetVolume(float volume) override;
base::TimeDelta GetMediaTime() override;
bool HasAudio() override;
bool HasVideo() override;

private:
// Returns the pointer to the actual renderer being used
::media::Renderer* GetRenderer() const;

::media::DemuxerStreamProvider* demuxer_stream_provider_;
scoped_ptr<::media::Renderer> default_renderer_;
scoped_ptr<::media::Renderer> cma_renderer_;

DISALLOW_COPY_AND_ASSIGN(SwitchingMediaRenderer);
};

} // namespace media
} // namespace chromecast

#endif // CHROMECAST_MEDIA_BASE_SWITCHING_MEDIA_RENDERER_H_
2 changes: 2 additions & 0 deletions chromecast/media/media.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
'base/decrypt_context_clearkey.h',
'base/key_systems_common.cc',
'base/key_systems_common.h',
'base/switching_media_renderer.cc',
'base/switching_media_renderer.h',
],
'conditions': [
['chromecast_branding=="Chrome"', {
Expand Down
1 change: 1 addition & 0 deletions chromecast/renderer/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ include_rules = [
"+components/network_hints/renderer",
"+content/public/renderer",
"+media/base",
"+media/renderers",
"+third_party/WebKit/public/platform",
"+third_party/WebKit/public/web",
]
6 changes: 3 additions & 3 deletions chromecast/renderer/cast_content_renderer_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "chromecast/renderer/cast_media_load_deferrer.h"
#include "chromecast/renderer/cast_render_process_observer.h"
#include "chromecast/renderer/key_systems_cast.h"
#include "chromecast/renderer/media/cma_media_renderer_factory.h"
#include "chromecast/renderer/media/chromecast_media_renderer_factory.h"
#include "components/network_hints/renderer/prescient_networking_dispatcher.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
Expand Down Expand Up @@ -160,8 +160,8 @@ CastContentRendererClient::CreateMediaRendererFactory(
return nullptr;

return scoped_ptr<::media::RendererFactory>(
new chromecast::media::CmaMediaRendererFactory(
render_frame->GetRoutingID()));
new chromecast::media::ChromecastMediaRendererFactory(
media_log, render_frame->GetRoutingID()));
}
#endif

Expand Down
73 changes: 73 additions & 0 deletions chromecast/renderer/media/chromecast_media_renderer_factory.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromecast/renderer/media/chromecast_media_renderer_factory.h"

#include "base/command_line.h"
#include "chromecast/media/base/switching_media_renderer.h"
#include "chromecast/media/cma/filters/cma_renderer.h"
#include "chromecast/renderer/media/media_pipeline_proxy.h"
#include "content/public/renderer/render_thread.h"
#include "media/base/audio_hardware_config.h"
#include "media/base/media_log.h"
#include "media/renderers/default_renderer_factory.h"

namespace chromecast {
namespace media {

ChromecastMediaRendererFactory::ChromecastMediaRendererFactory(
const scoped_refptr<::media::MediaLog>& media_log,
int render_frame_id)
: render_frame_id_(render_frame_id),
media_log_(media_log) {
}

ChromecastMediaRendererFactory::~ChromecastMediaRendererFactory() {
}

scoped_ptr<::media::Renderer> ChromecastMediaRendererFactory::CreateRenderer(
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
::media::AudioRendererSink* audio_renderer_sink) {
if (!default_render_factory_) {
// Chromecast doesn't have input audio devices, so leave this uninitialized
::media::AudioParameters input_audio_params;
// TODO(servolk): Audio parameters are hardcoded for now, but in the future
// either we need to obtain AudioHardwareConfig from RenderThreadImpl,
// or media renderer needs to figure out optimal audio parameters itself.
const int kDefaultSamplingRate = 48000;
const int kDefaultBitsPerSample = 16;
// About 20ms of stereo (2 channels) 16bit (2 byte) audio
int buffer_size = kDefaultSamplingRate * 20 * 2 * 2 / 1000;
::media::AudioParameters output_audio_params(
::media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
::media::CHANNEL_LAYOUT_STEREO,
kDefaultSamplingRate, kDefaultBitsPerSample,
buffer_size, ::media::AudioParameters::NO_EFFECTS);
::media::AudioHardwareConfig audio_config(input_audio_params,
output_audio_params);

default_render_factory_.reset(new ::media::DefaultRendererFactory(
media_log_, /*gpu_factories*/ nullptr, audio_config));
}

DCHECK(default_render_factory_);
// TODO(erickung): crbug.com/443956. Need to provide right LoadType.
LoadType cma_load_type = kLoadTypeMediaSource;
scoped_ptr<MediaPipeline> cma_media_pipeline(
new MediaPipelineProxy(
render_frame_id_,
content::RenderThread::Get()->GetIOMessageLoopProxy(),
cma_load_type));
scoped_ptr<CmaRenderer> cma_renderer(
new CmaRenderer(cma_media_pipeline.Pass()));
scoped_ptr<::media::Renderer> default_media_render(
default_render_factory_->CreateRenderer(media_task_runner,
audio_renderer_sink));
scoped_ptr<SwitchingMediaRenderer> media_renderer(new SwitchingMediaRenderer(
default_media_render.Pass(), cma_renderer.Pass()));
return media_renderer.Pass();
}

} // namespace media
} // namespace chromecast
43 changes: 43 additions & 0 deletions chromecast/renderer/media/chromecast_media_renderer_factory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMECAST_RENDERER_MEDIA_CHROMECAST_MEDIA_RENDERER_FACTORY_H_
#define CHROMECAST_RENDERER_MEDIA_CHROMECAST_MEDIA_RENDERER_FACTORY_H_

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/base/renderer_factory.h"

namespace media {
class MediaLog;
class DefaultRendererFactory;
}

namespace chromecast {
namespace media {

class ChromecastMediaRendererFactory : public ::media::RendererFactory {
public:
ChromecastMediaRendererFactory(
const scoped_refptr<::media::MediaLog>& media_log,
int render_frame_id);
~ChromecastMediaRendererFactory() final;

// ::media::RendererFactory implementation.
scoped_ptr<::media::Renderer> CreateRenderer(
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
::media::AudioRendererSink* audio_renderer_sink) final;

private:
int render_frame_id_;
scoped_refptr<::media::MediaLog> media_log_;
scoped_ptr<::media::DefaultRendererFactory> default_render_factory_;

DISALLOW_COPY_AND_ASSIGN(ChromecastMediaRendererFactory);
};

} // namespace media
} // namespace chromecast

#endif // CHROMECAST_RENDERER_MEDIA_CHROMECAST_MEDIA_RENDERER_FACTORY_H_
37 changes: 0 additions & 37 deletions chromecast/renderer/media/cma_media_renderer_factory.cc

This file was deleted.

Loading

0 comments on commit e67565c

Please sign in to comment.