While working on cropping video image in my newest version of VideoEditor app, I came to solving an issue of cropping area being incompatible with possible codec’s input. There’re two issues with this matter: cropping an area out of a YUV image, and then feeding codec with that image.
Let’s see, what are the rules, regarding few pixel formats – and coming from aligning color planes:
- YUV444P and all RGB/BGR formats: no restrictions, as they’re not packed;
- YUV422P requires x offset to be even, and also the overall width to be even;
- YUV420P (most common in H.264/H.265 codecs), and similar, like NV12 or YUVJ420P requires both x and y offset to be even, and also both width and height to be even.
Now, the second problem is a bit tricky – and sometimes it is a problem, while sometimes it’s not 😉 But, for encoding with codecs like H.264 or H.265, the safe choice is to have overall height to be divisible by 4 – or even by 16, to be on a super safe side.
So, that’s why I wrote this little helper function:
static QRect makeRectYUVCompliant(const QRect& rect, AVPixelFormat format, bool forceHeight4 = false, bool forceHeight16 = false)
{
int x = rect.x();
int y = rect.y();
int w = rect.width();
int h = rect.height();
switch (format)
{
case AV_PIX_FMT_YUV420P:
case AV_PIX_FMT_YUVJ420P:
case AV_PIX_FMT_NV12:
if (x % 2 != 0) x--;
if (y % 2 != 0) y--;
if (w % 2 != 0) w--;
if (h % 2 != 0) h--;
break;
case AV_PIX_FMT_YUV422P:
if (x % 2 != 0) x--;
if (w % 2 != 0) w--;
break;
case AV_PIX_FMT_YUV444P:
case AV_PIX_FMT_RGB24:
case AV_PIX_FMT_BGR24:
case AV_PIX_FMT_ARGB:
case AV_PIX_FMT_ABGR:
case AV_PIX_FMT_RGBA:
case AV_PIX_FMT_BGRA:
// no requirements
break;
default:
// unknown format, assume YUV420P
if (x % 2 != 0) x--;
if (y % 2 != 0) y--;
if (w % 2 != 0) w--;
if (h % 2 != 0) h--;
break;
}
if (forceHeight4)
{
while (h % 4 != 0) h--;
}
if (forceHeight16)
{
while (h % 16 != 0) h--;
}
return QRect(x, y, w, h);
}
Soon I’ll probably write more on the topic of cropping – and how to achieve it, using libavfilter library from ffmpeg.



