[FFmpeg-devel] logic error in libavformat/utils.c ?
Daniel Steinberg
daniel
Tue Mar 24 01:46:29 CET 2009
I believe there is a typo in libavformat/utils.c::av_read_frame()
if(genpts && next_pkt->dts != AV_NOPTS_VALUE){
while(pktl && next_pkt->pts == AV_NOPTS_VALUE){
. . .
}
}
if( next_pkt->pts != AV_NOPTS_VALUE
>>> || next_pkt->dts == AV_NOPTS_VALUE
|| !genpts || eof){
/* read packet from packet buffer, if there is data */
*pkt = *next_pkt;
s->packet_buffer = pktl->next;
av_free(pktl);
return 0;
}
}
if (genpts){
int ret = av_read_frame_internal(s, pkt);
. . .
I encountered a consistent crash when AVFMT_FLAG_GENPTS was set and
the input (H.264) packets had valid dts, but no pts set. At some point in the
first loop that tries to assign pts from dts, pktl->next becomes NULL and it
enters the 'if' in question. Because next_pkt->dts is valid, the return is
not taken, and the if(genpts) block is entered, perhaps, erroneously.
At that point, s->packet_buffer_end == NULL, and the subsequent
call to add_to_pktbuf() crashes when it tries to dereference it.
Changing the test above to:
if( next_pkt->pts != AV_NOPTS_VALUE
>>> || next_pkt->dts != AV_NOPTS_VALUE
|| !genpts || eof){
solves the crash problem, seems to result in correct packet parsing,
and causes no ill effects in a wide selection of other videos that i tried,
but it is hard to tell where the real fault lay.
I can supply some errant media, if necessary, but first i wanted to
run this by y'all.
On Sat, Mar 21, 2009 at 4:31 AM, Baptiste Coudurier
<baptiste.coudurier at gmail.com> wrote:
> Humm, I'm not maintainer of this code, but the code seems to add packets
> to the packet buffer only when genpts is set.
>
> Consequently, according to the loop computing pts for the packets, and
> assuming your packets have dts set, pts for the packet should be set at
> some time, unless the dts are not monotone which would cause the test:
> "next_pkt->dts < pktl->pkt.dts" to be false.
The first time through the loop, *next_pkt == pktl->pkt, so that test is false.
When pktl->next == 0, the code proceeds to the next test, which does not
pass (because pts == AV_NOPTS_VALUE and dts is valid).
> I believe the test for dts == AV_NOPTS_VALUE is because if dts is not
> set, pts cannot be set and function must return the packet nontheless.
Well, it's hard to tell, from the copious comments, but i thought the intention
here was for the packet to be returned *because* either there is a timestamp
in one of pts/dts OR timestamps are not being generated.
Perhaps the problem is really in add_to_pktbuf, which should be setting,
(*plast_pktl) instead of (*plast_pktl)->next, at least when *plast_pktl == NULL.
-Daniel Steinberg
More information about the ffmpeg-devel
mailing list