[FFmpeg-devel] AVFrame linesize and OpenGL GL_UNPACK_ROW_LENGTH

Pavel Koshevoy pkoshevoy at gmail.com
Tue May 7 05:45:57 CEST 2013


OpenGL requires that texture row stride must be pixel aligned, because 
GL_UNPACK_ROW_LENGTH parameter is expressed in pixels, not bytes.

AVFrame linesize is byte aligned on 32-byte boundary.  This means that for bgr24 
and similar pixel formats rows are usually not pixel aligned and AVFrame data 
can not be used directly as an OpenGL texture.

A quick example is bgr24 frame of 654 pixel width for which image_get_linesize 
calculates linesize 1962 and FFALIGN(1962, 32) pads it to 1984. 1984/3 = 
661.3333... non-integer value, not pixel aligned.

One fix is possible by tweaking image_get_linesize function a little to pad 
image width to align on 32 pixel boundary, like this:

static inline
int image_get_linesize(int width, int plane,
                        int max_step, int max_step_comp,
                        const AVPixFmtDescriptor *desc)
     int s, shifted_w, padded_w, linesize;

     if (!desc)
         return AVERROR(EINVAL);

     if (width < 0)
         return AVERROR(EINVAL);
     s = (max_step_comp == 1 || max_step_comp == 2) ? desc->log2_chroma_w : 0;
     shifted_w = ((width + (1 << s) - 1)) >> s;
     padded_w = (shifted_w + 31) & ~(31);
     if (padded_w && max_step > INT_MAX / padded_w)
         return AVERROR(EINVAL);
     linesize = max_step * padded_w;

     if (desc->flags & PIX_FMT_BITSTREAM)
         linesize = (linesize + 7) >> 3;
     return linesize;

Should I submit a patch for this, or is there a better way to do this?

Thank you,

More information about the ffmpeg-devel mailing list