3rdparty/licenseReport: Add seperate LGPL checks
[haiku.git] / src / add-ons / media / plugins / ffmpeg / Utilities.h
blob39039482c31e166c4687077c6133b563053fbf91
1 /*
2 * Copyright 2009, Stephan Aßmus <superstippi@gmx.de>
3 * Copyright 2014, Colin Günther <coling@gmx.de>
4 * All rights reserved. Distributed under the terms of the GNU L-GPL license.
5 */
6 #ifndef UTILITIES_H
7 #define UTILITIES_H
10 /*! \brief This file contains functions to convert and calculate values from
11 FFmpeg to Media Kit and vice versa.
15 #include <assert.h>
17 #include <GraphicsDefs.h>
19 extern "C" {
20 #include "avcodec.h"
24 /*! \brief Converts FFmpeg notation of video aspect ratio into the Media Kits
25 notation.
27 \see ConvertVideoAspectWidthAndHeightToAVCodecContext() for converting in
28 the other direction.
30 \param contextIn An AVCodeContext structure of FFmpeg containing the values
31 needed to calculate the Media Kit video aspect ratio.
32 The following fields are used for the calculation:
33 - AVCodecContext.sample_aspect_ratio.num (optional)
34 - AVCodecContext.sample_aspect_ratio.den (optional)
35 - AVCodecContext.width (must)
36 - AVCodecContext.height (must)
37 \param pixelWidthAspectOut On return contains Media Kits notation of the
38 video aspect ratio width. E.g. 16:9 -> 16 is returned here
39 \param pixelHeightAspectOut On return contains Media Kits notation of the
40 video aspect ratio height. E.g. 16:9 -> 9 is returned here
42 inline void
43 ConvertAVCodecContextToVideoAspectWidthAndHeight(AVCodecContext& contextIn,
44 uint16& pixelWidthAspectOut, uint16& pixelHeightAspectOut)
46 assert(contextIn.sample_aspect_ratio.num >= 0);
47 assert(contextIn.width > 0);
48 assert(contextIn.height > 0);
50 // The following code is based on code originally located in
51 // AVFormatReader::Stream::Init() and thus should be copyrighted to Stephan
52 // Aßmus
53 AVRational pixelAspectRatio;
55 if (contextIn.sample_aspect_ratio.num == 0
56 || contextIn.sample_aspect_ratio.den == 0) {
57 // AVCodecContext doesn't contain a video aspect ratio, so calculate it
58 // ourselve based solely on the video dimensions
59 av_reduce(&pixelAspectRatio.num, &pixelAspectRatio.den, contextIn.width,
60 contextIn.height, 1024 * 1024);
62 pixelWidthAspectOut = static_cast<int16>(pixelAspectRatio.num);
63 pixelHeightAspectOut = static_cast<int16>(pixelAspectRatio.den);
64 return;
67 // AVCodecContext contains a video aspect ratio, so use it
68 av_reduce(&pixelAspectRatio.num, &pixelAspectRatio.den,
69 contextIn.width * contextIn.sample_aspect_ratio.num,
70 contextIn.height * contextIn.sample_aspect_ratio.den,
71 1024 * 1024);
73 pixelWidthAspectOut = static_cast<int16>(pixelAspectRatio.num);
74 pixelHeightAspectOut = static_cast<int16>(pixelAspectRatio.den);
78 /*! \brief Converts the Media Kits notation of video aspect ratio into FFmpegs
79 notation.
81 \see ConvertAVCodecContextToVideoAspectWidthAndHeight() for converting in
82 the other direction.
84 \param pixelWidthAspectIn Contains Media Kits notation of the video aspect
85 ratio width. E.g. 16:9 -> 16 is passed here.
86 \param pixelHeightAspectIn Contains Media Kits notation of the video aspect
87 ratio height. E.g. 16:9 -> 9 is passed here.
88 \param contextInOut An AVCodecContext structure of FFmpeg.
89 On input must contain the following fields already initialized
90 otherwise the behaviour is undefined:
91 - AVCodecContext.width (must)
92 - AVCodecContext.height (must)
93 On output contains converted values in the following fields (other
94 fields stay as they were on input):
95 - AVCodecContext.sample_aspect_ratio.num
96 - AVCodecContext.sample_aspect_ratio.den
98 inline void
99 ConvertVideoAspectWidthAndHeightToAVCodecContext(uint16 pixelWidthAspectIn,
100 uint16 pixelHeightAspectIn, AVCodecContext& contextInOut)
102 assert(pixelWidthAspectIn > 0);
103 assert(pixelHeightAspectIn > 0);
104 assert(contextInOut.width > 0);
105 assert(contextInOut.height > 0);
107 AVRational pureVideoDimensionAspectRatio;
108 av_reduce(&pureVideoDimensionAspectRatio.num,
109 &pureVideoDimensionAspectRatio.den, contextInOut.width,
110 contextInOut.height, 1024 * 1024);
112 if (pureVideoDimensionAspectRatio.num == pixelWidthAspectIn
113 && pureVideoDimensionAspectRatio.den == pixelHeightAspectIn) {
114 // The passed Media Kit pixel aspect ratio equals the video dimension
115 // aspect ratio. Set sample_aspect_ratio to "ignore".
116 contextInOut.sample_aspect_ratio.num = 0;
117 contextInOut.sample_aspect_ratio.den = 1;
118 return;
121 av_reduce(&contextInOut.sample_aspect_ratio.num,
122 &contextInOut.sample_aspect_ratio.den,
123 contextInOut.height * pixelWidthAspectIn,
124 contextInOut.width * pixelHeightAspectIn,
125 1024 * 1024);
129 /*! \brief Calculates bytes per row for a video frame.
131 \param colorSpace The Media Kit color space the video frame uses.
132 \param videoWidth The width of the video frame.
134 \returns bytes per video frame row
135 \returns Zero, when bytes per video frame cannot be calculated.
137 inline uint32
138 CalculateBytesPerRowWithColorSpaceAndVideoWidth(color_space colorSpace, int videoWidth)
140 assert(videoWidth >= 0);
142 const uint32 kBytesPerRowUnknown = 0;
143 size_t bytesPerPixel;
144 size_t rowAlignment;
146 if (get_pixel_size_for(colorSpace, &bytesPerPixel, &rowAlignment, NULL) != B_OK)
147 return kBytesPerRowUnknown;
149 uint32 bytesPerRow = bytesPerPixel * videoWidth;
150 uint32 numberOfUnalignedBytes = bytesPerRow % rowAlignment;
152 if (numberOfUnalignedBytes == 0)
153 return bytesPerRow;
155 uint32 numberOfBytesNeededForAlignment = rowAlignment - numberOfUnalignedBytes;
156 bytesPerRow += numberOfBytesNeededForAlignment;
158 return bytesPerRow;
162 /*! \brief Converts FFmpeg notation of video frame rate into the Media Kits
163 notation.
165 \see ConvertAVCodecContextToVideoFrameRate() for converting in the other
166 direction.
168 \param contextIn An AVCodeContext structure of FFmpeg containing the values
169 needed to calculate the Media Kit video frame rate.
170 The following fields are used for the calculation:
171 - AVCodecContext.time_base.num (must)
172 - AVCodecContext.time_base.den (must)
173 - AVCodecContext.ticks_per_frame (must)
174 \param frameRateOut On return contains Media Kits notation of the video
175 frame rate.
177 inline void
178 ConvertAVCodecContextToVideoFrameRate(AVCodecContext& contextIn, float& frameRateOut)
180 // assert that av_q2d(contextIn.time_base) > 0 and computable
181 assert(contextIn.time_base.num > 0);
182 assert(contextIn.time_base.den > 0);
184 // The following code is based on private get_fps() function of FFmpeg's
185 // ratecontrol.c:
186 // https://lists.ffmpeg.org/pipermail/ffmpeg-cvslog/2012-April/049280.html
187 double possiblyInterlacedFrameRate = 1.0 / av_q2d(contextIn.time_base);
188 double numberOfInterlacedFramesPerFullFrame = FFMAX(contextIn.ticks_per_frame, 1);
190 frameRateOut
191 = possiblyInterlacedFrameRate / numberOfInterlacedFramesPerFullFrame;
195 /*! \brief Converts the Media Kits notation of video frame rate to FFmpegs
196 notation.
198 \see ConvertAVCodecContextToVideoFrameRate() for converting in the other
199 direction.
201 \param frameRateIn Contains Media Kits notation of the video frame rate
202 that will be converted into FFmpegs notation. Must be greater than
203 zero.
204 \param contextOut An AVCodecContext structure of FFmpeg.
205 On output contains converted values in the following fields (other
206 fields stay as they were on input):
207 - AVCodecContext.time_base.num
208 - AVCodecContext.time_base.den
209 - AVCodecContext.ticks_per_frame is set to 1
211 inline void
212 ConvertVideoFrameRateToAVCodecContext(float frameRateIn,
213 AVCodecContext& contextOut)
215 assert(frameRateIn > 0);
217 contextOut.ticks_per_frame = 1;
218 contextOut.time_base = av_d2q(1.0 / frameRateIn, 1024);
222 /*! \brief Converts the Media Kits notation of an audio sample format to
223 FFmpegs notation.
225 \see ConvertAVSampleFormatToRawAudioFormat() for converting in the other
226 direction.
228 \param rawAudioFormatIn Contains Media Kits notation of an audio sample
229 format that will be converted into FFmpegs notation.
230 \param sampleFormatOut On output contains FFmpegs notation of the passed
231 audio sample format. Might return AV_SAMPLE_FMT_NONE if there is no
232 conversion path.
234 inline void
235 ConvertRawAudioFormatToAVSampleFormat(uint32 rawAudioFormatIn,
236 AVSampleFormat& sampleFormatOut)
238 switch (rawAudioFormatIn) {
239 case media_raw_audio_format::B_AUDIO_FLOAT:
240 sampleFormatOut = AV_SAMPLE_FMT_FLT;
241 return;
243 case media_raw_audio_format::B_AUDIO_DOUBLE:
244 sampleFormatOut = AV_SAMPLE_FMT_DBL;
245 return;
247 case media_raw_audio_format::B_AUDIO_INT:
248 sampleFormatOut = AV_SAMPLE_FMT_S32;
249 return;
251 case media_raw_audio_format::B_AUDIO_SHORT:
252 sampleFormatOut = AV_SAMPLE_FMT_S16;
253 return;
255 case media_raw_audio_format::B_AUDIO_UCHAR:
256 sampleFormatOut = AV_SAMPLE_FMT_U8;
257 return;
259 default:
260 // Silence compiler warnings about unhandled enumeration values.
261 break;
264 sampleFormatOut = AV_SAMPLE_FMT_NONE;
268 /*! \brief Converts FFmpegs notation of an audio sample format to the Media
269 Kits notation.
271 \see ConvertAVSampleFormatToRawAudioFormat() for converting in the other
272 direction.
274 \param sampleFormatIn Contains FFmpegs notation of an audio sample format
275 that will be converted into the Media Kits notation.
276 \param rawAudioFormatOut On output contains Media Kits notation of the
277 passed audio sample format. Might return 0 if there is no conversion
278 path.
280 inline void
281 ConvertAVSampleFormatToRawAudioFormat(AVSampleFormat sampleFormatIn,
282 uint32& rawAudioFormatOut)
284 switch (sampleFormatIn) {
285 case AV_SAMPLE_FMT_FLT:
286 case AV_SAMPLE_FMT_FLTP:
287 rawAudioFormatOut = media_raw_audio_format::B_AUDIO_FLOAT;
288 return;
290 case AV_SAMPLE_FMT_DBL:
291 case AV_SAMPLE_FMT_DBLP:
292 rawAudioFormatOut = media_raw_audio_format::B_AUDIO_DOUBLE;
293 return;
295 case AV_SAMPLE_FMT_S32:
296 case AV_SAMPLE_FMT_S32P:
297 rawAudioFormatOut = media_raw_audio_format::B_AUDIO_INT;
298 return;
300 case AV_SAMPLE_FMT_S16:
301 case AV_SAMPLE_FMT_S16P:
302 rawAudioFormatOut = media_raw_audio_format::B_AUDIO_SHORT;
303 return;
305 case AV_SAMPLE_FMT_U8:
306 case AV_SAMPLE_FMT_U8P:
307 rawAudioFormatOut = media_raw_audio_format::B_AUDIO_UCHAR;
308 return;
310 default:
311 // Silence compiler warnings about unhandled enumeration values.
312 break;
315 const uint32 kBAudioNone = 0;
316 rawAudioFormatOut = kBAudioNone;
320 #endif // UTILITIES_H