Skip to content

Commit

Permalink
media: Add support for playback of VP8 Alpha video streams
Browse files Browse the repository at this point in the history
BUG=147355
TEST=VP8 Alpha video streams play
TBR=sky

Review URL: https://chromiumcodereview.appspot.com/13886011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195339 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
vigneshv@chromium.org committed Apr 19, 2013
1 parent e69198b commit 6ac955b
Show file tree
Hide file tree
Showing 31 changed files with 881 additions and 75 deletions.
4 changes: 4 additions & 0 deletions cc/resources/video_resource_updater.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ bool VideoResourceUpdater::VerifyFrame(
switch (video_frame->format()) {
// Acceptable inputs.
case media::VideoFrame::YV12:
case media::VideoFrame::YV12A:
case media::VideoFrame::YV16:
case media::VideoFrame::NATIVE_TEXTURE:
#if defined(GOOGLE_TV)
Expand Down Expand Up @@ -76,6 +77,7 @@ static gfx::Size SoftwarePlaneDimension(

switch (input_frame_format) {
case media::VideoFrame::YV12:
case media::VideoFrame::YV12A:
return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 0.5f));
case media::VideoFrame::YV16:
return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 1.f));
Expand Down Expand Up @@ -113,8 +115,10 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(

// Only YUV software video frames are supported.
DCHECK(input_frame_format == media::VideoFrame::YV12 ||
input_frame_format == media::VideoFrame::YV12A ||
input_frame_format == media::VideoFrame::YV16);
if (input_frame_format != media::VideoFrame::YV12 &&
input_frame_format != media::VideoFrame::YV12A &&
input_frame_format != media::VideoFrame::YV16)
return VideoFrameExternalResources();

Expand Down
6 changes: 6 additions & 0 deletions chrome/app/generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -6710,6 +6710,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_ENABLE_VP9_PLAYBACK_DESCRIPTION" desc="Description for the flag to enable VP9 playback in &lt;video&gt; elements.">
Enable experimental VP9 playback in the video element.
</message>
<message name="IDS_FLAGS_ENABLE_VP8_ALPHA_PLAYBACK_NAME" desc="Title for the flag to enable VP8 Alpha playback in &lt;video&gt; elements.">
Enable VP8 Alpha playback in &lt;video&gt; elements.
</message>
<message name="IDS_FLAGS_ENABLE_VP8_ALPHA_PLAYBACK_DESCRIPTION" desc="Description for the flag to enable VP8 Alpha playback in &lt;video&gt; elements.">
Enable experimental VP8 Alpha playback in the video element.
</message>
<message name="IDS_FLAGS_ASH_AUTO_WINDOW_PLACEMENT_NAME" desc="Name for the option to enable/disable the auto window placement functionality.">
Automatic window placement.
</message>
Expand Down
7 changes: 7 additions & 0 deletions chrome/browser/about_flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,13 @@ const Experiment kExperiments[] = {
kOsDesktop,
SINGLE_VALUE_TYPE(switches::kEnableVp9Playback)
},
{
"enable-vp8-alpha-playback",
IDS_FLAGS_ENABLE_VP8_ALPHA_PLAYBACK_NAME,
IDS_FLAGS_ENABLE_VP8_ALPHA_PLAYBACK_DESCRIPTION,
kOsDesktop,
SINGLE_VALUE_TYPE(switches::kEnableVp8AlphaPlayback)
},
{
"enable-managed-users",
IDS_FLAGS_ENABLE_LOCALLY_MANAGED_USERS_NAME,
Expand Down
21 changes: 21 additions & 0 deletions content/browser/renderer_host/media/video_capture_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ void VideoCaptureController::OnIncomingCapturedVideoFrame(
const int kYPlane = media::VideoFrame::kYPlane;
const int kUPlane = media::VideoFrame::kUPlane;
const int kVPlane = media::VideoFrame::kVPlane;
const int kAPlane = media::VideoFrame::kAPlane;
const int kRGBPlane = media::VideoFrame::kRGBPlane;

// Do color conversion from the camera format to I420.
Expand Down Expand Up @@ -430,6 +431,26 @@ void VideoCaptureController::OnIncomingCapturedVideoFrame(
target);
break;
}
case media::VideoFrame::YV12A: {
DCHECK(!chopped_width_ && !chopped_height_);
media::CopyYPlane(frame->data(kYPlane),
frame->stride(kYPlane),
frame->rows(kYPlane),
target);
media::CopyUPlane(frame->data(kUPlane),
frame->stride(kUPlane),
frame->rows(kUPlane),
target);
media::CopyVPlane(frame->data(kVPlane),
frame->stride(kVPlane),
frame->rows(kVPlane),
target);
media::CopyAPlane(frame->data(kAPlane),
frame->stride(kAPlane),
frame->rows(kAPlane),
target);
break;
}
case media::VideoFrame::RGB32: {
media::ConvertRGB32ToYUV(frame->data(kRGBPlane),
target->data(kYPlane),
Expand Down
1 change: 1 addition & 0 deletions content/browser/renderer_host/render_process_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kEnableViewport,
switches::kEnableOpusPlayback,
switches::kEnableVp9Playback,
switches::kEnableVp8AlphaPlayback,
switches::kForceDeviceScaleFactor,
switches::kFullMemoryCrashReport,
#if !defined (GOOGLE_CHROME_BUILD)
Expand Down
48 changes: 46 additions & 2 deletions media/base/decoder_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
namespace media {

DecoderBuffer::DecoderBuffer(int size)
: size_(size) {
: size_(size),
side_data_size_(0) {
Initialize();
}

DecoderBuffer::DecoderBuffer(const uint8* data, int size)
: size_(size) {
: size_(size),
side_data_size_(0) {
if (!data) {
CHECK_EQ(size_, 0);
return;
Expand All @@ -25,13 +27,32 @@ DecoderBuffer::DecoderBuffer(const uint8* data, int size)
memcpy(data_.get(), data, size_);
}

DecoderBuffer::DecoderBuffer(const uint8* data, int size,
const uint8* side_data, int side_data_size)
: size_(size),
side_data_size_(side_data_size) {
if (!data) {
CHECK_EQ(size_, 0);
return;
}

Initialize();
memcpy(data_.get(), data, size_);
memcpy(side_data_.get(), side_data, side_data_size_);
}

DecoderBuffer::~DecoderBuffer() {}

void DecoderBuffer::Initialize() {
CHECK_GE(size_, 0);
data_.reset(reinterpret_cast<uint8*>(
base::AlignedAlloc(size_ + kPaddingSize, kAlignmentSize)));
memset(data_.get() + size_, 0, kPaddingSize);
if (side_data_size_ > 0) {
side_data_.reset(reinterpret_cast<uint8*>(
base::AlignedAlloc(side_data_size_ + kPaddingSize, kAlignmentSize)));
memset(side_data_.get() + side_data_size_, 0, kPaddingSize);
}
}

// static
Expand All @@ -42,6 +63,18 @@ scoped_refptr<DecoderBuffer> DecoderBuffer::CopyFrom(const uint8* data,
return make_scoped_refptr(new DecoderBuffer(data, data_size));
}

// static
scoped_refptr<DecoderBuffer> DecoderBuffer::CopyFrom(const uint8* data,
int data_size,
const uint8* side_data,
int side_data_size) {
// If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
CHECK(data);
CHECK(side_data);
return make_scoped_refptr(new DecoderBuffer(data, data_size,
side_data, side_data_size));
}

// static
scoped_refptr<DecoderBuffer> DecoderBuffer::CreateEOSBuffer() {
return make_scoped_refptr(new DecoderBuffer(NULL, 0));
Expand Down Expand Up @@ -82,6 +115,16 @@ int DecoderBuffer::GetDataSize() const {
return size_;
}

const uint8* DecoderBuffer::GetSideData() const {
DCHECK(!IsEndOfStream());
return side_data_.get();
}

int DecoderBuffer::GetSideDataSize() const {
DCHECK(!IsEndOfStream());
return side_data_size_;
}

const DecryptConfig* DecoderBuffer::GetDecryptConfig() const {
DCHECK(!IsEndOfStream());
return decrypt_config_.get();
Expand All @@ -105,6 +148,7 @@ std::string DecoderBuffer::AsHumanReadableString() {
s << "timestamp: " << timestamp_.InMicroseconds()
<< " duration: " << duration_.InMicroseconds()
<< " size: " << size_
<< " side_data_size: " << side_data_size_
<< " encrypted: " << (decrypt_config_ != NULL);
return s.str();
}
Expand Down
14 changes: 14 additions & 0 deletions media/base/decoder_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ class MEDIA_EXPORT DecoderBuffer
// padded and aligned as necessary. |data| must not be NULL and |size| >= 0.
static scoped_refptr<DecoderBuffer> CopyFrom(const uint8* data, int size);

// Create a DecoderBuffer whose |data_| is copied from |data| and |side_data_|
// is copied from |side_data|. Buffers will be padded and aligned as necessary
// Data pointers must not be NULL and sizes must be >= 0.
static scoped_refptr<DecoderBuffer> CopyFrom(const uint8* data, int size,
const uint8* side_data,
int side_data_size);

// Create a DecoderBuffer indicating we've reached end of stream.
//
// Calling any method other than IsEndOfStream() on the resulting buffer
Expand All @@ -64,6 +71,9 @@ class MEDIA_EXPORT DecoderBuffer

int GetDataSize() const;

const uint8* GetSideData() const;
int GetSideDataSize() const;

const DecryptConfig* GetDecryptConfig() const;
void SetDecryptConfig(scoped_ptr<DecryptConfig> decrypt_config);

Expand All @@ -80,6 +90,8 @@ class MEDIA_EXPORT DecoderBuffer
// will be padded and aligned as necessary. If |data| is NULL then |data_| is
// set to NULL and |buffer_size_| to 0.
DecoderBuffer(const uint8* data, int size);
DecoderBuffer(const uint8* data, int size,
const uint8* side_data, int side_data_size);
virtual ~DecoderBuffer();

private:
Expand All @@ -88,6 +100,8 @@ class MEDIA_EXPORT DecoderBuffer

int size_;
scoped_ptr<uint8, base::ScopedPtrAlignedFree> data_;
int side_data_size_;
scoped_ptr<uint8, base::ScopedPtrAlignedFree> side_data_;
scoped_ptr<DecryptConfig> decrypt_config_;

// Constructor helper method for memory allocations.
Expand Down
11 changes: 11 additions & 0 deletions media/base/decoder_buffer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ TEST(DecoderBufferTest, CopyFrom) {
EXPECT_EQ(buffer2->GetDataSize(), kDataSize);
EXPECT_EQ(0, memcmp(buffer2->GetData(), kData, kDataSize));
EXPECT_FALSE(buffer2->IsEndOfStream());
scoped_refptr<DecoderBuffer> buffer3(DecoderBuffer::CopyFrom(
reinterpret_cast<const uint8*>(&kData), kDataSize,
reinterpret_cast<const uint8*>(&kData), kDataSize));
ASSERT_TRUE(buffer3);
EXPECT_NE(kData, buffer3->GetData());
EXPECT_EQ(buffer3->GetDataSize(), kDataSize);
EXPECT_EQ(0, memcmp(buffer3->GetData(), kData, kDataSize));
EXPECT_NE(kData, buffer3->GetSideData());
EXPECT_EQ(buffer3->GetSideDataSize(), kDataSize);
EXPECT_EQ(0, memcmp(buffer3->GetSideData(), kData, kDataSize));
EXPECT_FALSE(buffer3->IsEndOfStream());
}

#if !defined(OS_ANDROID)
Expand Down
3 changes: 3 additions & 0 deletions media/base/media_switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ const char kEnableOpusPlayback[] = "enable-opus-playback";
// Enables VP9 playback in media elements.
const char kEnableVp9Playback[] = "enable-vp9-playback";

// Enables VP8 Alpha playback in media elements.
const char kEnableVp8AlphaPlayback[] = "enable-vp8-alpha-playback";

#if defined(OS_WIN)
const char kWaveOutBuffers[] = "waveout-buffers";
#endif
Expand Down
2 changes: 2 additions & 0 deletions media/base/media_switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ MEDIA_EXPORT extern const char kEnableOpusPlayback[];

MEDIA_EXPORT extern const char kEnableVp9Playback[];

MEDIA_EXPORT extern const char kEnableVp8AlphaPlayback[];

#if defined(OS_WIN)
MEDIA_EXPORT extern const char kWaveOutBuffers[];
#endif
Expand Down
60 changes: 60 additions & 0 deletions media/base/simd/convert_yuv_to_rgb.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ typedef void (*ConvertYUVToRGB32Proc)(const uint8*,
int,
YUVType);

typedef void (*ConvertYUVAToARGBProc)(const uint8*,
const uint8*,
const uint8*,
const uint8*,
uint8*,
int,
int,
int,
int,
int,
int,
YUVType);

void ConvertYUVToRGB32_C(const uint8* yplane,
const uint8* uplane,
const uint8* vplane,
Expand All @@ -32,6 +45,19 @@ void ConvertYUVToRGB32_C(const uint8* yplane,
int rgbstride,
YUVType yuv_type);

void ConvertYUVAToARGB_C(const uint8* yplane,
const uint8* uplane,
const uint8* vplane,
const uint8* aplane,
uint8* rgbframe,
int width,
int height,
int ystride,
int uvstride,
int avstride,
int rgbstride,
YUVType yuv_type);

void ConvertYUVToRGB32_SSE(const uint8* yplane,
const uint8* uplane,
const uint8* vplane,
Expand All @@ -54,6 +80,19 @@ void ConvertYUVToRGB32_MMX(const uint8* yplane,
int rgbstride,
YUVType yuv_type);

void ConvertYUVAToARGB_MMX(const uint8* yplane,
const uint8* uplane,
const uint8* vplane,
const uint8* aplane,
uint8* rgbframe,
int width,
int height,
int ystride,
int uvstride,
int avstride,
int rgbstride,
YUVType yuv_type);

} // namespace media

// Assembly functions are declared without namespace.
Expand All @@ -72,6 +111,13 @@ typedef void (*ConvertYUVToRGB32RowProc)(const uint8*,
uint8*,
ptrdiff_t);

typedef void (*ConvertYUVAToARGBRowProc)(const uint8*,
const uint8*,
const uint8*,
const uint8*,
uint8*,
ptrdiff_t);

typedef void (*ScaleYUVToRGB32RowProc)(const uint8*,
const uint8*,
const uint8*,
Expand All @@ -85,12 +131,26 @@ void ConvertYUVToRGB32Row_C(const uint8* yplane,
uint8* rgbframe,
ptrdiff_t width);

void ConvertYUVAToARGBRow_C(const uint8* yplane,
const uint8* uplane,
const uint8* vplane,
const uint8* aplane,
uint8* rgbframe,
ptrdiff_t width);

void ConvertYUVToRGB32Row_MMX(const uint8* yplane,
const uint8* uplane,
const uint8* vplane,
uint8* rgbframe,
ptrdiff_t width);

void ConvertYUVAToARGBRow_MMX(const uint8* yplane,
const uint8* uplane,
const uint8* vplane,
const uint8* aplane,
uint8* rgbframe,
ptrdiff_t width);

void ConvertYUVToRGB32Row_SSE(const uint8* yplane,
const uint8* uplane,
const uint8* vplane,
Expand Down
Loading

0 comments on commit 6ac955b

Please sign in to comment.