summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscottfr@chromium.org <scottfr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-02 03:01:07 +0000
committerscottfr@chromium.org <scottfr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-02 03:01:07 +0000
commitf649bf548e4cbc6bfa0ab853ea2b0a9d8183fa2b (patch)
treeda830829da42937075575e9140803f66578921b5
parent32d017b5eae0c4b39370f57b09a6395b468ad6ef (diff)
downloadchromium_src-f649bf548e4cbc6bfa0ab853ea2b0a9d8183fa2b.zip
chromium_src-f649bf548e4cbc6bfa0ab853ea2b0a9d8183fa2b.tar.gz
chromium_src-f649bf548e4cbc6bfa0ab853ea2b0a9d8183fa2b.tar.bz2
Respect pixel aspect ratio of video if it contains one.
BUG=18941 TEST=Check correct AR on http://people.xiph.org/~giles/2009/celt-aspect.html Alternately, fix 59412 and run media/video-display-aspect-ratio layout test Review URL: http://codereview.chromium.org/7086002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87578 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/renderer/media/ipc_video_decoder.cc11
-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/video/ffmpeg_video_decode_engine.cc4
-rw-r--r--media/video/ffmpeg_video_decode_engine_unittest.cc4
9 files changed, 75 insertions, 12 deletions
diff --git a/content/renderer/media/ipc_video_decoder.cc b/content/renderer/media/ipc_video_decoder.cc
index 9b792f4..7f71312 100644
--- a/content/renderer/media/ipc_video_decoder.cc
+++ b/content/renderer/media/ipc_video_decoder.cc
@@ -49,9 +49,13 @@ void IpcVideoDecoder::Initialize(media::DemuxerStream* demuxer_stream,
int width = av_stream->codec->coded_width;
int height = av_stream->codec->coded_height;
- if (width > media::Limits::kMaxDimension ||
- height > media::Limits::kMaxDimension ||
- (width * height) > media::Limits::kMaxCanvas) {
+
+ int surface_width = media::GetSurfaceWidth(av_stream);
+ int surface_height = media::GetSurfaceHeight(av_stream);
+
+ if (surface_width > media::Limits::kMaxDimension ||
+ surface_height > media::Limits::kMaxDimension ||
+ (surface_width * surface_height) > media::Limits::kMaxCanvas) {
media::VideoCodecInfo info = {0};
OnInitializeComplete(info);
return;
@@ -69,6 +73,7 @@ void IpcVideoDecoder::Initialize(media::DemuxerStream* demuxer_stream,
media::VideoDecoderConfig config(
media::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/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..2ccd4eb 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/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.