[Cin] DAR, PAR and SAR, again
Andrea paz
gamberucci.andrea at gmail.com
Sat Jan 20 17:49:32 CET 2024
I tried reading all the ffmpeg.C code inside ../cinelerra-5.1/cinelerra/ffmpeg.C
I found these references to aspect ratio. I don't understand most of the lines.
We start by setting the default parameters (line 1105):
FFVideoStream::FFVideoStream(FFMPEG *ffmpeg, AVStream *strm, int idx, int fidx)
: FFStream(ffmpeg, strm, fidx),
FFVideoConvert(ffmpeg->ff_prefs())
{
this->idx = idx;
width = height = 0;
transpose = 0;
frame_rate = 0;
aspect_ratio = 0;
length = 0;
interlaced = 0;
top_field_first = 0;
color_space = -1;
color_range = -1;
fconvert_ctx = 0;
}
Then after doing many steps, we arrive at the aspect ratio (lines 1954):
AVRational FFMPEG::to_sample_aspect_ratio(Asset *asset)
#(==> SAR=AVRational)
{
#if 1
double display_aspect = asset->width / (double)asset->height;
#(==> DAR=Wa/Ha; if SAR=1)
double sample_aspect = display_aspect / asset->aspect_ratio;
#(==> SAR=DAR/(Wa/Ha))
int width = 1000000, height = width * sample_aspect + 0.5;
#(==> W= n°; H=W x SAR + 0.5) ??
float w, h;
MWindow::create_aspect_ratio(w, h, width, height);
return (AVRational){(int)w, (int)h}; #(==> SAR = Int W / Int H) ??
#else
// square pixels
return (AVRational){1, 1}; #(==> SAR = 1:1)
#endif
}
Then a long block dealing with various parameters including sar (lines 2548):
AVRational sar = av_guess_sample_aspect_ratio(fmt_ctx, st, NULL);
AVRational display_aspect_ratio;
if(sar.num) {
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
st->codecpar->width * (int64_t)sar.num, #(==>
DAR.num = W x SAR.num)
st->codecpar->height * (int64_t)sar.den, #(==>
DAR.den = W x SAR.den)
1024 * 1024);
/* report(" Guessed SAR: %d:%d, ", sar.num, sar.den ); #(==>
SAR is guessed from ffmpeg scan?)
report("DAR: %d:%d \n", display_aspect_ratio.num,
display_aspect_ratio.den); */
}
if (st->sample_aspect_ratio.num)
{
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
st->codecpar->width * (int64_t)st->sample_aspect_ratio.num,
st->codecpar->height * (int64_t)st->sample_aspect_ratio.den,
1024 * 1024);
report(" container Detected SAR: %d:%d , DAR %d:%d \n",
st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
display_aspect_ratio.num, display_aspect_ratio.den);
}
if (st->codecpar->sample_aspect_ratio.num)
{
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
st->codecpar->width *
(int64_t)st->codecpar->sample_aspect_ratio.num,
st->codecpar->height *
(int64_t)st->codecpar->sample_aspect_ratio.den,
1024 * 1024);
report(" codec Detected SAR: %d:%d , DAR %d:%d \n",
st->codecpar->sample_aspect_ratio.num,
st->codecpar->sample_aspect_ratio.den, display_aspect_ratio.num,
display_aspect_ratio.den);
}
I think the whole block refers to "ffprobe", that is what we read in Detail.
In a later block is the line (2777):
vid->aspect_ratio = (double)st->sample_aspect_ratio.num /
st->sample_aspect_ratio.den; #(==> SAR=SAR.num/SAR.den) ??
I do not know how to interpret, however.
At some point (lines 3660, but especially 3710) there are formulas
that also involve PAR (like par = width x sar):
int FFMPEG::ff_total_video_layers()
{
return vstrm_index.size();
}
int FFMPEG::ff_total_vstreams()
{
return ffvideo.size();
}
int FFMPEG::ff_video_width(int stream)
{
FFVideoStream *vst = ffvideo[stream];
return !vst->transpose ? vst->width : vst->height;
}
int FFMPEG::ff_video_height(int stream)
{
FFVideoStream *vst = ffvideo[stream];
return !vst->transpose ? vst->height : vst->width;
}
int FFMPEG::ff_set_video_width(int stream, int width)
{
FFVideoStream *vst = ffvideo[stream];
int *vw = !vst->transpose ? &vst->width : &vst->height, w = *vw;
*vw = width;
return w;
}
int FFMPEG::ff_set_video_height(int stream, int height)
{
FFVideoStream *vst = ffvideo[stream];
int *vh = !vst->transpose ? &vst->height : &vst->width, h = *vh;
*vh = height;
return h;
}
int FFMPEG::ff_coded_width(int stream)
{
return ffvideo[stream]->avctx->coded_width;
}
int FFMPEG::ff_coded_height(int stream)
{
return ffvideo[stream]->avctx->coded_height;
}
float FFMPEG::ff_aspect_ratio(int stream)
{
//return ffvideo[stream]->aspect_ratio;
AVFormatContext *fmt_ctx = ffvideo[stream]->fmt_ctx;
AVStream *strm = ffvideo[stream]->st;
AVCodecParameters *par = ffvideo[stream]->st->codecpar;
AVRational dar;
AVRational sar = av_guess_sample_aspect_ratio(fmt_ctx, strm, NULL);
if (sar.num && ffvideo[stream]->get_rotation_angle() == 0) {
av_reduce(&dar.num, &dar.den,
par->width * sar.num,
par->height * sar.den,
1024*1024);
return av_q2d(dar);
}
return ffvideo[stream]->aspect_ratio;
}
Certainly, although the previous par were intended as "parameter,"
this time it is definitely PAR as aspect ratio; but I don't know
whether as "Pixel aspect ratio" or "Picture aspect ratio."
So it would seem that ffmpeg uses it (or is it a variation of CinGG?).
On line 3872 it is found:
AVCodecParameters *avpar = st->codecpar;
int sa_num = avpar->sample_aspect_ratio.num;
if( !sa_num ) sa_num = 1;
int sa_den = avpar->sample_aspect_ratio.den;
if( !sa_den ) sa_num = 1;
I don't quite understand if it sets the sar parameters: if we specify
them it takes the value given to it, otherwise it takes 1 by default.
I couldn't find any other references to aspect ratio in ffmpeg.C.
More information about the Cin
mailing list