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é
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user