[FFmpeg-devel] All packets are marked with PKT_FLAG_KEY when reading AVI files
Eyal Beit-Halachmi
eyal.b
Mon Sep 7 16:03:00 CEST 2009
Hello,
When reading video frames from AVI files using av_read_frame(), all
packets read have their packet->flags set to PKT_FLAG_KEY
In avidec.c, in avi_read_header(), for CODEC_TYPE_VIDEO codec, the
"need_parsing" is set to "st->need_parsing = AVSTREAM_PARSE_HEADERS ".
Then in utils.c, av_read_frame_internal(), the parser is initialized
and set to parse whole frames "st->parser->flags |=
PARSER_FLAG_COMPLETE_FRAMES ".
But when setting to parse whole frames, various parsers do not parse
but rather skip to the end of frame.
Here is h264_parse() and mpeg4_parse() code that do the skip:
...
if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
next= buf_size;
}else{
...
Now, in av_read_frame_internal(), when there is a parser, the
returned packet "flags" are set by "compute_pkt_fields()", rather than by
copying the value from the packet read by avi_read_packet().
Now, because the parser did not parse the frame, its key_frame and
pict_type are the defaults -1 and FF_I_TYPE respectively, and the packet is
always marked as KEY (as seen from the code below).
void compute_pkt_fields(AVFormatContext *s, AVStream *st,
AVCodecParserContext *pc, AVPacket *pkt)
{
...
/* update flags */
if(is_intra_only(st->codec))
pkt->flags |= PKT_FLAG_KEY;
else if (pc) {
pkt->flags = 0;
/* keyframe computation */
if (pc->key_frame == 1)
pkt->flags |= PKT_FLAG_KEY;
else if (pc->key_frame == -1 && pc->pict_type == FF_I_TYPE)
pkt->flags |= PKT_FLAG_KEY;
}
...
}
I have added code handling the PARSER_FLAG_COMPLETE_FRAMES case,
setting the packet flags by the read packets' ones:
...
else if (pc) {
pkt->flags = 0;
//Added code
if(pc->flags & PARSER_FLAG_COMPLETE_FRAMES)
pkt->flags = st->cur_pkt.flags;
else
//Added code
if (pc->key_frame == 1)
pkt->flags |= PKT_FLAG_KEY;
else if (pc->key_frame == -1 && pc->pict_type == FF_I_TYPE)
pkt->flags |= PKT_FLAG_KEY;
}
...
Eyal.
More information about the ffmpeg-devel
mailing list