Ticket #566 (closed defect: fixed)

Opened 4 years ago

Last modified 3 years ago

Frapsv4 shows black

Reported by: JuergenM Owned by: astrange
Priority: normal Milestone: 1.2.3
Component: Codec Version: 1.2.2
Severity: normal Keywords:
Cc:

Description

The new version 1.2.2 has some problems with the Fraps codes (v3.4). I had to switch back to Perian 1.2.1 for using Fraps codec.

Change History

comment:1 Changed 4 years ago by gbooker

  • Milestone set to Needs Feedback From User

Can you provide a sample file and a description of what "some problems" means?

comment:2 Changed 4 years ago by astrange

  • Owner set to astrange
  • Status changed from new to assigned

comment:3 Changed 4 years ago by astrange

  • Summary changed from Perian v1.2.2 to Frapsv4 shows black

comment:4 Changed 4 years ago by astrange

(In [1424]) Map PIX_FMT_YUVJ420P to 2vuy

Fixes fraps v0/3/4.

Note this is wrong - the full-range YUV format is kComponentVideoCodecType. Follow up later.

Refs #566

comment:5 Changed 4 years ago by astrange

(In [1425]) Fix last commit

Refs #566

comment:6 Changed 4 years ago by astrange

  • Status changed from assigned to closed
  • Resolution set to fixed

And we can't implement kComponentVideoCodecType (yuv2) because QT doesn't accept it as the output of a component. Okay then.

comment:7 Changed 4 years ago by astrange

  • Milestone changed from Needs Feedback From User to Next Fix

comment:8 Changed 4 years ago by astrange

(In [1426]) Fix complete nonsense call to Gestalt() which broke compat checks

Fixes #566

comment:9 Changed 3 years ago by gbooker

  • Status changed from closed to reopened
  • Resolution fixed deleted

Color space is wrong. We can use k4444YpCbCrA8RPixelFormat. The following clear and convert functions seem to work. They aren't pretty, but functional:

//Y420+Alpha Planar to V408 (YUV 4:4:4+Alpha 32-bit packed)
//Could be fully unrolled to avoid x/2
static FASTCALL void YA420toV408rf(AVPicture *picture, UInt8 *o, int outRB, int width, int height)
{
	UInt8	*yc = picture->data[0], *u = picture->data[1], *v = picture->data[2], *a = picture->data[3];
	int		rYA = picture->linesize[0], rUV = picture->linesize[1];
	int y, x;
	
	for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
			if(a != NULL)
				o[x*4] = a[x];
			else
				o[x*4] = 255;
			o[x*4+1] = yc[x];
			o[x*4+2]   = u[x>>1];
			o[x*4+3] = v[x>>1];
		}
		
		o  += outRB;
		yc += rYA;
		if(a != NULL)
			a  += rYA;
		if (y & 1) {
			u += rUV;
			v += rUV;
		}
	}
}
static FASTCALL void ClearV408rf(UInt8 *baseAddr, int rowBytes, int width, int height)
{
	int x, y;
	
	for (y = 0; y < height; y++)
	{
		for (x = 0; x < width; x++)
		{
			int x4 = x * 4;
			baseAddr[x4] = 0xFF; //opaque
			baseAddr[x4+1] = 0x00; //black
			baseAddr[x4+2] = 0x80; //zero chroma
			baseAddr[x4+3] = 0x80; 
		}
		baseAddr += rowBytes;
	}
}

comment:10 Changed 3 years ago by tick

  • Milestone changed from Next Fix to 1.2.3

comment:11 Changed 3 years ago by gbooker

Faster conversion without going all the way to sse:

//Handles the last row for Y420 videos with an odd number of luma rows
//FIXME: odd number of luma columns is not handled and they will be lost
static void YA420toY408_lastrow(UInt8 *o, UInt8 *yc, UInt8 *u, UInt8 *v, int halfWidth)
{
	int x;
	for (x=0; x < halfWidth; x++) {
		int x8 = x*8, x2 = x*2;
		o [x8  ] = o [x8+4] = 255;
		o [x8+1] = yc[x2];
		o [x8+5] = yc[x2+1];
		o [x8+2] = o [x8+6] = u[x];
		o [x8+3] = o [x8+7] = v[x];
	}
}

#define HandleLastRow408(o, yc, uc, vc, halfWidth, height) if (unlikely(height & 1)) YA420toY408_lastrow(o, yc, uc, vc, halfWidth)

//Y420+Alpha Planar to V408 (YUV 4:4:4+Alpha 32-bit packed)
static FASTCALL void YA420toV408rf(AVPicture *picture, UInt8 *o, int outRB, int width, int height)
{
	UInt8	*yc = picture->data[0], *u = picture->data[1], *v = picture->data[2];
	int		rYA = picture->linesize[0], rUV = picture->linesize[1];
	int		y, x, halfwidth = width >> 1, halfheight = height >> 1;
	
	for (y = 0; y < halfheight; y++) {
		UInt8   *o2 = o + outRB,   *yc2 = yc + rYA;
		for (x=0; x < halfwidth; x++) {
			int x8 = x*8, x2 = x*2;
			o [x8  ] = o2[x8  ] = \
			o [x8+4] = o2[x8+4] = \
				255;
			o [x8+1] = yc[x2];
			o [x8+5] = yc[x2+1];
			o2[x8+1] = yc2[x2];
			o2[x8+5] = yc2[x2+1];
			o [x8+2] = o2[x8+2] = \
			o [x8+6] = o2[x8+6] = \
				u[x];
			o [x8+3] = o2[x8+3] = \
			o [x8+7] = o2[x8+7] = \
				v[x];
		}
		
		o  += outRB*2;
		yc += rYA*2;
		u += rUV;
		v += rUV;
	}
	HandleLastRow408(o, yc, u, v, halfwidth, height);
}

Decoding a big image, the real limiting factor is the decode process, not the color conversion; so this is likely good enough for now.

comment:12 Changed 3 years ago by astrange

We're currently using k4444YpCbCrA8PixelFormat which is not too different. r408 still doesn't have 0-255 luma. But it does have 0-255 alpha, so that's a bit more accurate.

comment:13 Changed 3 years ago by astrange

  • Status changed from reopened to closed
  • Resolution set to fixed

Actually fraps doesn't use alpha, that's huffyuv.

Note: See TracTickets for help on using tickets.