[FFmpeg-devel] [PATCH 2/2] MxPEG decoder
Anatoly Nenashev
anatoly.nenashev
Wed Nov 3 17:58:15 CET 2010
On 03.11.2010 19:24, Anatoly Nenashev wrote:
> 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.
>
>
Also there is no problem with variable FPS containers like matroska. So
this command
./ffmpeg -i stream.mxg -vcodec mjpeg out.mkv
works fine.
Then file out.mkv can be successfully played.
More information about the ffmpeg-devel
mailing list