From 6cbcaba2a80c47714e8aa45d021bdcd4965780b1 Mon Sep 17 00:00:00 2001
From: Mole Shang <135e2@135e2.dev>
Date: Thu, 10 Aug 2023 14:15:00 +0800
Subject: ui: show progress while remuxing

---
 src/utils/ffmpeg.c    | 22 ++++++++++++++++++----
 src/utils/ffmpeg.h    |  4 ++++
 src/utils/time_info.c |  8 ++++++++
 src/utils/time_info.h |  6 ++++++
 4 files changed, 36 insertions(+), 4 deletions(-)
 create mode 100644 src/utils/time_info.c
 create mode 100644 src/utils/time_info.h

(limited to 'src/utils')

diff --git a/src/utils/ffmpeg.c b/src/utils/ffmpeg.c
index 98d2ba1..8a6d114 100644
--- a/src/utils/ffmpeg.c
+++ b/src/utils/ffmpeg.c
@@ -9,6 +9,8 @@
 #include "../logger.h"
 #include "ffmpeg.h"
 
+static status_t *stat_g;
+
 #ifdef DEBUG
 static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt,
                        const char *tag) {
@@ -28,6 +30,8 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt,
 }
 #endif
 
+void setup_stat(status_t *stat) { stat_g = stat; }
+
 int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
   AVFormatContext *input1_format_context = NULL, *input2_format_context = NULL,
                   *output_format_context = NULL;
@@ -66,6 +70,8 @@ int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
     goto end;
   }
 
+  stat_g->total = input1_format_context->duration / AV_TIME_BASE;
+
   avformat_alloc_output_context2(&output_format_context, NULL, NULL, outfn);
   if (!output_format_context) {
     append_log("Could not create output context\n");
@@ -172,6 +178,9 @@ int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
                                    out_stream->time_base);
     packet.pos = -1;
     // log_packet(output_format_context, &packet, "out");
+    stat_g->cur = (stat_g->cur <= stat_g->total)
+                      ? av_q2d(in_stream->time_base) * packet.pts
+                      : stat_g->total;
 
     ret = av_interleaved_write_frame(output_format_context, &packet);
     if (ret < 0) {
@@ -196,7 +205,7 @@ int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
         streams_list[packet.stream_index + input1_format_context->nb_streams];
     out_stream = output_format_context->streams[packet.stream_index];
     /* copy packet */
-    log_packet(input2_format_context, &packet, "in");
+    // log_packet(input2_format_context, &packet, "in");
     packet.pts = av_rescale_q_rnd(packet.pts, in_stream->time_base,
                                   out_stream->time_base,
                                   AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
@@ -206,8 +215,10 @@ int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
     packet.duration = av_rescale_q(packet.duration, in_stream->time_base,
                                    out_stream->time_base);
     packet.pos = -1;
-    log_packet(output_format_context, &packet, "out");
-
+    // log_packet(output_format_context, &packet, "out");
+    stat_g->cur = (stat_g->cur <= stat_g->total)
+                      ? av_q2d(in_stream->time_base) * packet.pts
+                      : stat_g->total;
     ret = av_interleaved_write_frame(output_format_context, &packet);
     if (ret < 0) {
       append_log("Error muxing packet\n");
@@ -271,6 +282,7 @@ int remux(const char *in_filename, const char *out_filename) {
 
   DEBUG_PRINT("duration: %.2Lf\n",
               (long double)ifmt_ctx->duration / AV_TIME_BASE);
+  stat_g->total = ifmt_ctx->duration / AV_TIME_BASE;
 
   av_dump_format(ifmt_ctx, 0, in_filename, 0);
 
@@ -356,7 +368,9 @@ int remux(const char *in_filename, const char *out_filename) {
     av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
     pkt->pos = -1;
     // log_packet(ofmt_ctx, pkt, "out");
-
+    stat_g->cur = (stat_g->cur <= stat_g->total)
+                      ? av_q2d(in_stream->time_base) * pkt->pts
+                      : stat_g->total;
     ret = av_interleaved_write_frame(ofmt_ctx, pkt);
     /* pkt is now blank (av_interleaved_write_frame() takes ownership of
      * its contents and resets pkt), so that no unreferencing is necessary.
diff --git a/src/utils/ffmpeg.h b/src/utils/ffmpeg.h
index 1ca949d..1dae806 100644
--- a/src/utils/ffmpeg.h
+++ b/src/utils/ffmpeg.h
@@ -1,6 +1,10 @@
 #ifndef FFMPEG_H_
 #define FFMPEG_H_
 
+#include "../status.h"
+
+void setup_stat(status_t *status);
+
 int merge_av(const char *videofn, const char *audiofn, const char *outfn);
 
 int remux(const char *inputfn, const char *outfn);
diff --git a/src/utils/time_info.c b/src/utils/time_info.c
new file mode 100644
index 0000000..f825a72
--- /dev/null
+++ b/src/utils/time_info.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+void sec2timestamp(int seconds, char **p_ts) {
+  int hours = seconds / 3600;
+  int minutes = (seconds % 3600) / 60;
+  int secs = seconds % 60;
+  sprintf(*p_ts, "%02d:%02d:%02d", hours, minutes, secs);
+}
diff --git a/src/utils/time_info.h b/src/utils/time_info.h
new file mode 100644
index 0000000..35bf256
--- /dev/null
+++ b/src/utils/time_info.h
@@ -0,0 +1,6 @@
+#ifndef TIME_INFO_H_
+#define TIME_INFO_H_
+
+void sec2timestamp(int seconds, char **p_ts);
+
+#endif
-- 
cgit v1.2.3