From 714c632ff6e6a18213443c9b94304d1fdba345d8 Mon Sep 17 00:00:00 2001
From: erankor <eran.kornblau@kaltura.com>
Date: Sun, 23 Apr 2017 12:28:59 +0300
Subject: [PATCH] ffmpeg: add video/audio_timescale options

video/audio_timescale set the encoding time base -
 0 - for video, uses 1/frame_rate, for audio uses 1/sample_rate (this is
  the default)
-1 - matches the input time base (when possible)
>0 - sets the time base to 1/(the provided timescale value)
---
 ffmpeg.c     | 36 ++++++++++++++++++++++++++++++++++--
 ffmpeg.h     |  2 ++
 ffmpeg_opt.c |  8 ++++++++
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index 70431e8..d18f923 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -3301,10 +3301,42 @@ static int init_output_stream_encode(OutputStream *ost)
         enc_ctx->sample_rate    = av_buffersink_get_sample_rate(ost->filter->filter);
         enc_ctx->channel_layout = av_buffersink_get_channel_layout(ost->filter->filter);
         enc_ctx->channels       = av_buffersink_get_channels(ost->filter->filter);
-        enc_ctx->time_base      = (AVRational){ 1, enc_ctx->sample_rate };
+
+        switch (audio_timescale) {
+        case -1:
+            if (ist) {
+                enc_ctx->time_base = ist->st->time_base;
+                break;
+            }
+            av_log(oc, AV_LOG_WARNING, "Input stream data not available, using the sample rate as the time base\n");
+            /* fall-through */
+        case 0:
+            enc_ctx->time_base = (AVRational){ 1, enc_ctx->sample_rate };
+            break;
+
+        default:
+            enc_ctx->time_base = (AVRational){ 1, audio_timescale };
+            break;
+        }
         break;
     case AVMEDIA_TYPE_VIDEO:
-        enc_ctx->time_base = av_inv_q(ost->frame_rate);
+        switch (video_timescale) {
+        case -1:
+            if (ist) {
+                enc_ctx->time_base = ist->st->time_base;
+                break;
+            }
+            av_log(oc, AV_LOG_WARNING, "Input stream data not available, using the frame rate as the time base\n");
+             /* fall-through */
+        case 0:
+            enc_ctx->time_base = av_inv_q(ost->frame_rate);
+            break;
+
+        default:
+            enc_ctx->time_base = (AVRational){ 1, video_timescale };
+            break;
+        }
+
         if (!(enc_ctx->time_base.num && enc_ctx->time_base.den))
             enc_ctx->time_base = av_buffersink_get_time_base(ost->filter->filter);
         if (   av_q2d(enc_ctx->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH
diff --git a/ffmpeg.h b/ffmpeg.h
index 4d0456c..84c168a 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -594,6 +594,8 @@ extern int do_pkt_dump;
 extern int copy_ts;
 extern int start_at_zero;
 extern int copy_tb;
+extern int audio_timescale;
+extern int video_timescale;
 extern int debug_ts;
 extern int exit_on_error;
 extern int abort_on_flags;
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index d1fe874..36a85c0 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -111,6 +111,8 @@ int do_pkt_dump       = 0;
 int copy_ts           = 0;
 int start_at_zero     = 0;
 int copy_tb           = -1;
+int audio_timescale   = 0;
+int video_timescale   = 0;
 int debug_ts          = 0;
 int exit_on_error     = 0;
 int abort_on_flags    = 0;
@@ -3392,6 +3394,12 @@ const OptionDef options[] = {
         "shift input timestamps to start at 0 when using copyts" },
     { "copytb",         HAS_ARG | OPT_INT | OPT_EXPERT,              { &copy_tb },
         "copy input stream time base when stream copying", "mode" },
+    { "video_timescale",HAS_ARG | OPT_INT | OPT_EXPERT,              { &video_timescale },
+        "time base for video encoding, two special values are defined -"
+        "0 = use frame rate, -1 = match source time base" },
+    { "audio_timescale",HAS_ARG | OPT_INT | OPT_EXPERT,              { &audio_timescale },
+        "time base for audio encoding, two special values are defined -"
+        "0 = use sample rate, -1 = match source time base" },
     { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
                         OPT_OUTPUT,                                  { .off = OFFSET(shortest) },
         "finish encoding within shortest input" },
-- 
2.9.2.windows.1

