Skip to content

Commit

Permalink
Update to Pipeline Metadata and Decoder stream
Browse files Browse the repository at this point in the history
to track the set of video rotation metadata. This 
will later be used to correctly orient rotated videos.

BUG=47554

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282236 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
suderman@chromium.org committed Jul 10, 2014
1 parent 5b8cfce commit d4f8988
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 1 deletion.
3 changes: 3 additions & 0 deletions media/base/demuxer_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "media/base/media_export.h"
#include "media/base/video_rotation.h"

namespace media {

Expand Down Expand Up @@ -80,6 +81,8 @@ class MEDIA_EXPORT DemuxerStream {
// on this.
virtual bool SupportsConfigChanges() = 0;

virtual VideoRotation video_rotation() = 0;

protected:
// Only allow concrete implementations to get deleted.
virtual ~DemuxerStream();
Expand Down
4 changes: 4 additions & 0 deletions media/base/fake_text_track_stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ DemuxerStream::Type FakeTextTrackStream::type() {

bool FakeTextTrackStream::SupportsConfigChanges() { return false; }

VideoRotation FakeTextTrackStream::video_rotation() {
return VIDEO_ROTATION_0;
}

void FakeTextTrackStream::SatisfyPendingRead(
const base::TimeDelta& start,
const base::TimeDelta& duration,
Expand Down
1 change: 1 addition & 0 deletions media/base/fake_text_track_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class FakeTextTrackStream : public DemuxerStream {
virtual Type type() OVERRIDE;
MOCK_METHOD0(EnableBitstreamConverter, void());
virtual bool SupportsConfigChanges();
virtual VideoRotation video_rotation() OVERRIDE;

void SatisfyPendingRead(const base::TimeDelta& start,
const base::TimeDelta& duration,
Expand Down
4 changes: 4 additions & 0 deletions media/base/mock_filters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ void MockDemuxerStream::set_video_decoder_config(
video_decoder_config_ = config;
}

VideoRotation MockDemuxerStream::video_rotation() {
return VIDEO_ROTATION_0;
}

MockVideoDecoder::MockVideoDecoder() {
EXPECT_CALL(*this, HasAlpha()).WillRepeatedly(Return(false));
}
Expand Down
2 changes: 2 additions & 0 deletions media/base/mock_filters.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class MockDemuxerStream : public DemuxerStream {
void set_audio_decoder_config(const AudioDecoderConfig& config);
void set_video_decoder_config(const VideoDecoderConfig& config);

virtual VideoRotation video_rotation() OVERRIDE;

private:
DemuxerStream::Type type_;
AudioDecoderConfig audio_decoder_config_;
Expand Down
1 change: 1 addition & 0 deletions media/base/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ void Pipeline::StateTransitionTask(PipelineStatus status) {
if (stream) {
metadata.natural_size =
stream->video_decoder_config().natural_size();
metadata.video_rotation = stream->video_rotation();
}
metadata_cb_.Run(metadata);
}
Expand Down
5 changes: 4 additions & 1 deletion media/base/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "media/base/pipeline_status.h"
#include "media/base/ranges.h"
#include "media/base/serial_runner.h"
#include "media/base/video_rotation.h"
#include "ui/gfx/size.h"

namespace base {
Expand All @@ -37,11 +38,13 @@ class VideoRenderer;

// Metadata describing a pipeline once it has been initialized.
struct PipelineMetadata {
PipelineMetadata() : has_audio(false), has_video(false) {}
PipelineMetadata()
: has_audio(false), has_video(false), video_rotation(VIDEO_ROTATION_0) {}

bool has_audio;
bool has_video;
gfx::Size natural_size;
VideoRotation video_rotation;
base::Time timeline_offset;
};

Expand Down
21 changes: 21 additions & 0 deletions media/base/video_rotation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2014 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 MEDIA_BASE_VIDEO_ROTATION_H_
#define MEDIA_BASE_VIDEO_ROTATION_H_

namespace media {

// Enumeration to represent 90 degree video rotation for MP4 videos
// where it can be rotated by 90 degree intervals.
enum VideoRotation {
VIDEO_ROTATION_0 = 0,
VIDEO_ROTATION_90,
VIDEO_ROTATION_180,
VIDEO_ROTATION_270
};

} // namespace media

#endif // MEDIA_BASE_VIDEO_ROTATION_H_
4 changes: 4 additions & 0 deletions media/filters/chunk_demuxer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,10 @@ TextTrackConfig ChunkDemuxerStream::text_track_config() {
return stream_->GetCurrentTextTrackConfig();
}

VideoRotation ChunkDemuxerStream::video_rotation() {
return VIDEO_ROTATION_0;
}

void ChunkDemuxerStream::ChangeState_Locked(State state) {
lock_.AssertAcquired();
DVLOG(1) << "ChunkDemuxerStream::ChangeState_Locked() : "
Expand Down
1 change: 1 addition & 0 deletions media/filters/chunk_demuxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class MEDIA_EXPORT ChunkDemuxerStream : public DemuxerStream {
virtual AudioDecoderConfig audio_decoder_config() OVERRIDE;
virtual VideoDecoderConfig video_decoder_config() OVERRIDE;
virtual bool SupportsConfigChanges() OVERRIDE;
virtual VideoRotation video_rotation() OVERRIDE;

// Returns the text track configuration. It is an error to call this method
// if type() != TEXT.
Expand Down
4 changes: 4 additions & 0 deletions media/filters/decrypting_demuxer_stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ bool DecryptingDemuxerStream::SupportsConfigChanges() {
return demuxer_stream_->SupportsConfigChanges();
}

VideoRotation DecryptingDemuxerStream::video_rotation() {
return VIDEO_ROTATION_0;
}

DecryptingDemuxerStream::~DecryptingDemuxerStream() {
DVLOG(2) << __FUNCTION__ << " : state_ = " << state_;
}
Expand Down
1 change: 1 addition & 0 deletions media/filters/decrypting_demuxer_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class MEDIA_EXPORT DecryptingDemuxerStream : public DemuxerStream {
virtual Type type() OVERRIDE;
virtual void EnableBitstreamConverter() OVERRIDE;
virtual bool SupportsConfigChanges() OVERRIDE;
virtual VideoRotation video_rotation() OVERRIDE;

private:
// For a detailed state diagram please see this link: http://goo.gl/8jAok
Expand Down
4 changes: 4 additions & 0 deletions media/filters/fake_demuxer_stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ bool FakeDemuxerStream::SupportsConfigChanges() {
return config_changes_;
}

VideoRotation FakeDemuxerStream::video_rotation() {
return VIDEO_ROTATION_0;
}

void FakeDemuxerStream::HoldNextRead() {
DCHECK(task_runner_->BelongsToCurrentThread());
read_to_hold_ = next_read_num_;
Expand Down
1 change: 1 addition & 0 deletions media/filters/fake_demuxer_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class FakeDemuxerStream : public DemuxerStream {
virtual Type type() OVERRIDE;
virtual void EnableBitstreamConverter() OVERRIDE;
virtual bool SupportsConfigChanges() OVERRIDE;
virtual VideoRotation video_rotation() OVERRIDE;

void Initialize();

Expand Down
30 changes: 30 additions & 0 deletions media/filters/ffmpeg_demuxer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/sys_byteorder.h"
Expand Down Expand Up @@ -92,11 +93,14 @@ FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer,
type_(UNKNOWN),
end_of_stream_(false),
last_packet_timestamp_(kNoTimestamp()),
video_rotation_(VIDEO_ROTATION_0),
bitstream_converter_enabled_(false),
fixup_negative_ogg_timestamps_(false) {
DCHECK(demuxer_);

bool is_encrypted = false;
int rotation = 0;
AVDictionaryEntry* rotation_entry = NULL;

// Determine our media format.
switch (stream->codec->codec_type) {
Expand All @@ -109,6 +113,28 @@ FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer,
type_ = VIDEO;
AVStreamToVideoDecoderConfig(stream, &video_config_, true);
is_encrypted = video_config_.is_encrypted();

rotation_entry = av_dict_get(stream->metadata, "rotate", NULL, 0);
if (rotation_entry && rotation_entry->value && rotation_entry->value[0])
base::StringToInt(rotation_entry->value, &rotation);

switch (rotation) {
case 0:
break;
case 90:
video_rotation_ = VIDEO_ROTATION_90;
break;
case 180:
video_rotation_ = VIDEO_ROTATION_180;
break;
case 270:
video_rotation_ = VIDEO_ROTATION_270;
break;
default:
LOG(ERROR) << "Unsupported video rotation metadata: " << rotation;
break;
}

break;
case AVMEDIA_TYPE_SUBTITLE:
type_ = TEXT;
Expand Down Expand Up @@ -380,6 +406,10 @@ VideoDecoderConfig FFmpegDemuxerStream::video_decoder_config() {
return video_config_;
}

VideoRotation FFmpegDemuxerStream::video_rotation() {
return video_rotation_;
}

FFmpegDemuxerStream::~FFmpegDemuxerStream() {
DCHECK(!demuxer_);
DCHECK(read_cb_.is_null());
Expand Down
4 changes: 4 additions & 0 deletions media/filters/ffmpeg_demuxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class FFmpegDemuxerStream : public DemuxerStream {
virtual bool SupportsConfigChanges() OVERRIDE;
virtual AudioDecoderConfig audio_decoder_config() OVERRIDE;
virtual VideoDecoderConfig video_decoder_config() OVERRIDE;
virtual VideoRotation video_rotation() OVERRIDE;

// Returns the range of buffered data in this stream.
Ranges<base::TimeDelta> GetBufferedRanges() const;
Expand Down Expand Up @@ -133,6 +134,7 @@ class FFmpegDemuxerStream : public DemuxerStream {
bool end_of_stream_;
base::TimeDelta last_packet_timestamp_;
Ranges<base::TimeDelta> buffered_ranges_;
VideoRotation video_rotation_;

DecoderBufferQueue buffer_queue_;
ReadCB read_cb_;
Expand Down Expand Up @@ -277,6 +279,8 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
// time if the file doesn't have an association to Time.
base::Time timeline_offset_;

VideoRotation video_rotation_;

// Liveness of the stream.
Liveness liveness_;

Expand Down
36 changes: 36 additions & 0 deletions media/filters/ffmpeg_demuxer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,42 @@ TEST_F(FFmpegDemuxerTest, IsValidAnnexB) {
}
}

TEST_F(FFmpegDemuxerTest, Rotate_Metadata_0) {
CreateDemuxer("bear_rotate_0.mp4");
InitializeDemuxer();

DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
ASSERT_TRUE(stream);
ASSERT_EQ(VIDEO_ROTATION_0, stream->video_rotation());
}

TEST_F(FFmpegDemuxerTest, Rotate_Metadata_90) {
CreateDemuxer("bear_rotate_90.mp4");
InitializeDemuxer();

DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
ASSERT_TRUE(stream);
ASSERT_EQ(VIDEO_ROTATION_90, stream->video_rotation());
}

TEST_F(FFmpegDemuxerTest, Rotate_Metadata_180) {
CreateDemuxer("bear_rotate_180.mp4");
InitializeDemuxer();

DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
ASSERT_TRUE(stream);
ASSERT_EQ(VIDEO_ROTATION_180, stream->video_rotation());
}

TEST_F(FFmpegDemuxerTest, Rotate_Metadata_270) {
CreateDemuxer("bear_rotate_270.mp4");
InitializeDemuxer();

DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
ASSERT_TRUE(stream);
ASSERT_EQ(VIDEO_ROTATION_270, stream->video_rotation());
}

#endif

} // namespace media
22 changes: 22 additions & 0 deletions media/filters/pipeline_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,28 @@ TEST_F(PipelineIntegrationTest, DISABLED_SeekWhilePlaying) {
ASSERT_TRUE(WaitUntilOnEnded());
}

#if defined(USE_PROPRIETARY_CODECS)
TEST_F(PipelineIntegrationTest, Rotated_Metadata_0) {
ASSERT_TRUE(Start(GetTestDataFilePath("bear_rotate_0.mp4"), PIPELINE_OK));
ASSERT_EQ(VIDEO_ROTATION_0, metadata_.video_rotation);
}

TEST_F(PipelineIntegrationTest, Rotated_Metadata_90) {
ASSERT_TRUE(Start(GetTestDataFilePath("bear_rotate_90.mp4"), PIPELINE_OK));
ASSERT_EQ(VIDEO_ROTATION_90, metadata_.video_rotation);
}

TEST_F(PipelineIntegrationTest, Rotated_Metadata_180) {
ASSERT_TRUE(Start(GetTestDataFilePath("bear_rotate_180.mp4"), PIPELINE_OK));
ASSERT_EQ(VIDEO_ROTATION_180, metadata_.video_rotation);
}

TEST_F(PipelineIntegrationTest, Rotated_Metadata_270) {
ASSERT_TRUE(Start(GetTestDataFilePath("bear_rotate_270.mp4"), PIPELINE_OK));
ASSERT_EQ(VIDEO_ROTATION_270, metadata_.video_rotation);
}
#endif

// Verify audio decoder & renderer can handle aborted demuxer reads.
TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_AudioOnly) {
ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", kAudioOnlyWebM,
Expand Down
1 change: 1 addition & 0 deletions media/media.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@
'base/video_frame_pool.h',
'base/video_renderer.cc',
'base/video_renderer.h',
'base/video_rotation.h',
'base/video_util.cc',
'base/video_util.h',
'base/yuv_convert.cc',
Expand Down

0 comments on commit d4f8988

Please sign in to comment.