[FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-05 Thread manuelyuan
From: Mengyang Yuan 

In this case, the input video is of dynamic frame rate and we don't want to
duplicate or drop frames, but the output video duration calculated by DTS is
incorrect, I solved it by using PTS.
There are many UGC videos with dynamic frame rates, which are represented by
PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
video duration becomes longer.By reading the code of x264/encoder/encoder.c,
I found that in order to predict the B frame, x264 needs to ensure that there
are enough reference frames when DTS = 0, so the DTS of these reference frames
will subtract the cache time. However, the cache time includes the part of PTS
jumps, which results in the abnormal small DTS.

Signed-off-by: Mengyang Yuan 
---
 libavformat/movenc.c | 23 ++-
 libavformat/movenc.h |  2 ++
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 715bec1c2f..206aa48d8c 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1015,7 +1015,7 @@ static int get_cluster_duration(MOVTrack *track, int 
cluster_idx)
 return 0;
 
 if (cluster_idx + 1 == track->entry)
-next_dts = track->track_duration + track->start_dts;
+next_dts = track->end_dts;
 else
 next_dts = track->cluster[cluster_idx + 1].dts;
 
@@ -5149,8 +5149,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 mov->mdat_size = 0;
 for (i = 0; i < mov->nb_streams; i++) {
 if (mov->tracks[i].entry)
-mov->tracks[i].frag_start += mov->tracks[i].start_dts +
- mov->tracks[i].track_duration -
+mov->tracks[i].frag_start += mov->tracks[i].end_dts -
  mov->tracks[i].cluster[0].dts;
 mov->tracks[i].entry = 0;
 mov->tracks[i].end_reliable = 0;
@@ -5208,7 +5207,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 int64_t duration = 0;
 
 if (track->entry)
-duration = track->start_dts + track->track_duration -
+duration = track->end_dts -
track->cluster[0].dts;
 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
 if (!track->mdat_buf)
@@ -5281,7 +5280,7 @@ static int check_pkt(AVFormatContext *s, AVPacket *pkt)
 ref = trk->cluster[trk->entry - 1].dts;
 } else if (   trk->start_dts != AV_NOPTS_VALUE
&& !trk->frag_discont) {
-ref = trk->start_dts + trk->track_duration;
+ref = trk->end_dts;
 } else
 ref = pkt->dts; // Skip tests for the first packet
 
@@ -5494,7 +5493,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * of the last packet of the previous fragment based on 
track_duration,
  * which might not exactly match our dts. Therefore adjust the dts
  * of this packet to be what the previous packets duration 
implies. */
-trk->cluster[trk->entry].dts = trk->start_dts + 
trk->track_duration;
+trk->cluster[trk->entry].dts = trk->end_dts;
 /* We also may have written the pts and the corresponding duration
  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration 
match up with
  * the next fragment. This means the cts of the first sample must
@@ -5546,13 +5545,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
"this case.\n",
pkt->stream_index, pkt->dts);
 }
-trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
-trk->last_sample_is_subtitle_end = 0;
-
 if (pkt->pts == AV_NOPTS_VALUE) {
 av_log(s, AV_LOG_WARNING, "pts has no value\n");
 pkt->pts = pkt->dts;
 }
+if (trk->start_pts == AV_NOPTS_VALUE) {
+trk->start_pts = pkt->pts;
+}
+trk->track_duration = FFMAX(pkt->pts - trk->start_pts + pkt->duration, 
trk->track_duration);
+trk->end_dts = pkt->dts + pkt->duration;
+trk->last_sample_is_subtitle_end = 0;
+
 if (pkt->dts != pkt->pts)
 trk->flags |= MOV_TRACK_CTTS;
 trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
@@ -6295,7 +6298,9 @@ static int mov_init(AVFormatContext *s)
  * this is updated. */
 track->hint_track = -1;
 track->start_dts  = AV_NOPTS_VALUE;
+track->start_pts  = AV_NOPTS_VALUE;
 track->start_cts  = AV_NOPTS_VALUE;
+track->end_dts= AV_NOPTS_VALUE;
 track->end_pts= AV_NOPTS_VALUE;
 track->dts_shift  = AV_NOPTS_VALUE;
 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 68d6f23a5a..ddad2631d7 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -116,7 +116,9 @@ typedef struct MOVTrack {
 uint32_ttref_tag;
 int tref_id; ///< trackID of the reference

Re: [FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-07 Thread manuelyuan
Thanks for your reply! 
My changes break make fate but this is inevitable. I will update the 
corresponding references to make sure make fate success



At 2019-11-07 00:47:42, "Michael Niedermayer"  wrote:
>On Wed, Nov 06, 2019 at 10:36:11AM +0800, manuelyuan wrote:
>> From: Mengyang Yuan 
>> 
>> In this case, the input video is of dynamic frame rate and we don't want to
>> duplicate or drop frames, but the output video duration calculated by DTS is
>> incorrect, I solved it by using PTS.
>> There are many UGC videos with dynamic frame rates, which are represented by
>> PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
>> video duration becomes longer.By reading the code of x264/encoder/encoder.c,
>> I found that in order to predict the B frame, x264 needs to ensure that there
>> are enough reference frames when DTS = 0, so the DTS of these reference 
>> frames
>> will subtract the cache time. However, the cache time includes the part of 
>> PTS
>> jumps, which results in the abnormal small DTS.
>> 
>> Signed-off-by: Mengyang Yuan 
>> ---
>>  libavformat/movenc.c | 23 ++-
>>  libavformat/movenc.h |  2 ++
>>  2 files changed, 16 insertions(+), 9 deletions(-)
>
>this breaks make fate / changes checksums
>if the changes are intended, the references would need to be updated
>with the patch doing the change
>
>make: *** [fate-lavf-mp4] Error 1
>make: *** [fate-lavf-mov] Error 1
>make: *** [fate-binsub-movtextenc] Error 1
>make: *** [fate-movenc] Error 1
>
>thanks
>
>[...]
>-- 
>Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
>Asymptotically faster algorithms should always be preferred if you have
>asymptotical amounts of data
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-07 Thread manuelyuan
From: Mengyang Yuan 

In this case, the input video is of dynamic frame rate and we don't want to
duplicate or drop frames, but the output video duration calculated by DTS is
incorrect, I solved it by using PTS.
There are many UGC videos with dynamic frame rates, which are represented by
PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
video duration becomes longer.By reading the code of x264/encoder/encoder.c,
I found that in order to predict the B frame, x264 needs to ensure that there
are enough reference frames when DTS = 0, so the DTS of these reference frames
will subtract the cache time. However, the cache time includes the part of PTS
jumps, which results in the abnormal small DTS.

Signed-off-by: Mengyang Yuan 
---
 libavformat/movenc.c  | 23 ++-
 libavformat/movenc.h  |  2 ++
 tests/ref/fate/movenc | 20 ++--
 tests/ref/lavf/mov|  4 ++--
 tests/ref/lavf/mp4|  4 ++--
 5 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 715bec1c2f..206aa48d8c 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1015,7 +1015,7 @@ static int get_cluster_duration(MOVTrack *track, int 
cluster_idx)
 return 0;
 
 if (cluster_idx + 1 == track->entry)
-next_dts = track->track_duration + track->start_dts;
+next_dts = track->end_dts;
 else
 next_dts = track->cluster[cluster_idx + 1].dts;
 
@@ -5149,8 +5149,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 mov->mdat_size = 0;
 for (i = 0; i < mov->nb_streams; i++) {
 if (mov->tracks[i].entry)
-mov->tracks[i].frag_start += mov->tracks[i].start_dts +
- mov->tracks[i].track_duration -
+mov->tracks[i].frag_start += mov->tracks[i].end_dts -
  mov->tracks[i].cluster[0].dts;
 mov->tracks[i].entry = 0;
 mov->tracks[i].end_reliable = 0;
@@ -5208,7 +5207,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 int64_t duration = 0;
 
 if (track->entry)
-duration = track->start_dts + track->track_duration -
+duration = track->end_dts -
track->cluster[0].dts;
 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
 if (!track->mdat_buf)
@@ -5281,7 +5280,7 @@ static int check_pkt(AVFormatContext *s, AVPacket *pkt)
 ref = trk->cluster[trk->entry - 1].dts;
 } else if (   trk->start_dts != AV_NOPTS_VALUE
&& !trk->frag_discont) {
-ref = trk->start_dts + trk->track_duration;
+ref = trk->end_dts;
 } else
 ref = pkt->dts; // Skip tests for the first packet
 
@@ -5494,7 +5493,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * of the last packet of the previous fragment based on 
track_duration,
  * which might not exactly match our dts. Therefore adjust the dts
  * of this packet to be what the previous packets duration 
implies. */
-trk->cluster[trk->entry].dts = trk->start_dts + 
trk->track_duration;
+trk->cluster[trk->entry].dts = trk->end_dts;
 /* We also may have written the pts and the corresponding duration
  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration 
match up with
  * the next fragment. This means the cts of the first sample must
@@ -5546,13 +5545,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
"this case.\n",
pkt->stream_index, pkt->dts);
 }
-trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
-trk->last_sample_is_subtitle_end = 0;
-
 if (pkt->pts == AV_NOPTS_VALUE) {
 av_log(s, AV_LOG_WARNING, "pts has no value\n");
 pkt->pts = pkt->dts;
 }
+if (trk->start_pts == AV_NOPTS_VALUE) {
+trk->start_pts = pkt->pts;
+}
+trk->track_duration = FFMAX(pkt->pts - trk->start_pts + pkt->duration, 
trk->track_duration);
+trk->end_dts = pkt->dts + pkt->duration;
+trk->last_sample_is_subtitle_end = 0;
+
 if (pkt->dts != pkt->pts)
 trk->flags |= MOV_TRACK_CTTS;
 trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
@@ -6295,7 +6298,9 @@ static int mov_init(AVFormatContext *s)
  * this is updated. */
 track->hint_track = -1;
 track->start_dts  = AV_NOPTS_VALUE;
+track->start_pts  = AV_NOPTS_VALUE;
 track->start_cts  = AV_NOPTS_VALUE;
+track->end_dts= AV_NOPTS_VALUE;
 track->end_pts= AV_NOPTS_VALUE;
 track->dts_shift  = AV_NOPTS_VALUE;
 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 68d6f23a5a..ddad2631d7 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -116,7 

[FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-07 Thread manuelyuan
From: Mengyang Yuan 

In this case, the input video is of dynamic frame rate and we don't want to
duplicate or drop frames, but the output video duration calculated by DTS is
incorrect, I solved it by using PTS.
There are many UGC videos with dynamic frame rates, which are represented by
PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
video duration becomes longer.By reading the code of x264/encoder/encoder.c,
I found that in order to predict the B frame, x264 needs to ensure that there
are enough reference frames when DTS = 0, so the DTS of these reference frames
will subtract the cache time. However, the cache time includes the part of PTS
jumps, which results in the abnormal small DTS.

Signed-off-by: Mengyang Yuan 
---
 libavformat/movenc.c  | 23 ++-
 libavformat/movenc.h  |  2 ++
 tests/ref/fate/movenc | 20 ++--
 tests/ref/lavf/mov|  4 ++--
 tests/ref/lavf/mp4|  4 ++--
 5 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 715bec1c2f..206aa48d8c 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1015,7 +1015,7 @@ static int get_cluster_duration(MOVTrack *track, int 
cluster_idx)
 return 0;
 
 if (cluster_idx + 1 == track->entry)
-next_dts = track->track_duration + track->start_dts;
+next_dts = track->end_dts;
 else
 next_dts = track->cluster[cluster_idx + 1].dts;
 
@@ -5149,8 +5149,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 mov->mdat_size = 0;
 for (i = 0; i < mov->nb_streams; i++) {
 if (mov->tracks[i].entry)
-mov->tracks[i].frag_start += mov->tracks[i].start_dts +
- mov->tracks[i].track_duration -
+mov->tracks[i].frag_start += mov->tracks[i].end_dts -
  mov->tracks[i].cluster[0].dts;
 mov->tracks[i].entry = 0;
 mov->tracks[i].end_reliable = 0;
@@ -5208,7 +5207,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 int64_t duration = 0;
 
 if (track->entry)
-duration = track->start_dts + track->track_duration -
+duration = track->end_dts -
track->cluster[0].dts;
 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
 if (!track->mdat_buf)
@@ -5281,7 +5280,7 @@ static int check_pkt(AVFormatContext *s, AVPacket *pkt)
 ref = trk->cluster[trk->entry - 1].dts;
 } else if (   trk->start_dts != AV_NOPTS_VALUE
&& !trk->frag_discont) {
-ref = trk->start_dts + trk->track_duration;
+ref = trk->end_dts;
 } else
 ref = pkt->dts; // Skip tests for the first packet
 
@@ -5494,7 +5493,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * of the last packet of the previous fragment based on 
track_duration,
  * which might not exactly match our dts. Therefore adjust the dts
  * of this packet to be what the previous packets duration 
implies. */
-trk->cluster[trk->entry].dts = trk->start_dts + 
trk->track_duration;
+trk->cluster[trk->entry].dts = trk->end_dts;
 /* We also may have written the pts and the corresponding duration
  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration 
match up with
  * the next fragment. This means the cts of the first sample must
@@ -5546,13 +5545,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
"this case.\n",
pkt->stream_index, pkt->dts);
 }
-trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
-trk->last_sample_is_subtitle_end = 0;
-
 if (pkt->pts == AV_NOPTS_VALUE) {
 av_log(s, AV_LOG_WARNING, "pts has no value\n");
 pkt->pts = pkt->dts;
 }
+if (trk->start_pts == AV_NOPTS_VALUE) {
+trk->start_pts = pkt->pts;
+}
+trk->track_duration = FFMAX(pkt->pts - trk->start_pts + pkt->duration, 
trk->track_duration);
+trk->end_dts = pkt->dts + pkt->duration;
+trk->last_sample_is_subtitle_end = 0;
+
 if (pkt->dts != pkt->pts)
 trk->flags |= MOV_TRACK_CTTS;
 trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
@@ -6295,7 +6298,9 @@ static int mov_init(AVFormatContext *s)
  * this is updated. */
 track->hint_track = -1;
 track->start_dts  = AV_NOPTS_VALUE;
+track->start_pts  = AV_NOPTS_VALUE;
 track->start_cts  = AV_NOPTS_VALUE;
+track->end_dts= AV_NOPTS_VALUE;
 track->end_pts= AV_NOPTS_VALUE;
 track->dts_shift  = AV_NOPTS_VALUE;
 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 68d6f23a5a..ddad2631d7 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -116,7 

Re: [FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-07 Thread manuelyuan
I have try to make fate again and it still works, I do not know why it breaks 
fate-binsub-movtextenc on your side
My steps are:
1、./configure 
2、make fate
If I'm wrong, what should I do?


At 2019-11-08 02:21:16, "Michael Niedermayer"  wrote:
>On Thu, Nov 07, 2019 at 05:55:18PM +0800, manuelyuan wrote:
>> From: Mengyang Yuan 
>> 
>> In this case, the input video is of dynamic frame rate and we don't want to
>> duplicate or drop frames, but the output video duration calculated by DTS is
>> incorrect, I solved it by using PTS.
>> There are many UGC videos with dynamic frame rates, which are represented by
>> PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
>> video duration becomes longer.By reading the code of x264/encoder/encoder.c,
>> I found that in order to predict the B frame, x264 needs to ensure that there
>> are enough reference frames when DTS = 0, so the DTS of these reference 
>> frames
>> will subtract the cache time. However, the cache time includes the part of 
>> PTS
>> jumps, which results in the abnormal small DTS.
>> 
>> Signed-off-by: Mengyang Yuan 
>> ---
>>  libavformat/movenc.c  | 23 ++-
>>  libavformat/movenc.h  |  2 ++
>>  tests/ref/fate/movenc | 20 ++--
>>  tests/ref/lavf/mov|  4 ++--
>>  tests/ref/lavf/mp4|  4 ++--
>>  5 files changed, 30 insertions(+), 23 deletions(-)
>
>breaks fate-binsub-movtextenc
>...
>
>[mp4 @ 0x29327c0] Estimating the duration of the last packet in a fragment, 
>consider setting the duration field in AVPacket instead.
>size=   1kB time=00:00:05.85 bitrate=   1.3kbits/s speed=6.03e+04x
>video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing 
>overhead: 1809.803955%
>make: *** [fate-binsub-movtextenc] Error 1
>
>[...]
>-- 
>Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
>Any man who breaks a law that conscience tells him is unjust and willingly 
>accepts the penalty by staying in jail in order to arouse the conscience of 
>the community on the injustice of the law is at that moment expressing the 
>very highest respect for law. - Martin Luther King Jr
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-07 Thread manuelyuan
From: Mengyang Yuan 

In this case, the input video is of dynamic frame rate and we don't want to
duplicate or drop frames, but the output video duration calculated by DTS is
incorrect, I solved it by using PTS.
There are many UGC videos with dynamic frame rates, which are represented by
PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
video duration becomes longer.By reading the code of x264/encoder/encoder.c,
I found that in order to predict the B frame, x264 needs to ensure that there
are enough reference frames when DTS = 0, so the DTS of these reference frames
will subtract the cache time. However, the cache time includes the part of PTS
jumps, which results in the abnormal small DTS.

Signed-off-by: Mengyang Yuan 
---
 libavformat/movenc.c | 23 ++-
 libavformat/movenc.h |  2 ++
 tests/ref/fate/binsub-movtextenc |  2 +-
 tests/ref/fate/movenc| 20 ++--
 tests/ref/lavf/mov   |  4 ++--
 tests/ref/lavf/mp4   |  4 ++--
 6 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 715bec1c2f..206aa48d8c 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1015,7 +1015,7 @@ static int get_cluster_duration(MOVTrack *track, int 
cluster_idx)
 return 0;
 
 if (cluster_idx + 1 == track->entry)
-next_dts = track->track_duration + track->start_dts;
+next_dts = track->end_dts;
 else
 next_dts = track->cluster[cluster_idx + 1].dts;
 
@@ -5149,8 +5149,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 mov->mdat_size = 0;
 for (i = 0; i < mov->nb_streams; i++) {
 if (mov->tracks[i].entry)
-mov->tracks[i].frag_start += mov->tracks[i].start_dts +
- mov->tracks[i].track_duration -
+mov->tracks[i].frag_start += mov->tracks[i].end_dts -
  mov->tracks[i].cluster[0].dts;
 mov->tracks[i].entry = 0;
 mov->tracks[i].end_reliable = 0;
@@ -5208,7 +5207,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 int64_t duration = 0;
 
 if (track->entry)
-duration = track->start_dts + track->track_duration -
+duration = track->end_dts -
track->cluster[0].dts;
 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
 if (!track->mdat_buf)
@@ -5281,7 +5280,7 @@ static int check_pkt(AVFormatContext *s, AVPacket *pkt)
 ref = trk->cluster[trk->entry - 1].dts;
 } else if (   trk->start_dts != AV_NOPTS_VALUE
&& !trk->frag_discont) {
-ref = trk->start_dts + trk->track_duration;
+ref = trk->end_dts;
 } else
 ref = pkt->dts; // Skip tests for the first packet
 
@@ -5494,7 +5493,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * of the last packet of the previous fragment based on 
track_duration,
  * which might not exactly match our dts. Therefore adjust the dts
  * of this packet to be what the previous packets duration 
implies. */
-trk->cluster[trk->entry].dts = trk->start_dts + 
trk->track_duration;
+trk->cluster[trk->entry].dts = trk->end_dts;
 /* We also may have written the pts and the corresponding duration
  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration 
match up with
  * the next fragment. This means the cts of the first sample must
@@ -5546,13 +5545,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
"this case.\n",
pkt->stream_index, pkt->dts);
 }
-trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
-trk->last_sample_is_subtitle_end = 0;
-
 if (pkt->pts == AV_NOPTS_VALUE) {
 av_log(s, AV_LOG_WARNING, "pts has no value\n");
 pkt->pts = pkt->dts;
 }
+if (trk->start_pts == AV_NOPTS_VALUE) {
+trk->start_pts = pkt->pts;
+}
+trk->track_duration = FFMAX(pkt->pts - trk->start_pts + pkt->duration, 
trk->track_duration);
+trk->end_dts = pkt->dts + pkt->duration;
+trk->last_sample_is_subtitle_end = 0;
+
 if (pkt->dts != pkt->pts)
 trk->flags |= MOV_TRACK_CTTS;
 trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
@@ -6295,7 +6298,9 @@ static int mov_init(AVFormatContext *s)
  * this is updated. */
 track->hint_track = -1;
 track->start_dts  = AV_NOPTS_VALUE;
+track->start_pts  = AV_NOPTS_VALUE;
 track->start_cts  = AV_NOPTS_VALUE;
+track->end_dts= AV_NOPTS_VALUE;
 track->end_pts= AV_NOPTS_VALUE;
 track->dts_shift  = AV_NOPTS_VALUE;
 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
ind

Re: [FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-13 Thread manuelyuan
 ensure make fate works, please take a look


At 2019-11-08 12:12:58, "manuelyuan"  wrote:
>From: Mengyang Yuan 
>
>In this case, the input video is of dynamic frame rate and we don't want to
>duplicate or drop frames, but the output video duration calculated by DTS is
>incorrect, I solved it by using PTS.
>There are many UGC videos with dynamic frame rates, which are represented by
>PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
>video duration becomes longer.By reading the code of x264/encoder/encoder.c,
>I found that in order to predict the B frame, x264 needs to ensure that there
>are enough reference frames when DTS = 0, so the DTS of these reference frames
>will subtract the cache time. However, the cache time includes the part of PTS
>jumps, which results in the abnormal small DTS.
>
>Signed-off-by: Mengyang Yuan 
>---
> libavformat/movenc.c | 23 ++-
> libavformat/movenc.h |  2 ++
> tests/ref/fate/binsub-movtextenc |  2 +-
> tests/ref/fate/movenc| 20 ++--
> tests/ref/lavf/mov   |  4 ++--
> tests/ref/lavf/mp4   |  4 ++--
> 6 files changed, 31 insertions(+), 24 deletions(-)
>
>diff --git a/libavformat/movenc.c b/libavformat/movenc.c
>index 715bec1c2f..206aa48d8c 100644
>--- a/libavformat/movenc.c
>+++ b/libavformat/movenc.c
>@@ -1015,7 +1015,7 @@ static int get_cluster_duration(MOVTrack *track, int 
>cluster_idx)
> return 0;
> 
> if (cluster_idx + 1 == track->entry)
>-next_dts = track->track_duration + track->start_dts;
>+next_dts = track->end_dts;
> else
> next_dts = track->cluster[cluster_idx + 1].dts;
> 
>@@ -5149,8 +5149,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
>force)
> mov->mdat_size = 0;
> for (i = 0; i < mov->nb_streams; i++) {
> if (mov->tracks[i].entry)
>-mov->tracks[i].frag_start += mov->tracks[i].start_dts +
>- mov->tracks[i].track_duration -
>+mov->tracks[i].frag_start += mov->tracks[i].end_dts -
>  mov->tracks[i].cluster[0].dts;
> mov->tracks[i].entry = 0;
> mov->tracks[i].end_reliable = 0;
>@@ -5208,7 +5207,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
>force)
> int64_t duration = 0;
> 
> if (track->entry)
>-duration = track->start_dts + track->track_duration -
>+duration = track->end_dts -
>track->cluster[0].dts;
> if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
> if (!track->mdat_buf)
>@@ -5281,7 +5280,7 @@ static int check_pkt(AVFormatContext *s, AVPacket *pkt)
> ref = trk->cluster[trk->entry - 1].dts;
> } else if (   trk->start_dts != AV_NOPTS_VALUE
>&& !trk->frag_discont) {
>-ref = trk->start_dts + trk->track_duration;
>+ref = trk->end_dts;
> } else
> ref = pkt->dts; // Skip tests for the first packet
> 
>@@ -5494,7 +5493,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
>*pkt)
>  * of the last packet of the previous fragment based on 
> track_duration,
>  * which might not exactly match our dts. Therefore adjust the dts
>  * of this packet to be what the previous packets duration 
> implies. */
>-trk->cluster[trk->entry].dts = trk->start_dts + 
>trk->track_duration;
>+trk->cluster[trk->entry].dts = trk->end_dts;
> /* We also may have written the pts and the corresponding duration
>  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration 
> match up with
>  * the next fragment. This means the cts of the first sample must
>@@ -5546,13 +5545,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
>*pkt)
>"this case.\n",
>pkt->stream_index, pkt->dts);
> }
>-trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
>-trk->last_sample_is_subtitle_end = 0;
>-
> if (pkt->pts == AV_NOPTS_VALUE) {
> av_log(s, AV_LOG_WARNING, "pts has no value\n");
> pkt->pts = pkt->dts;
> }
>+if (trk->start_pts == AV_NOPTS_VALUE) {
>+trk->start_pts = pkt->pts;
>+}
>+trk->track_duration = FFMAX(pkt->pts - trk->start_pts + pkt->duration, 
>trk->track_duration);
>+trk->end_dts =

[FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-27 Thread manuelyuan
In this case, the input video is of dynamic frame rate and we don't want to
duplicate or drop frames, but the output video duration calculated by DTS is
incorrect, I solved it by using PTS.
There are many UGC videos with dynamic frame rates, which are represented by
PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
video duration becomes longer.By reading the code of x264/encoder/encoder.c,
I found that in order to predict the B frame, x264 needs to ensure that there
are enough reference frames when DTS = 0, so the DTS of these reference frames
will subtract the cache time. However, the cache time includes the part of PTS
jumps, which results in the abnormal small DTS.

Signed-off-by: Mengyang Yuan 
---
 libavformat/movenc.c | 23 ++-
 libavformat/movenc.h |  2 ++
 tests/ref/fate/binsub-movtextenc |  2 +-
 tests/ref/fate/movenc| 20 ++--
 tests/ref/lavf/mov   |  4 ++--
 tests/ref/lavf/mp4   |  4 ++--
 6 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 715bec1c2f..206aa48d8c 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1015,7 +1015,7 @@ static int get_cluster_duration(MOVTrack *track, int 
cluster_idx)
 return 0;
 
 if (cluster_idx + 1 == track->entry)
-next_dts = track->track_duration + track->start_dts;
+next_dts = track->end_dts;
 else
 next_dts = track->cluster[cluster_idx + 1].dts;
 
@@ -5149,8 +5149,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 mov->mdat_size = 0;
 for (i = 0; i < mov->nb_streams; i++) {
 if (mov->tracks[i].entry)
-mov->tracks[i].frag_start += mov->tracks[i].start_dts +
- mov->tracks[i].track_duration -
+mov->tracks[i].frag_start += mov->tracks[i].end_dts -
  mov->tracks[i].cluster[0].dts;
 mov->tracks[i].entry = 0;
 mov->tracks[i].end_reliable = 0;
@@ -5208,7 +5207,7 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
 int64_t duration = 0;
 
 if (track->entry)
-duration = track->start_dts + track->track_duration -
+duration = track->end_dts -
track->cluster[0].dts;
 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
 if (!track->mdat_buf)
@@ -5281,7 +5280,7 @@ static int check_pkt(AVFormatContext *s, AVPacket *pkt)
 ref = trk->cluster[trk->entry - 1].dts;
 } else if (   trk->start_dts != AV_NOPTS_VALUE
&& !trk->frag_discont) {
-ref = trk->start_dts + trk->track_duration;
+ref = trk->end_dts;
 } else
 ref = pkt->dts; // Skip tests for the first packet
 
@@ -5494,7 +5493,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  * of the last packet of the previous fragment based on 
track_duration,
  * which might not exactly match our dts. Therefore adjust the dts
  * of this packet to be what the previous packets duration 
implies. */
-trk->cluster[trk->entry].dts = trk->start_dts + 
trk->track_duration;
+trk->cluster[trk->entry].dts = trk->end_dts;
 /* We also may have written the pts and the corresponding duration
  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration 
match up with
  * the next fragment. This means the cts of the first sample must
@@ -5546,13 +5545,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
"this case.\n",
pkt->stream_index, pkt->dts);
 }
-trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
-trk->last_sample_is_subtitle_end = 0;
-
 if (pkt->pts == AV_NOPTS_VALUE) {
 av_log(s, AV_LOG_WARNING, "pts has no value\n");
 pkt->pts = pkt->dts;
 }
+if (trk->start_pts == AV_NOPTS_VALUE) {
+trk->start_pts = pkt->pts;
+}
+trk->track_duration = FFMAX(pkt->pts - trk->start_pts + pkt->duration, 
trk->track_duration);
+trk->end_dts = pkt->dts + pkt->duration;
+trk->last_sample_is_subtitle_end = 0;
+
 if (pkt->dts != pkt->pts)
 trk->flags |= MOV_TRACK_CTTS;
 trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
@@ -6295,7 +6298,9 @@ static int mov_init(AVFormatContext *s)
  * this is updated. */
 track->hint_track = -1;
 track->start_dts  = AV_NOPTS_VALUE;
+track->start_pts  = AV_NOPTS_VALUE;
 track->start_cts  = AV_NOPTS_VALUE;
+track->end_dts= AV_NOPTS_VALUE;
 track->end_pts= AV_NOPTS_VALUE;
 track->dts_shift  = AV_NOPTS_VALUE;
 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 68d6f23a5a..ddad263

Re: [FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-11-28 Thread manuelyuan
Of course I did,and I can give you the bad case videos for your analysis if you 
need. 
How can I give them to you?

At 2019-11-28 14:38:34, "Carl Eugen Hoyos"  wrote:
>
>
>> Am 28.11.2019 um 03:34 schrieb manuelyuan :
>> 
>> In this case, the input video is of dynamic frame rate and we don't want to
>> duplicate or drop frames, but the output video duration calculated by DTS is
>> incorrect, I solved it by using PTS.
>> There are many UGC videos with dynamic frame rates, which are represented by
>> PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
>> video duration becomes longer.By reading the code of x264/encoder/encoder.c,
>> I found that in order to predict the B frame, x264 needs to ensure that there
>> are enough reference frames when DTS = 0, so the DTS of these reference 
>> frames
>> will subtract the cache time. However, the cache time includes the part of 
>> PTS
>> jumps, which results in the abnormal small DTS.
>
>Do you have access to a stream analyser to verify the output file with your 
>patch?
>
>Carl Eugen
>___
>ffmpeg-devel mailing list
>ffmpeg-devel@ffmpeg.org
>https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>To unsubscribe, visit link above, or email
>ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-12-09 Thread manuelyuan
 I opened a ticket in https://trac.ffmpeg.org/ticket/8420
 my patch may be not absolutely right, but this problem should get your 
attention, thank you

At 2019-12-03 20:57:44, "Martin Storsjö"  wrote:
>On Thu, 28 Nov 2019, manuelyuan wrote:
>
>> There are many UGC videos with dynamic frame rates, which are represented by
>> PTS jumps. After transcoding with ffmpeg -vsync 0 or -vsync 2, the output
>> video duration becomes longer.
>
>Did you post any reproduction case of what, exactly (which field in which 
>box), you think is wrong?
>
>Right now, this patch, among other things, breaks the implied last 
>duration of the last packet in a fragment.
>
>This can be reproduced by with the lavf-movenc test, like this:
>$ make libavformat/tests/movenc
>$ libavformat/tests/movenc -w
>
>Then inspect vfr-noduration.mp4 (with a suitable tool, e.g. L-SMASH's 
>boxdumper). Previously, the last packet in each fragment got an 
>inferred/guessed duration (if the duration field of the AVFrame was zero) 
>based on earlier frame intervals, but with your patch it is zero.
>
>I'm fairly convinced that most of the changes in your patch shouldn't be 
>made, but to make the discussion proceed you need to _exactly_ specify 
>what you think is wrong, in a way that others can reproduce.
>
>// Martin
>
>___
>ffmpeg-devel mailing list
>ffmpeg-devel@ffmpeg.org
>https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>To unsubscribe, visit link above, or email
>ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] lavf/movenc: Replace dts by pts to calculate duration

2019-12-23 Thread manuelyuan
thank you,I learned

At 2019-12-16 06:17:33, "Martin Storsjö"  wrote:
>On Tue, 10 Dec 2019, manuelyuan wrote:
>
>> I opened a ticket in https://trac.ffmpeg.org/ticket/8420
>> my patch may be not absolutely right, but this problem should get your 
>> attention, thank you
>
>I sent a patch that doesn't mess up all the details in the fragmentation, 
>but only changes the calculation of duration for the relevant boxes.
>
>// Martin
>
>___
>ffmpeg-devel mailing list
>ffmpeg-devel@ffmpeg.org
>https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>To unsubscribe, visit link above, or email
>ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".