diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-03 02:41:03 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-03 02:41:03 +0000 |
commit | e21f5304d45b690b7c727e7499e507eea2eb4780 (patch) | |
tree | 9915804172309764e6c9f45de5908da56d786f5a /media | |
parent | 4461043a49c61121f38644659d9f3f7e8c7d0cf9 (diff) | |
download | chromium_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.cc | 12 | ||||
-rw-r--r-- | media/base/video_decoder_config.h | 7 | ||||
-rw-r--r-- | media/ffmpeg/ffmpeg_common.cc | 21 | ||||
-rw-r--r-- | media/ffmpeg/ffmpeg_common.h | 6 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.cc | 11 | ||||
-rw-r--r-- | media/filters/omx_video_decoder.cc | 11 | ||||
-rw-r--r-- | media/tools/omx_test/omx_test.cc | 2 | ||||
-rw-r--r-- | media/video/ffmpeg_video_decode_engine.cc | 4 | ||||
-rw-r--r-- | media/video/ffmpeg_video_decode_engine_unittest.cc | 4 |
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. |