summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-03 02:41:03 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-03 02:41:03 +0000
commite21f5304d45b690b7c727e7499e507eea2eb4780 (patch)
tree9915804172309764e6c9f45de5908da56d786f5a /media
parent4461043a49c61121f38644659d9f3f7e8c7d0cf9 (diff)
downloadchromium_src-e21f5304d45b690b7c727e7499e507eea2eb4780.zip
chromium_src-e21f5304d45b690b7c727e7499e507eea2eb4780.tar.gz
chromium_src-e21f5304d45b690b7c727e7499e507eea2eb4780.tar.bz2
Respect pixel aspect ratio of video if it contains one.
Patch by scottfr@chromium.org: http://codereview.chromium.org/7086002 BUG=18941 TEST=Check correct AR on http://people.xiph.org/~giles/2009/celt-aspect.html, media/video-display-aspect-ratio git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87751 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/video_decoder_config.cc12
-rw-r--r--media/base/video_decoder_config.h7
-rw-r--r--media/ffmpeg/ffmpeg_common.cc21
-rw-r--r--media/ffmpeg/ffmpeg_common.h6
-rw-r--r--media/filters/ffmpeg_video_decoder.cc11
-rw-r--r--media/filters/omx_video_decoder.cc11
-rw-r--r--media/tools/omx_test/omx_test.cc2
-rw-r--r--media/video/ffmpeg_video_decode_engine.cc4
-rw-r--r--media/video/ffmpeg_video_decode_engine_unittest.cc4
9 files changed, 69 insertions, 9 deletions
diff --git a/media/base/video_decoder_config.cc b/media/base/video_decoder_config.cc
index abcd80b..5ec7c02d 100644
--- a/media/base/video_decoder_config.cc
+++ b/media/base/video_decoder_config.cc
@@ -11,6 +11,8 @@ namespace media {
VideoDecoderConfig::VideoDecoderConfig(VideoCodec codec,
int width,
int height,
+ int surface_width,
+ int surface_height,
int frame_rate_numerator,
int frame_rate_denominator,
uint8* extra_data,
@@ -18,6 +20,8 @@ VideoDecoderConfig::VideoDecoderConfig(VideoCodec codec,
: codec_(codec),
width_(width),
height_(height),
+ surface_width_(surface_width),
+ surface_height_(surface_height),
frame_rate_numerator_(frame_rate_numerator),
frame_rate_denominator_(frame_rate_denominator),
extra_data_size_(extra_data_size) {
@@ -42,6 +46,14 @@ int VideoDecoderConfig::height() const {
return height_;
}
+int VideoDecoderConfig::surface_width() const {
+ return surface_width_;
+}
+
+int VideoDecoderConfig::surface_height() const {
+ return surface_height_;
+}
+
int VideoDecoderConfig::frame_rate_numerator() const {
return frame_rate_numerator_;
}
diff --git a/media/base/video_decoder_config.h b/media/base/video_decoder_config.h
index 9ce582b..011efbf 100644
--- a/media/base/video_decoder_config.h
+++ b/media/base/video_decoder_config.h
@@ -23,6 +23,7 @@ enum VideoCodec {
class VideoDecoderConfig {
public:
VideoDecoderConfig(VideoCodec codec, int width, int height,
+ int surface_width, int surface_height,
int frame_rate_numerator, int frame_rate_denominator,
uint8* extra_data, size_t extra_data_size);
~VideoDecoderConfig();
@@ -30,6 +31,8 @@ class VideoDecoderConfig {
VideoCodec codec() const;
int width() const;
int height() const;
+ int surface_width() const;
+ int surface_height() const;
int frame_rate_numerator() const;
int frame_rate_denominator() const;
uint8* extra_data() const;
@@ -42,6 +45,10 @@ class VideoDecoderConfig {
int width_;
int height_;
+ // Width and height of the display surface for this video.
+ int surface_width_;
+ int surface_height_;
+
// Frame rate in seconds expressed as a fraction.
// TODO(scherkus): fairly certain decoders don't require frame rates.
int frame_rate_numerator_;
diff --git a/media/ffmpeg/ffmpeg_common.cc b/media/ffmpeg/ffmpeg_common.cc
index dedc40c..7af9635 100644
--- a/media/ffmpeg/ffmpeg_common.cc
+++ b/media/ffmpeg/ffmpeg_common.cc
@@ -185,4 +185,25 @@ bool GetStreamByteCountOverRange(AVStream* stream,
return true;
}
+int GetSurfaceHeight(AVStream* stream) {
+ return stream->codec->coded_height;
+}
+
+int GetSurfaceWidth(AVStream* stream) {
+ double aspect_ratio;
+
+ if (stream->sample_aspect_ratio.num)
+ aspect_ratio = av_q2d(stream->sample_aspect_ratio);
+ else if (stream->codec->sample_aspect_ratio.num)
+ aspect_ratio = av_q2d(stream->codec->sample_aspect_ratio);
+ else
+ aspect_ratio = 1.0;
+
+ int width = floor(stream->codec->coded_width * aspect_ratio + 0.5);
+
+ // An even width makes things easier for YV12 and appears to be the behavior
+ // expected by WebKit layout tests.
+ return width & ~1;
+}
+
} // namespace media
diff --git a/media/ffmpeg/ffmpeg_common.h b/media/ffmpeg/ffmpeg_common.h
index 3d39d52..07daae1 100644
--- a/media/ffmpeg/ffmpeg_common.h
+++ b/media/ffmpeg/ffmpeg_common.h
@@ -103,6 +103,12 @@ bool GetStreamByteCountOverRange(AVStream* stream,
int64* bytes,
base::TimeDelta* range_start,
base::TimeDelta* range_end);
+
+// Calculates the width and height of the video surface using the video's
+// encoded dimensions and sample_aspect_ratio.
+int GetSurfaceHeight(AVStream* stream);
+int GetSurfaceWidth(AVStream* stream);
+
} // namespace media
#endif // MEDIA_FFMPEG_FFMPEG_COMMON_H_
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
index 5487398..53d28a2 100644
--- a/media/filters/ffmpeg_video_decoder.cc
+++ b/media/filters/ffmpeg_video_decoder.cc
@@ -64,9 +64,13 @@ void FFmpegVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
int width = av_stream->codec->coded_width;
int height = av_stream->codec->coded_height;
- if (width > Limits::kMaxDimension ||
- height > Limits::kMaxDimension ||
- (width * height) > Limits::kMaxCanvas) {
+
+ int surface_width = GetSurfaceWidth(av_stream);
+ int surface_height = GetSurfaceHeight(av_stream);
+
+ if (surface_width > Limits::kMaxDimension ||
+ surface_height > Limits::kMaxDimension ||
+ (surface_width * surface_height) > Limits::kMaxCanvas) {
VideoCodecInfo info = {0};
OnInitializeComplete(info);
return;
@@ -74,6 +78,7 @@ void FFmpegVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
VideoDecoderConfig config(CodecIDToVideoCodec(av_stream->codec->codec_id),
width, height,
+ surface_width, surface_height,
av_stream->r_frame_rate.num,
av_stream->r_frame_rate.den,
av_stream->codec->extradata,
diff --git a/media/filters/omx_video_decoder.cc b/media/filters/omx_video_decoder.cc
index b185965..b58e1c6 100644
--- a/media/filters/omx_video_decoder.cc
+++ b/media/filters/omx_video_decoder.cc
@@ -64,9 +64,13 @@ void OmxVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
int width = av_stream->codec->coded_width;
int height = av_stream->codec->coded_height;
- if (width > Limits::kMaxDimension ||
- height > Limits::kMaxDimension ||
- (width * height) > Limits::kMaxCanvas) {
+
+ int surface_width = GetSurfaceWidth(av_stream);
+ int surface_height = GetSurfaceHeight(av_stream);
+
+ if (surface_width > Limits::kMaxDimension ||
+ surface_height > Limits::kMaxDimension ||
+ (surface_width * surface_height) > Limits::kMaxCanvas) {
VideoCodecInfo info = {0};
OnInitializeComplete(info);
return;
@@ -74,6 +78,7 @@ void OmxVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
VideoDecoderConfig config(CodecIDToVideoCodec(av_stream->codec->codec_id),
width, height,
+ surface_width, surface_height,
av_stream->r_frame_rate.num,
av_stream->r_frame_rate.den,
av_stream->codec->extradata,
diff --git a/media/tools/omx_test/omx_test.cc b/media/tools/omx_test/omx_test.cc
index ebba0b1..a5f6591 100644
--- a/media/tools/omx_test/omx_test.cc
+++ b/media/tools/omx_test/omx_test.cc
@@ -174,6 +174,8 @@ class TestApp : public base::RefCountedThreadSafe<TestApp>,
media::CodecIDToVideoCodec(av_stream_->codec->codec_id),
av_stream_->codec->coded_width,
av_stream_->codec->coded_height,
+ media::GetSurfaceWidth(av_stream_.get()),
+ media::GetSurfaceHeight(av_stream_.get()),
av_stream_->r_frame_rate.num,
av_stream_->r_frame_rate.den,
av_stream_->codec->extradata,
diff --git a/media/video/ffmpeg_video_decode_engine.cc b/media/video/ffmpeg_video_decode_engine.cc
index 0413092..c1e1d63 100644
--- a/media/video/ffmpeg_video_decode_engine.cc
+++ b/media/video/ffmpeg_video_decode_engine.cc
@@ -117,8 +117,8 @@ void FFmpegVideoDecodeEngine::Initialize(
info.provides_buffers = true;
info.stream_info.surface_type = VideoFrame::TYPE_SYSTEM_MEMORY;
info.stream_info.surface_format = GetSurfaceFormat();
- info.stream_info.surface_width = config.width();
- info.stream_info.surface_height = config.height();
+ info.stream_info.surface_width = config.surface_width();
+ info.stream_info.surface_height = config.surface_height();
// If we do not have enough buffers, we will report error too.
bool buffer_allocated = true;
diff --git a/media/video/ffmpeg_video_decode_engine_unittest.cc b/media/video/ffmpeg_video_decode_engine_unittest.cc
index 8a53f6d..2589289 100644
--- a/media/video/ffmpeg_video_decode_engine_unittest.cc
+++ b/media/video/ffmpeg_video_decode_engine_unittest.cc
@@ -23,6 +23,8 @@ namespace media {
static const int kWidth = 320;
static const int kHeight = 240;
+static const int kSurfaceWidth = 522;
+static const int kSurfaceHeight = 288;
static const AVRational kFrameRate = { 100, 1 };
static void InitializeFrame(uint8_t* data, int width, AVFrame* frame) {
@@ -50,7 +52,7 @@ class FFmpegVideoDecodeEngineTest : public testing::Test,
public VideoDecodeEngine::EventHandler {
public:
FFmpegVideoDecodeEngineTest()
- : config_(kCodecH264, kWidth, kHeight,
+ : config_(kCodecH264, kWidth, kHeight, kSurfaceWidth, kSurfaceHeight,
kFrameRate.num, kFrameRate.den, NULL, 0) {
// Setup FFmpeg structures.