FFMPEG Plugin: Extract video aspect ratio calculation code.

- Also make use of the extracted code in the AVCodecDecoder class.
- Enhance some documentation and fix some coding style violations.
- No functional change intended.
This commit is contained in:
Colin Günther
2014-08-04 12:25:22 +02:00
parent 05f06a9065
commit 4f4d98911a
3 changed files with 92 additions and 26 deletions
@@ -21,6 +21,8 @@
#include <Bitmap.h>
#include <Debug.h>
#include "Utilities.h"
#undef TRACE
//#define TRACE_AV_CODEC
@@ -879,8 +881,8 @@ AVCodecDecoder::_DecodeNextVideoFrame()
}
/*! \brief Updates relevant fields of the class member fHeader with the properties of
the most recently decoded video frame.
/*! \brief Updates relevant fields of the class member fHeader with the
properties of the most recently decoded video frame.
It is assumed that this function is called in _DecodeNextVideoFrame() only
when the following asserts hold true:
@@ -893,6 +895,9 @@ AVCodecDecoder::_DecodeNextVideoFrame()
4. There will be at maximumn only one decoded video frame in our cache
at any single point in time. Otherwise you couldn't tell to which
cached decoded video frame the properties in fHeader relate to.
5. AVCodecContext is still valid for this video frame (This is the case
when this function is called immediately after
avcodec_decode_video2().
*/
void
AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
@@ -901,6 +906,9 @@ AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
fHeader.file_pos = 0;
fHeader.orig_size = 0;
fHeader.start_time = fRawDecodedPicture->reordered_opaque;
fHeader.u.raw_video.display_line_width = fRawDecodedPicture->width;
fHeader.u.raw_video.display_line_count = fRawDecodedPicture->height;
fHeader.u.raw_video.bytes_per_row = 0; // TODO: Implement calculation
fHeader.u.raw_video.field_gamma = 1.0;
fHeader.u.raw_video.field_sequence = fFrame;
fHeader.u.raw_video.field_number = 0;
@@ -908,6 +916,10 @@ AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
fHeader.u.raw_video.first_active_line = 1;
fHeader.u.raw_video.line_count = fRawDecodedPicture->height;
ConvertAVCodecContextToVideoAspectWidthAndHeight(*fContext,
fHeader.u.raw_video.pixel_width_aspect,
fHeader.u.raw_video.pixel_height_aspect);
TRACE("[v] start_time=%02d:%02d.%02d field_sequence=%lu\n",
int((fHeader.start_time / 60000000) % 60),
int((fHeader.start_time / 1000000) % 60),
@@ -25,6 +25,7 @@ extern "C" {
#include "DemuxerTable.h"
#include "gfx_util.h"
#include "Utilities.h"
//#define TRACE_AVFORMAT_READER
@@ -1151,30 +1152,9 @@ AVFormatReader::Stream::Init(int32 virtualIndex)
format->u.encoded_video.output.orientation
= B_VIDEO_TOP_LEFT_RIGHT;
// Calculate the display aspect ratio
AVRational displayAspectRatio;
if (codecContext->sample_aspect_ratio.num != 0) {
av_reduce(&displayAspectRatio.num, &displayAspectRatio.den,
codecContext->width
* codecContext->sample_aspect_ratio.num,
codecContext->height
* codecContext->sample_aspect_ratio.den,
1024 * 1024);
TRACE(" pixel aspect ratio: %d/%d, "
"display aspect ratio: %d/%d\n",
codecContext->sample_aspect_ratio.num,
codecContext->sample_aspect_ratio.den,
displayAspectRatio.num, displayAspectRatio.den);
} else {
av_reduce(&displayAspectRatio.num, &displayAspectRatio.den,
codecContext->width, codecContext->height, 1024 * 1024);
TRACE(" no display aspect ratio (%d/%d)\n",
displayAspectRatio.num, displayAspectRatio.den);
}
format->u.encoded_video.output.pixel_width_aspect
= displayAspectRatio.num;
format->u.encoded_video.output.pixel_height_aspect
= displayAspectRatio.den;
ConvertAVCodecContextToVideoAspectWidthAndHeight(*codecContext,
format->u.encoded_video.output.pixel_width_aspect,
format->u.encoded_video.output.pixel_height_aspect);
format->u.encoded_video.output.display.format
= pixfmt_to_colorspace(codecContext->pix_fmt);
@@ -0,0 +1,74 @@
/*
* Copyright 2009, Stephan Aßmus <superstippi@gmx.de>
* Copyright 2014, Colin Günther <coling@gmx.de>
* All rights reserved. Distributed under the terms of the GNU L-GPL license.
*/
#ifndef UTILITIES_H
#define UTILITIES_H
/*! \brief This file contains functions to convert values from FFmpeg to Media
Kit and vice versa.
*/
#include <assert.h>
extern "C" {
#include "avcodec.h"
}
/*! \brief Converts FFmpeg notation of video aspect ratio into the Media Kits
notation.
\param pixelWidthAspectOut On return contains the Media Kits notation of
the video aspect ratio width. E.g. 16:9 -> 16 is returned here
\param pixelHeightAspectOut On return contains the Media Kits notation of
the video aspect ratio height. E.g. 16:9 -> 9 is returned here
\param contextIn An AVCodeContext structure of FFmpeg containing the values
needed to calculate the Media Kit video aspect ratio.
The following fields are used for the calculation:
- AVCodecContext.sample_aspect_ratio.num (optional)
- AVCodecContext.sample_aspect_ratio.den (optional)
- AVCodecContext.width (must)
- AVCodecContext.height (must)
*/
inline void
ConvertAVCodecContextToVideoAspectWidthAndHeight(AVCodecContext& contextIn,
uint16& pixelWidthAspectOut, uint16& pixelHeightAspectOut)
{
assert(contextIn.sample_aspect_ratio.num >= 0);
assert(contextIn.sample_aspect_ratio.den > 0);
assert(contextIn.width > 0);
assert(contextIn.height > 0);
// The following code is based on code originally located in
// AVFormatReader::Stream::Init() and thus should be copyrighted to Stephan
// Aßmus
AVRational pixelAspectRatio;
if (contextIn.sample_aspect_ratio.num == 0) {
// AVCodecContext doesn't contain a video aspect ratio, so calculate it
// ourselve based solely on the video dimensions
av_reduce(&pixelAspectRatio.num, &pixelAspectRatio.den, contextIn.width,
contextIn.height, 1024 * 1024);
pixelWidthAspectOut = static_cast<int16>(pixelAspectRatio.num);
pixelHeightAspectOut = static_cast<int16>(pixelAspectRatio.den);
return;
}
// AVCodecContext contains a video aspect ratio, so use it
av_reduce(&pixelAspectRatio.num, &pixelAspectRatio.den,
contextIn.width * contextIn.sample_aspect_ratio.num,
contextIn.height * contextIn.sample_aspect_ratio.den,
1024 * 1024);
pixelWidthAspectOut = static_cast<int16>(pixelAspectRatio.num);
pixelHeightAspectOut = static_cast<int16>(pixelAspectRatio.den);
}
#endif // UTILITIES_H