#ifndef UTILITIES_H
#define UTILITIES_H
#include <assert.h>
#include <stdio.h>
#include <GraphicsDefs.h>
extern "C" {
#include "avcodec.h"
}
struct avpacket_user_data {
int64_t pts;
int64_t dts;
int stream_index;
int flags;
int64_t duration;
int64_t pos;
};
#define AVPACKET_USER_DATA_TYPE 'ffav'
inline void
ConvertAVCodecContextToVideoAspectWidthAndHeight(AVCodecContext& contextIn,
uint16& pixelWidthAspectOut, uint16& pixelHeightAspectOut)
{
if (contextIn.width <= 0 || contextIn.height <= 0) {
fprintf(stderr, "Cannot compute video aspect ratio correctly\n");
pixelWidthAspectOut = 1;
pixelHeightAspectOut = 1;
return;
}
assert(contextIn.sample_aspect_ratio.num >= 0);
AVRational pixelAspectRatio;
if (contextIn.sample_aspect_ratio.num == 0
|| contextIn.sample_aspect_ratio.den == 0) {
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;
}
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);
}
inline void
ConvertAVCodecParametersToVideoAspectWidthAndHeight(AVCodecParameters& parametersIn,
uint16& pixelWidthAspectOut, uint16& pixelHeightAspectOut)
{
if (parametersIn.width <= 0 || parametersIn.height <= 0) {
fprintf(stderr, "Cannot compute video aspect ratio correctly\n");
pixelWidthAspectOut = 1;
pixelHeightAspectOut = 1;
return;
}
assert(parametersIn.sample_aspect_ratio.num >= 0);
AVRational pixelAspectRatio;
if (parametersIn.sample_aspect_ratio.num == 0
|| parametersIn.sample_aspect_ratio.den == 0) {
av_reduce(&pixelAspectRatio.num, &pixelAspectRatio.den, parametersIn.width,
parametersIn.height, 1024 * 1024);
pixelWidthAspectOut = static_cast<int16>(pixelAspectRatio.num);
pixelHeightAspectOut = static_cast<int16>(pixelAspectRatio.den);
return;
}
av_reduce(&pixelAspectRatio.num, &pixelAspectRatio.den,
parametersIn.width * parametersIn.sample_aspect_ratio.num,
parametersIn.height * parametersIn.sample_aspect_ratio.den,
1024 * 1024);
pixelWidthAspectOut = static_cast<int16>(pixelAspectRatio.num);
pixelHeightAspectOut = static_cast<int16>(pixelAspectRatio.den);
}
inline void
ConvertVideoAspectWidthAndHeightToAVCodecContext(uint16 pixelWidthAspectIn,
uint16 pixelHeightAspectIn, AVCodecContext& contextInOut)
{
if (contextInOut.width <= 0 || contextInOut.height <= 0) {
fprintf(stderr, "Cannot compute video aspect ratio correctly\n");
contextInOut.sample_aspect_ratio.num = 0;
contextInOut.sample_aspect_ratio.den = 1;
return;
}
assert(pixelWidthAspectIn > 0);
assert(pixelHeightAspectIn > 0);
AVRational pureVideoDimensionAspectRatio;
av_reduce(&pureVideoDimensionAspectRatio.num,
&pureVideoDimensionAspectRatio.den, contextInOut.width,
contextInOut.height, 1024 * 1024);
if (pureVideoDimensionAspectRatio.num == pixelWidthAspectIn
&& pureVideoDimensionAspectRatio.den == pixelHeightAspectIn) {
contextInOut.sample_aspect_ratio.num = 0;
contextInOut.sample_aspect_ratio.den = 1;
return;
}
av_reduce(&contextInOut.sample_aspect_ratio.num,
&contextInOut.sample_aspect_ratio.den,
contextInOut.height * pixelWidthAspectIn,
contextInOut.width * pixelHeightAspectIn,
1024 * 1024);
}
inline uint32
CalculateBytesPerRowWithColorSpaceAndVideoWidth(color_space colorSpace, int videoWidth)
{
assert(videoWidth >= 0);
const uint32 kBytesPerRowUnknown = 0;
size_t pixelChunk;
size_t rowAlignment;
size_t pixelsPerChunk;
if (get_pixel_size_for(colorSpace, &pixelChunk, &rowAlignment, &pixelsPerChunk) != B_OK)
return kBytesPerRowUnknown;
uint32 bytesPerRow = pixelChunk * videoWidth / pixelsPerChunk;
uint32 numberOfUnalignedBytes = bytesPerRow % rowAlignment;
if (numberOfUnalignedBytes == 0)
return bytesPerRow;
uint32 numberOfBytesNeededForAlignment = rowAlignment - numberOfUnalignedBytes;
bytesPerRow += numberOfBytesNeededForAlignment;
return bytesPerRow;
}
inline void
ConvertVideoFrameRateToAVCodecContext(float frameRateIn,
AVCodecContext& contextOut)
{
assert(frameRateIn > 0);
contextOut.framerate = av_d2q(frameRateIn, 1024);
contextOut.time_base = av_d2q(1.0 / frameRateIn, 1024);
}
inline void
ConvertRawAudioFormatToAVSampleFormat(uint32 rawAudioFormatIn,
AVSampleFormat& sampleFormatOut)
{
switch (rawAudioFormatIn) {
case media_raw_audio_format::B_AUDIO_FLOAT:
sampleFormatOut = AV_SAMPLE_FMT_FLT;
return;
case media_raw_audio_format::B_AUDIO_DOUBLE:
sampleFormatOut = AV_SAMPLE_FMT_DBL;
return;
case media_raw_audio_format::B_AUDIO_INT:
sampleFormatOut = AV_SAMPLE_FMT_S32;
return;
case media_raw_audio_format::B_AUDIO_SHORT:
sampleFormatOut = AV_SAMPLE_FMT_S16;
return;
case media_raw_audio_format::B_AUDIO_UCHAR:
sampleFormatOut = AV_SAMPLE_FMT_U8;
return;
default:
break;
}
sampleFormatOut = AV_SAMPLE_FMT_NONE;
}
inline void
ConvertAVSampleFormatToRawAudioFormat(AVSampleFormat sampleFormatIn,
uint32& rawAudioFormatOut)
{
switch (sampleFormatIn) {
case AV_SAMPLE_FMT_FLT:
case AV_SAMPLE_FMT_FLTP:
rawAudioFormatOut = media_raw_audio_format::B_AUDIO_FLOAT;
return;
case AV_SAMPLE_FMT_DBL:
case AV_SAMPLE_FMT_DBLP:
rawAudioFormatOut = media_raw_audio_format::B_AUDIO_DOUBLE;
return;
case AV_SAMPLE_FMT_S32:
case AV_SAMPLE_FMT_S32P:
rawAudioFormatOut = media_raw_audio_format::B_AUDIO_INT;
return;
case AV_SAMPLE_FMT_S16:
case AV_SAMPLE_FMT_S16P:
rawAudioFormatOut = media_raw_audio_format::B_AUDIO_SHORT;
return;
case AV_SAMPLE_FMT_U8:
case AV_SAMPLE_FMT_U8P:
rawAudioFormatOut = media_raw_audio_format::B_AUDIO_UCHAR;
return;
default:
break;
}
const uint32 kBAudioNone = 0;
rawAudioFormatOut = kBAudioNone;
}
#endif