[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