Well... three days passed, but I still couldn't find the problem.
I don't know which word is used for describing "get a wrong frame which is
several frames earlier than the correct one about 5-6 times per second" --
so I will just call it "screen splash".

I tested my program with eight files.
The audio part is always perfect, but the video part is very strange.
#1, h264, screen splashes after seeking;
#2-3, mpeg4, splashes after seeking;
#4, mpeg4, splashes even without seeking; (that is too bad...)
#5-7, h264, perfect;
#8, mpeg4, perfect.
And, all of them could be played perfectly by ffplay.

My program is composed in a structure other than ffplay's.
There are three important variables:
vp: queue of decoded AVFrame;
ap: array of buffers of decoded audio data;
mutex: just... a mutex.

And three functions:
_decode():
1. lock mutex;
2. get an AVPacket;
3. if it is a video packet, decode it, and push it into vp;
4. else if it is an audio packet, decode it, and push it into ap.
5. unlock mutex;
6. return.

audio_callback():
1. while ap is empty, call _decode(); when encountered EOF, return.
2. use data in ap. if not enough, go to step 1.

get_video_frame:
1. while ap is empty, call _decode(); when encountered EOF, return.
2. return vp.pop().

As well as the main loop:
1. initialize, run audio_callback in another thread;
2. if w_frame == NULL, then w_frame = get_video_frame();
3. convert w_frame into SDL_Overlay with sws_scale(), then show it on the
screen. then free w_frame, and set it as NULL.
4. if user requested to seek, lock mutex, free all data in vp and ap, call
av_seek_frame(),
    then call avcodec_flush_buffers() twice(for both video and audio),
    unlock mutex. then goto step 2.
5. w_frame = get_video_frame();
6. wait proper time for the next frame(we do this to sync the video to an
external clock).
7. go to step 2.

My player plays the movie a little more fluently than ffplay does(because
there are only two threads and one mutex ;-P),
but I don't know why it works so weirdly when seeking...

I tried to add an redundant "while (vp.element_number < 3 or
ap.element_number < 3) _decode();" between step 5 and 6 in the main
loop, but just made it worse: the screen will splash even without seeking.
It's really confusing.

Anyway, if don't mind reading a 700-line program, you could have a look at
this: https://github.com/wecing/SimpleAV

Thanks you all,
wecing.

On Mon, Jun 6, 2011 at 4:54 PM, wecing <[email protected]> wrote:

> Hi,
>
> My program works well if I don't do any seeking.
> But after doing that, it may get stuck for about 2-3 seconds;
> After that, it will get a wrong frame(several frames earlier than the
> correct one) frequently(about 5-6 times per second) and periodically.
>
> I have no idea what I did wrong. It seems that the PTS I got(using exactly
> ffplay's way) is correct.
>
> wecing.
>
_______________________________________________
libav-api mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-api

Reply via email to