[Libav-user] porting FFusion codec to current FFmpeg libs - ParseContext1 ??

"René J.V. Bertin" rjvbertin at gmail.com
Thu Jan 24 19:04:33 CET 2013


Hello List,

I'm hacking my way around the version of the FFusion codec component that is included in Perian, the catch-all importer/exporter plugin collection for QuickTime. FFusion is the part that relies on FFmpeg for demuxing and decoding — I'm interested only in the codec functionality, not in adding support for various container formats. Once this works on Mac OS X, the goal is to get it to build on Win32, in the hope of improving Win32 QuickTime's playback performance for mpg4, h264, etc.

I'm currently at the point where I've stripped out all unneeded functionality from my FFusion component, and I'm trying to get it to build with the current FFmpeg version (for which I can get the Win32 DLLs easily).

Perian, and thus my FFusion pet project, use an older FFmpeg version, major 52 ... with quite a few patches from what I've seen ... and it hooks into "internal" functionality, notably in order to do additional parsing of, for instance, AVContext->extradata . I've no idea why this is needed, but if I strip this out altogether, I'm getting white or black content in my player. Here's an example:

static int parse_mpeg4_extra(FFusionParserContext *parser, const uint8_t *buf, int buf_size)
{
	ParseContext1 *pc1 = (ParseContext1 *)parser->pc->priv_data;
	pc1->pc.frame_start_found = 0;
	
	MpegEncContext *s = pc1->enc;
	GetBitContext gb1, *gb = &gb1;
	
	s->avctx = parser->avctx;
	s->current_picture_ptr = &s->current_picture;
	
	init_get_bits(gb, buf, 8 * buf_size);
	ff_mpeg4_decode_picture_header(s, gb);
	return 1;
}

/*
 * Long story short, FFMpeg's parsers suck for our use.  This function parses an mpeg4 bitstream,
 * and assumes that it is given at least a full frame of data.
 * @param parser A FFusionParserContext structure containg all our info
 * @param buf The buffer to parse
 * @param buf_size Size of the input buffer
 * @param out_buf_size The number of bytes present in the first frame of data
 * @param type The frame Type: FF_*_TYPE
 * @param pts The PTS of the frame
 * @return 1 if a frame is found, 0 otherwise
 */
static int parse_mpeg4_stream(FFusionParserContext *parser, const uint8_t *buf, int buf_size, int *out_buf_size, int *type, int *skippable, int *skipped)
{
	ParseContext1 *pc1 = (ParseContext1 *)parser->pc->priv_data;
	pc1->pc.frame_start_found = 0;
	
	int endOfFrame = ff_mpeg4_find_frame_end(&(pc1->pc), buf, buf_size);
	
	MpegEncContext *s = pc1->enc;
	GetBitContext gb1, *gb = &gb1;
	
	s->avctx = parser->avctx;
	s->current_picture_ptr = &s->current_picture;
	
	init_get_bits(gb, buf, 8 * buf_size);
	int parse_res = ff_mpeg4_decode_picture_header(s, gb);
	if(parse_res == FRAME_SKIPPED) {
		*out_buf_size = buf_size;
		*type = FF_P_TYPE;
		*skippable = 1;
		*skipped = 1;
	}
	if(parse_res != 0)
		return 0;
	
	*type = s->pict_type;
	*skippable = (*type == FF_B_TYPE);
	*skipped = 0;
#if 0 /*this was an attempt to figure out the PTS information and detect an out of order P frame before we hit its B frame */
	int64_t *lastPtsPtr = (int64_t *)parser->internalContext;
	int64_t lastPts = *lastPtsPtr;
	int64_t currentPts = s->current_picture.pts;
	
	switch(s->pict_type)
	{
		case FF_I_TYPE:
			*lastPtsPtr = currentPts;
			*precedesAPastFrame = 0;
			break;
		case FF_P_TYPE:
			if(currentPts > lastPts + 1)
				*precedesAPastFrame = 1;
			else
				*precedesAPastFrame = 0;
			*lastPtsPtr = currentPts;
			break;
		case FF_B_TYPE:
			*precedesAPastFrame = 0;
			break;
		default:
			break;
	}
#endif
	
	if(endOfFrame == END_NOT_FOUND)
		*out_buf_size = buf_size;
	else
		*out_buf_size = endOfFrame;
	return 1;
}


(parser->pc is a struct AVCodecParserContext).

I'm a bit stuck on how to port this code/functionality. I'm guessing there must be a more official way, using published APIs, but for now I have no idea where to start looking.

Of course, if someone can help me to a set of Win32 DLLs for libavcodec, libavutil and libavcore of a compatible version (or give me some pointers on how to build them off the Perian code using a mingw23 crossCC) that would suit me too ... O:-)


TIA,
René


More information about the Libav-user mailing list