diff mbox

[FFmpeg-devel] fftools/ffmpeg.c: allow forcing input framerate on streamcopy

Message ID 55c1c681-d8df-376c-7c37-60ad0c9dfdee@gmail.com
State Superseded
Headers show

Commit Message

Leo Izen Oct. 19, 2018, 11:29 p.m. UTC
On 10/19/18 3:02 PM, Carl Eugen Hoyos wrote:
> 2018-10-19 20:39 GMT+02:00, Leo Izen <leo.izen@gmail.com>:
>> On 10/19/18 2:26 PM, Carl Eugen Hoyos wrote:
>>> 2018-10-19 4:58 GMT+02:00, Leo Izen <leo.izen@gmail.com>:
>>>> ---
>>>>    fftools/ffmpeg.c | 8 +++++---
>>>>    1 file changed, 5 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
>>>> index da4259a9a8..5d68194676 100644
>>>> --- a/fftools/ffmpeg.c
>>>> +++ b/fftools/ffmpeg.c
>>>> @@ -2045,12 +2045,14 @@ static void do_streamcopy(InputStream *ist,
>>>> OutputStream *ost, const AVPacket *p
>>>>        if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
>>>>            ost->sync_opts++;
>>>>
>>>> -    if (pkt->pts != AV_NOPTS_VALUE)
>>>> +    if (ist->framerate.num)
>>>> +        opkt.pts = av_rescale_q(ist->pts, AV_TIME_BASE_Q,
>>>> ost->mux_timebase) - ost_tb_start_time;
>>>> +    else if (pkt->pts != AV_NOPTS_VALUE)
>>>>            opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base,
>>>> ost->mux_timebase) - ost_tb_start_time;
>>>>        else
>>>>            opkt.pts = AV_NOPTS_VALUE;
>>>>
>>>> -    if (pkt->dts == AV_NOPTS_VALUE)
>>>> +    if (pkt->dts == AV_NOPTS_VALUE || ist->framerate.num)
>>>>            opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q,
>>>> ost->mux_timebase);
>>>>        else
>>>>            opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base,
>>>> ost->mux_timebase);
>>>> @@ -2602,7 +2604,7 @@ static int process_input_packet(InputStream *ist,
>>>> const AVPacket *pkt, int no_eo
>>>>            avpkt = *pkt;
>>>>        }
>>>>
>>>> -    if (pkt && pkt->dts != AV_NOPTS_VALUE) {
>>>> +    if (pkt && pkt->dts != AV_NOPTS_VALUE && !ist->framerate.num) {
>>>>            ist->next_dts = ist->dts = av_rescale_q(pkt->dts,
>>>> ist->st->time_base, AV_TIME_BASE_Q);
>>>>            if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_VIDEO ||
>>>> !ist->decoding_needed)
>>>>                ist->next_pts = ist->pts = ist->dts;
>>> How can this be tested?
>>>
>>> Carl Eugen
>> I'm not entirely sure. I ran "make fate" and it passed, and I
>> successfully rescaled a 30fps clip to 15fps, 20fps, 45fps, and 60fps
>> using -r:v as an input option. I'm not entirely sure what the standard
>> procedure is for performing more rigorous tests.
> What I meant was:
> Which kind of input and output did you use to test your patch?
>
> Carl Eugen
> _______________________________________________

It worked perfectly at various framerates for AVI files. It also worked 
in practice for MP4 and Matroska files, although my patch doesn't 
properly set the avg_frame_rate and r_frame_rate of the output stream. 
Intelligent players like MPV play it fine and ignore the incorrect 
*_frame_rate metadata. Anyway, here's an updated patch that fixes that 
problem so it shouldn't be an issue.

Leo Izen

---
  fftools/ffmpeg.c | 19 ++++++++++++++-----
  1 file changed, 14 insertions(+), 5 deletions(-)

          opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, 
ost->mux_timebase);
      else
          opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, 
ost->mux_timebase);
@@ -2602,7 +2604,7 @@ static int process_input_packet(InputStream *ist, 
const AVPacket *pkt, int no_eo
          avpkt = *pkt;
      }

-    if (pkt && pkt->dts != AV_NOPTS_VALUE) {
+    if (pkt && pkt->dts != AV_NOPTS_VALUE && !ist->framerate.num) {
          ist->next_dts = ist->dts = av_rescale_q(pkt->dts, 
ist->st->time_base, AV_TIME_BASE_Q);
          if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_VIDEO || 
!ist->decoding_needed)
              ist->next_pts = ist->pts = ist->dts;
@@ -3158,8 +3160,15 @@ static int 
init_output_stream_streamcopy(OutputStream *ost)
          else
              sar = par_src->sample_aspect_ratio;
          ost->st->sample_aspect_ratio = par_dst->sample_aspect_ratio = sar;
-        ost->st->avg_frame_rate = ist->st->avg_frame_rate;
-        ost->st->r_frame_rate = ist->st->r_frame_rate;
+
+        if (ist->framerate.num) {
+            ost->st->avg_frame_rate = ist->framerate;
+            ost->st->r_frame_rate = ist->framerate;
+        } else {
+            ost->st->avg_frame_rate = ist->st->avg_frame_rate;
+            ost->st->r_frame_rate = ist->st->r_frame_rate;
+        }
+
          break;
      }

Comments

Michael Niedermayer Oct. 20, 2018, 10:47 p.m. UTC | #1
On Fri, Oct 19, 2018 at 07:29:28PM -0400, Leo Izen wrote:
> 
> On 10/19/18 3:02 PM, Carl Eugen Hoyos wrote:
> >2018-10-19 20:39 GMT+02:00, Leo Izen <leo.izen@gmail.com>:
> >>On 10/19/18 2:26 PM, Carl Eugen Hoyos wrote:
> >>>2018-10-19 4:58 GMT+02:00, Leo Izen <leo.izen@gmail.com>:
> >>>>---
> >>>>   fftools/ffmpeg.c | 8 +++++---
> >>>>   1 file changed, 5 insertions(+), 3 deletions(-)
> >>>>
> >>>>diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> >>>>index da4259a9a8..5d68194676 100644
> >>>>--- a/fftools/ffmpeg.c
> >>>>+++ b/fftools/ffmpeg.c
> >>>>@@ -2045,12 +2045,14 @@ static void do_streamcopy(InputStream *ist,
> >>>>OutputStream *ost, const AVPacket *p
> >>>>       if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
> >>>>           ost->sync_opts++;
> >>>>
> >>>>-    if (pkt->pts != AV_NOPTS_VALUE)
> >>>>+    if (ist->framerate.num)
> >>>>+        opkt.pts = av_rescale_q(ist->pts, AV_TIME_BASE_Q,
> >>>>ost->mux_timebase) - ost_tb_start_time;
> >>>>+    else if (pkt->pts != AV_NOPTS_VALUE)
> >>>>           opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base,
> >>>>ost->mux_timebase) - ost_tb_start_time;
> >>>>       else
> >>>>           opkt.pts = AV_NOPTS_VALUE;
> >>>>
> >>>>-    if (pkt->dts == AV_NOPTS_VALUE)
> >>>>+    if (pkt->dts == AV_NOPTS_VALUE || ist->framerate.num)
> >>>>           opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q,
> >>>>ost->mux_timebase);
> >>>>       else
> >>>>           opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base,
> >>>>ost->mux_timebase);
> >>>>@@ -2602,7 +2604,7 @@ static int process_input_packet(InputStream *ist,
> >>>>const AVPacket *pkt, int no_eo
> >>>>           avpkt = *pkt;
> >>>>       }
> >>>>
> >>>>-    if (pkt && pkt->dts != AV_NOPTS_VALUE) {
> >>>>+    if (pkt && pkt->dts != AV_NOPTS_VALUE && !ist->framerate.num) {
> >>>>           ist->next_dts = ist->dts = av_rescale_q(pkt->dts,
> >>>>ist->st->time_base, AV_TIME_BASE_Q);
> >>>>           if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_VIDEO ||
> >>>>!ist->decoding_needed)
> >>>>               ist->next_pts = ist->pts = ist->dts;
> >>>How can this be tested?
> >>>
> >>>Carl Eugen
> >>I'm not entirely sure. I ran "make fate" and it passed, and I
> >>successfully rescaled a 30fps clip to 15fps, 20fps, 45fps, and 60fps
> >>using -r:v as an input option. I'm not entirely sure what the standard
> >>procedure is for performing more rigorous tests.
> >What I meant was:
> >Which kind of input and output did you use to test your patch?
> >
> >Carl Eugen
> >_______________________________________________
> 
> It worked perfectly at various framerates for AVI files. It also worked in
> practice for MP4 and Matroska files, although my patch doesn't properly set
> the avg_frame_rate and r_frame_rate of the output stream. Intelligent
> players like MPV play it fine and ignore the incorrect *_frame_rate
> metadata. Anyway, here's an updated patch that fixes that problem so it
> shouldn't be an issue.
> 
> Leo Izen
> 
> ---

>  fftools/ffmpeg.c | 19 ++++++++++++++-----
>  1 file changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index da4259a9a8..6e81716795 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -2045,12 +2045,14 @@ static void do_streamcopy(InputStream *ist,
> OutputStream *ost, const AVPacket *p

This will not apply as it has too many newlines

[...]
Leo Izen Oct. 21, 2018, 2:42 a.m. UTC | #2
On 10/20/18 6:47 PM, Michael Niedermayer wrote:
> On Fri, Oct 19, 2018 at 07:29:28PM -0400, Leo Izen wrote:
>> On 10/19/18 3:02 PM, Carl Eugen Hoyos wrote:
>>> 2018-10-19 20:39 GMT+02:00, Leo Izen <leo.izen@gmail.com>:
>>>> On 10/19/18 2:26 PM, Carl Eugen Hoyos wrote:
>>>>> 2018-10-19 4:58 GMT+02:00, Leo Izen <leo.izen@gmail.com>:
>>>>>> ---
>>>>>>    fftools/ffmpeg.c | 8 +++++---
>>>>>>    1 file changed, 5 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
>>>>>> index da4259a9a8..5d68194676 100644
>>>>>> --- a/fftools/ffmpeg.c
>>>>>> +++ b/fftools/ffmpeg.c
>>>>>> @@ -2045,12 +2045,14 @@ static void do_streamcopy(InputStream *ist,
>>>>>> OutputStream *ost, const AVPacket *p
>>>>>>        if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
>>>>>>            ost->sync_opts++;
>>>>>>
>>>>>> -    if (pkt->pts != AV_NOPTS_VALUE)
>>>>>> +    if (ist->framerate.num)
>>>>>> +        opkt.pts = av_rescale_q(ist->pts, AV_TIME_BASE_Q,
>>>>>> ost->mux_timebase) - ost_tb_start_time;
>>>>>> +    else if (pkt->pts != AV_NOPTS_VALUE)
>>>>>>            opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base,
>>>>>> ost->mux_timebase) - ost_tb_start_time;
>>>>>>        else
>>>>>>            opkt.pts = AV_NOPTS_VALUE;
>>>>>>
>>>>>> -    if (pkt->dts == AV_NOPTS_VALUE)
>>>>>> +    if (pkt->dts == AV_NOPTS_VALUE || ist->framerate.num)
>>>>>>            opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q,
>>>>>> ost->mux_timebase);
>>>>>>        else
>>>>>>            opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base,
>>>>>> ost->mux_timebase);
>>>>>> @@ -2602,7 +2604,7 @@ static int process_input_packet(InputStream *ist,
>>>>>> const AVPacket *pkt, int no_eo
>>>>>>            avpkt = *pkt;
>>>>>>        }
>>>>>>
>>>>>> -    if (pkt && pkt->dts != AV_NOPTS_VALUE) {
>>>>>> +    if (pkt && pkt->dts != AV_NOPTS_VALUE && !ist->framerate.num) {
>>>>>>            ist->next_dts = ist->dts = av_rescale_q(pkt->dts,
>>>>>> ist->st->time_base, AV_TIME_BASE_Q);
>>>>>>            if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_VIDEO ||
>>>>>> !ist->decoding_needed)
>>>>>>                ist->next_pts = ist->pts = ist->dts;
>>>>> How can this be tested?
>>>>>
>>>>> Carl Eugen
>>>> I'm not entirely sure. I ran "make fate" and it passed, and I
>>>> successfully rescaled a 30fps clip to 15fps, 20fps, 45fps, and 60fps
>>>> using -r:v as an input option. I'm not entirely sure what the standard
>>>> procedure is for performing more rigorous tests.
>>> What I meant was:
>>> Which kind of input and output did you use to test your patch?
>>>
>>> Carl Eugen
>>> _______________________________________________
>> It worked perfectly at various framerates for AVI files. It also worked in
>> practice for MP4 and Matroska files, although my patch doesn't properly set
>> the avg_frame_rate and r_frame_rate of the output stream. Intelligent
>> players like MPV play it fine and ignore the incorrect *_frame_rate
>> metadata. Anyway, here's an updated patch that fixes that problem so it
>> shouldn't be an issue.
>>
>> Leo Izen
>>
>> ---
>>   fftools/ffmpeg.c | 19 ++++++++++++++-----
>>   1 file changed, 14 insertions(+), 5 deletions(-)
>>
>> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
>> index da4259a9a8..6e81716795 100644
>> --- a/fftools/ffmpeg.c
>> +++ b/fftools/ffmpeg.c
>> @@ -2045,12 +2045,14 @@ static void do_streamcopy(InputStream *ist,
>> OutputStream *ost, const AVPacket *p
> This will not apply as it has too many newlines
>
> [...]

What do you mean by "this will not apply"? Do you mean attempting to 
apply the patch fails? What do newline characters have anything to do 
with it?

Leo Izen
Moritz Barsnick Oct. 21, 2018, 11:23 a.m. UTC | #3
On Sat, Oct 20, 2018 at 22:42:55 -0400, Leo Izen wrote:
> On 10/20/18 6:47 PM, Michael Niedermayer wrote:
> > This will not apply as it has too many newlines
> What do you mean by "this will not apply"? Do you mean attempting to 
> apply the patch fails? What do newline characters have anything to do 
> with it?

You patch is corrupted by newlines introduced by your email client. You
may need to attach the patch as a file attachment, or use "git
send-email".

Moritz
diff mbox

Patch

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index da4259a9a8..6e81716795 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2045,12 +2045,14 @@  static void do_streamcopy(InputStream *ist, 
OutputStream *ost, const AVPacket *p
      if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
          ost->sync_opts++;

-    if (pkt->pts != AV_NOPTS_VALUE)
+    if (ist->framerate.num)
+        opkt.pts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, 
ost->mux_timebase) - ost_tb_start_time;
+    else if (pkt->pts != AV_NOPTS_VALUE)
          opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, 
ost->mux_timebase) - ost_tb_start_time;
      else
          opkt.pts = AV_NOPTS_VALUE;

-    if (pkt->dts == AV_NOPTS_VALUE)
+    if (pkt->dts == AV_NOPTS_VALUE || ist->framerate.num)