[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