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 <Bitmap.h>
#include <Debug.h> #include <Debug.h>
#include "Utilities.h"
#undef TRACE #undef TRACE
//#define TRACE_AV_CODEC //#define TRACE_AV_CODEC
@@ -879,8 +881,8 @@ AVCodecDecoder::_DecodeNextVideoFrame()
} }
/*! \brief Updates relevant fields of the class member fHeader with the properties of /*! \brief Updates relevant fields of the class member fHeader with the
the most recently decoded video frame. properties of the most recently decoded video frame.
It is assumed that this function is called in _DecodeNextVideoFrame() only It is assumed that this function is called in _DecodeNextVideoFrame() only
when the following asserts hold true: 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 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 at any single point in time. Otherwise you couldn't tell to which
cached decoded video frame the properties in fHeader relate to. 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 void
AVCodecDecoder::_UpdateMediaHeaderForVideoFrame() AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
@@ -901,6 +906,9 @@ AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
fHeader.file_pos = 0; fHeader.file_pos = 0;
fHeader.orig_size = 0; fHeader.orig_size = 0;
fHeader.start_time = fRawDecodedPicture->reordered_opaque; 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_gamma = 1.0;
fHeader.u.raw_video.field_sequence = fFrame; fHeader.u.raw_video.field_sequence = fFrame;
fHeader.u.raw_video.field_number = 0; 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.first_active_line = 1;
fHeader.u.raw_video.line_count = fRawDecodedPicture->height; 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", TRACE("[v] start_time=%02d:%02d.%02d field_sequence=%lu\n",
int((fHeader.start_time / 60000000) % 60), int((fHeader.start_time / 60000000) % 60),
int((fHeader.start_time / 1000000) % 60), int((fHeader.start_time / 1000000) % 60),
@@ -25,6 +25,7 @@ extern "C" {
#include "DemuxerTable.h" #include "DemuxerTable.h"
#include "gfx_util.h" #include "gfx_util.h"
#include "Utilities.h"
//#define TRACE_AVFORMAT_READER //#define TRACE_AVFORMAT_READER
@@ -1151,30 +1152,9 @@ AVFormatReader::Stream::Init(int32 virtualIndex)
format->u.encoded_video.output.orientation format->u.encoded_video.output.orientation
= B_VIDEO_TOP_LEFT_RIGHT; = B_VIDEO_TOP_LEFT_RIGHT;
// Calculate the display aspect ratio ConvertAVCodecContextToVideoAspectWidthAndHeight(*codecContext,
AVRational displayAspectRatio; format->u.encoded_video.output.pixel_width_aspect,
if (codecContext->sample_aspect_ratio.num != 0) { format->u.encoded_video.output.pixel_height_aspect);
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;
format->u.encoded_video.output.display.format format->u.encoded_video.output.display.format
= pixfmt_to_colorspace(codecContext->pix_fmt); = 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