[FFmpeg-devel] [PATCH 2/2] MxPEG decoder
Anatoly Nenashev
anatoly.nenashev
Wed Nov 3 17:24:50 CET 2010
On 03.11.2010 18:54, Michael Niedermayer wrote:
> On Wed, Nov 03, 2010 at 06:11:11PM +0300, Anatoly Nenashev wrote:
>
>>
>> I have additional question. This patch works fine with ffplay, so this
>> command
>> ./ffplay stream.mxg
>> works fine and I see well syncronized video.
>>
>> But if I run
>> ./ffmpeg -i stream.mxg -f rawvideo /dev/null
>> there are a lot of messages:
>> [rawvideo @ 0x30f4d10] st:0 error, non monotone timestamps 1>= 1
>>
>> After some researches I found that right command line must be
>> ./ffmpeg -i stream.mxg -r 25 -f rawvideo /dev/null
>>
>> So it meens that user must manually define output FPS, otherwise it will
>> be 1/time_base. In case of mxg demuxer it is 1000000.
>> I think that it isn't so user friendly way. What can I do with this issue?
>>
> please show us what actual pts/dts values are being returned by your demuxer
> maybe there is something wrong with them
>
No, because ffplay works fine. But if you ask:
PTS = 0
PTS = 301649
PTS = 452451
PTS = 603265
PTS = 754087
PTS = 904892
PTS = 1055714
PTS = 1206524
PTS = 1357346
PTS = 1508156
PTS = 1658979
PTS = 1809785
PTS = 1960608
PTS = 2111417
PTS = 2262241
PTS = 2563873
PTS = 2865505
> also make sure tb_unreliable() returns non zero
>
It returns 1 because time_base={1,1000000}. I see it under gdb.
> and i assume there is no true fps value stored in the file?
>
No, mxg has variable fps.
I think the main issue in function do_video_out (ffmpeg.c). Let's see
few lines of code:
ffmpeg.c:1103
sync_ipts = get_sync_ipts(ost) / av_q2d(enc->time_base);
/* by default, we output a single frame */
nb_frames = 1;
*frame_size = 0;
if(video_sync_method){
double vdelta = sync_ipts - ost->sync_opts;
//FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
if (vdelta < -1.1)
nb_frames = 0;
else if (video_sync_method == 2 || (video_sync_method<0 &&
(s->oformat->flags & AVFMT_VARIABLE_FPS))){
if(vdelta<=-0.6){
nb_frames=0;
}else if(vdelta>0.6)
ost->sync_opts= lrintf(sync_ipts);
}else if (vdelta > 1.1)
nb_frames = lrintf(vdelta);
//fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64",
ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts,
get_sync_ipts(ost), nb_frames);
if (nb_frames == 0){
++nb_frames_drop;
if (verbose>2)
fprintf(stderr, "*** drop!\n");
}else if (nb_frames > 1) {
nb_frames_dup += nb_frames - 1;
if (verbose>2)
fprintf(stderr, "*** %d dup!\n", nb_frames-1);
}
}else
ost->sync_opts= lrintf(sync_ipts);
nb_frames= FFMIN(nb_frames, max_frames[AVMEDIA_TYPE_VIDEO] -
ost->frame_number);
First time call of "do_video_out" we have ost->sync_ist->pts = 0. Then
sync_ipts=0, vdelta = 0.0 and nb_frames=1.
Second time call of "do_video_out" we have ost->sync_ist->pts = 301649.
Then sync_ipts=301649, vdelta = 301649.0 and nb_frames=301649.
Thus second decoded frame will be cloned in output stream 301649 times.
That's the main reason for this issue.
More information about the ffmpeg-devel
mailing list