NV12截图

截图原理参考:

从NV12中裁剪子画面注意事项

这是源码:

//裁剪的坐标X和Y必须是偶数,否则UV和Y会有偏差, 注意点,linesize对其为1
int NV12CropTo420P(uint8_t *nv12data, int width, int height, int cropx,
		int cropy, uint8_t *yuv420pdata, int dscw, int dsch) {
	uint8_t *ptry = yuv420pdata, *ptru, *ptrv;
	uint8_t *nvptr = nv12data + width * height;

	ptry = yuv420pdata;
	ptru = yuv420pdata + dscw * dsch; //u
	ptrv = yuv420pdata + dscw * dsch + (dscw * dsch) / 4; //v

	for (int y = cropy; y < dsch + cropy /*pFrame->height*/; y++) {
		memcpy(ptry, nv12data + y * width + cropx, dscw);
		ptry += dscw;
	}

	for (int nvy = cropy / 2; nvy < dsch / 2 + cropy / 2 /*height / 2*/;
			nvy++) {
		//-----w-----
		//Y  Y  Y  Y
		//Y  Y  Y  Y
		//Y  Y  Y  Y
		//Y  Y  Y  Y
		//U  V  U  V
		//U  V  U  V
		for (int nvx = cropx; nvx < dscw + cropx; nvx++) {
			//如果目标是ffmpeg的avframe则需要注意的是linesize
			if (nvx % 2 == 0) {
				*ptru++ = nvptr[nvy * width + nvx]; //u
			} else {
				*ptrv++ = nvptr[nvy * width + nvx]; //v
			}
		}
	}
	return 0;
}

//-----w-----
//Y00 Y01 Y02 Y03
//Y10 Y11 Y12 Y13
//Y20 Y21 Y22 Y23
//Y30 Y31 Y32 Y33
//U00 V01 U02 V03
//U10 V11 U12 V13

YUV对应关系为:
Y00 Y01
Y10 Y11
U00 V01

你可能感兴趣的:(ffmpeg)