patocolher commited on
Commit
a5768ac
Β·
verified Β·
1 Parent(s): ff3152b

Upload 2 files

Browse files
Files changed (2) hide show
  1. Dockerfile +6 -3
  2. app.py +41 -18
Dockerfile CHANGED
@@ -8,12 +8,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
8
  libfdk-aac-dev libx264-dev libx265-dev libnuma-dev \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
- # nv-codec-headers (necessΓ‘rio para h264_nvenc / hevc_nvenc)
12
  RUN git clone --depth 1 https://git.videolan.org/git/ffmpeg/nv-codec-headers.git /tmp/nv-codec-headers \
13
  && make -C /tmp/nv-codec-headers install \
14
  && rm -rf /tmp/nv-codec-headers
15
 
16
- # Compila ffmpeg 7.1.1 com libfdk_aac + NVENC
17
  RUN wget -q -O /tmp/ffmpeg.tar.bz2 https://ffmpeg.org/releases/ffmpeg-7.1.1.tar.bz2 \
18
  && tar xf /tmp/ffmpeg.tar.bz2 -C /tmp \
19
  && rm /tmp/ffmpeg.tar.bz2 \
@@ -25,14 +25,16 @@ RUN wget -q -O /tmp/ffmpeg.tar.bz2 https://ffmpeg.org/releases/ffmpeg-7.1.1.tar.
25
  --disable-everything \
26
  --enable-encoder=libx264,libx265,libfdk_aac,aac,h264_nvenc,hevc_nvenc \
27
  --enable-decoder=h264,hevc,aac,mp3,ac3,eac3,opus,vorbis,flac,pcm_s16le,pcm_s16be \
 
28
  --enable-demuxer=mov,mp4,matroska,avi,flv,mpegts,wav,mp3,aac,flac \
29
  --enable-muxer=mp4,matroska,null \
30
- --enable-filter=loudnorm,volume,aresample,scale,pad,mpdecimate,fps,null \
31
  --enable-protocol=file,pipe \
32
  --enable-libx264 \
33
  --enable-libx265 \
34
  --enable-libfdk-aac \
35
  --enable-nvenc \
 
36
  --enable-cuda \
37
  --enable-cuvid \
38
  --extra-cflags="-O2 -pipe -I/usr/local/cuda/include" \
@@ -63,6 +65,7 @@ COPY --from=builder /usr/local/bin/ffprobe /usr/local/bin/ffprobe
63
 
64
  RUN ffmpeg -version | head -3 \
65
  && ffmpeg -encoders 2>/dev/null | grep -E "fdk|nvenc" \
 
66
  && echo "βœ… ffmpeg OK"
67
 
68
  WORKDIR /app
 
8
  libfdk-aac-dev libx264-dev libx265-dev libnuma-dev \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
+ # nv-codec-headers (necessΓ‘rio para h264_nvenc / hevc_nvenc / cuvid)
12
  RUN git clone --depth 1 https://git.videolan.org/git/ffmpeg/nv-codec-headers.git /tmp/nv-codec-headers \
13
  && make -C /tmp/nv-codec-headers install \
14
  && rm -rf /tmp/nv-codec-headers
15
 
16
+ # Compila ffmpeg 7.1.1 com libfdk_aac + NVENC + scale_cuda
17
  RUN wget -q -O /tmp/ffmpeg.tar.bz2 https://ffmpeg.org/releases/ffmpeg-7.1.1.tar.bz2 \
18
  && tar xf /tmp/ffmpeg.tar.bz2 -C /tmp \
19
  && rm /tmp/ffmpeg.tar.bz2 \
 
25
  --disable-everything \
26
  --enable-encoder=libx264,libx265,libfdk_aac,aac,h264_nvenc,hevc_nvenc \
27
  --enable-decoder=h264,hevc,aac,mp3,ac3,eac3,opus,vorbis,flac,pcm_s16le,pcm_s16be \
28
+ --enable-hwaccel=h264_nvdec,hevc_nvdec \
29
  --enable-demuxer=mov,mp4,matroska,avi,flv,mpegts,wav,mp3,aac,flac \
30
  --enable-muxer=mp4,matroska,null \
31
+ --enable-filter=loudnorm,volume,aresample,scale,scale_cuda,hwupload_cuda,hwdownload,pad,mpdecimate,fps,null \
32
  --enable-protocol=file,pipe \
33
  --enable-libx264 \
34
  --enable-libx265 \
35
  --enable-libfdk-aac \
36
  --enable-nvenc \
37
+ --enable-nvdec \
38
  --enable-cuda \
39
  --enable-cuvid \
40
  --extra-cflags="-O2 -pipe -I/usr/local/cuda/include" \
 
65
 
66
  RUN ffmpeg -version | head -3 \
67
  && ffmpeg -encoders 2>/dev/null | grep -E "fdk|nvenc" \
68
+ && ffmpeg -filters 2>/dev/null | grep -E "scale_cuda|hwupload" \
69
  && echo "βœ… ffmpeg OK"
70
 
71
  WORKDIR /app
app.py CHANGED
@@ -56,6 +56,11 @@ def reencode_video(video_file, modo, resolucao, fps, crf_valor, normalizar_audio
56
  use_gpu = quer_gpu and gpu_disponivel()
57
  gpu_fallback = quer_gpu and not use_gpu
58
 
 
 
 
 
 
59
  # ── Filtro de vΓ­deo ─────────────────────────────────────────
60
  vf_parts = []
61
 
@@ -64,26 +69,40 @@ def reencode_video(video_file, modo, resolucao, fps, crf_valor, normalizar_audio
64
  tw, th = m.group(1), m.group(2)
65
  if is_vertical:
66
  tw, th = th, tw
67
- vf_parts.append(
68
- f"scale={tw}:{th}:force_original_aspect_ratio=increase,"
69
- f"crop={tw}:{th}"
70
- )
71
-
72
- vf_parts.append(f"fps={fps}")
 
 
73
 
74
- if remover_duplicados:
75
- vf_parts.append("mpdecimate=hi=1")
 
 
 
76
 
77
- vf = ",".join(vf_parts) if vf_parts else "null"
78
 
79
  # ── Monta comando base ──────────────────────────────────────
80
- # NOTA: Removido o -hwaccel cuda. Como usamos filtros de software (-vf),
81
- # deixar o FFmpeg decodificar na CPU e enviar direto pro NVENC Γ© muito
82
- # mais rΓ‘pido do que ficar transferindo frames da GPU pra CPU e vice-versa.
83
  cmd = ["ffmpeg", "-hide_banner", "-loglevel", "error", "-progress", "pipe:1", "-y"]
84
- cmd += ["-i", input_path, "-vf", vf]
85
 
86
- if remover_duplicados:
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  cmd += ["-fps_mode", "vfr"]
88
 
89
  # ── Codec de vΓ­deo + CRF/CQ ─────────────────────────────────
@@ -192,12 +211,16 @@ def reencode_video(video_file, modo, resolucao, fps, crf_valor, normalizar_audio
192
  reducao = round((1 - final_mb / orig_mb) * 100, 1)
193
 
194
  extras = []
 
 
 
 
195
  if normalizar_audio and has_audio:
196
  extras.append("Γ‘udio normalizado")
197
  elif not has_audio:
198
  extras.append("⚠️ sem faixa de Γ‘udio")
199
  if remover_duplicados:
200
- extras.append("frames duplicados removidos (forΓ§a uso de CPU)")
201
  if gpu_fallback:
202
  extras.append("⚠️ GPU indisponΓ­vel β†’ usou CPU")
203
 
@@ -208,7 +231,7 @@ def reencode_video(video_file, modo, resolucao, fps, crf_valor, normalizar_audio
208
  f"ReduΓ§Γ£o : {reducao}%\n"
209
  f"FPS : {fps}\n"
210
  f"CRF/CQ : {crf_valor}\n"
211
- f"Codec : {'NVENC' if use_gpu else 'CPU'}\n"
212
  f"Extras : {' | '.join(extras) if extras else 'nenhum'}"
213
  )
214
 
@@ -256,7 +279,7 @@ with gr.Blocks(title="Super Re-Encoder") as demo:
256
  normalizar_audio = gr.Checkbox(value=True,
257
  label="πŸ”Š Normalizar Γ‘udio (loudnorm -23 LUFS)")
258
  remover_duplicados = gr.Checkbox(value=True,
259
- label="πŸ—‘οΈ Remover frames duplicados (mpdecimate)")
260
 
261
  btn = gr.Button("πŸš€ RE-ENCODE AGORA", variant="primary", size="large")
262
 
@@ -271,4 +294,4 @@ with gr.Blocks(title="Super Re-Encoder") as demo:
271
  )
272
 
273
  demo.queue(max_size=5)
274
- demo.launch(server_name="0.0.0.0", server_port=7860, theme=gr.themes.Soft())
 
56
  use_gpu = quer_gpu and gpu_disponivel()
57
  gpu_fallback = quer_gpu and not use_gpu
58
 
59
+ # Pipeline 100% GPU sΓ³ Γ© possΓ­vel sem mpdecimate.
60
+ # O mpdecimate nΓ£o tem equivalente CUDA no FFmpeg, entΓ£o quando estΓ‘
61
+ # ativo o decode e os filtros sΓ£o forΓ§ados a rodar na CPU.
62
+ full_gpu_pipeline = use_gpu and not remover_duplicados
63
+
64
  # ── Filtro de vΓ­deo ─────────────────────────────────────────
65
  vf_parts = []
66
 
 
69
  tw, th = m.group(1), m.group(2)
70
  if is_vertical:
71
  tw, th = th, tw
72
+ if full_gpu_pipeline:
73
+ # scale_cuda mantΓ©m o frame na VRAM β€” zero transferΓͺncia CPU↔GPU
74
+ vf_parts.append(f"scale_cuda=w={tw}:h={th}:interp_algo=lanczos")
75
+ else:
76
+ vf_parts.append(
77
+ f"scale={tw}:{th}:force_original_aspect_ratio=increase,"
78
+ f"crop={tw}:{th}"
79
+ )
80
 
81
+ if not full_gpu_pipeline:
82
+ # No pipeline de CPU, fps e mpdecimate ficam no filtro de vΓ­deo
83
+ vf_parts.append(f"fps={fps}")
84
+ if remover_duplicados:
85
+ vf_parts.append("mpdecimate=hi=1")
86
 
87
+ vf = ",".join(vf_parts) if vf_parts else None
88
 
89
  # ── Monta comando base ──────────────────────────────────────
 
 
 
90
  cmd = ["ffmpeg", "-hide_banner", "-loglevel", "error", "-progress", "pipe:1", "-y"]
 
91
 
92
+ if full_gpu_pipeline:
93
+ # Decodifica direto na GPU β†’ frames ficam na VRAM o tempo todo
94
+ # Fluxo: GPU decode β†’ scale_cuda (VRAM) β†’ NVENC encode
95
+ cmd += ["-hwaccel", "cuda", "-hwaccel_output_format", "cuda"]
96
+
97
+ cmd += ["-i", input_path]
98
+
99
+ if vf:
100
+ cmd += ["-vf", vf]
101
+
102
+ if full_gpu_pipeline:
103
+ # FPS definido via parΓ’metro de saΓ­da β€” sem precisar de filtro de software
104
+ cmd += ["-r", str(fps)]
105
+ elif remover_duplicados:
106
  cmd += ["-fps_mode", "vfr"]
107
 
108
  # ── Codec de vΓ­deo + CRF/CQ ─────────────────────────────────
 
211
  reducao = round((1 - final_mb / orig_mb) * 100, 1)
212
 
213
  extras = []
214
+ if full_gpu_pipeline:
215
+ extras.append("pipeline GPU completo (decode+scale+encode na VRAM)")
216
+ elif use_gpu:
217
+ extras.append("encode NVENC / decode+scale na CPU")
218
  if normalizar_audio and has_audio:
219
  extras.append("Γ‘udio normalizado")
220
  elif not has_audio:
221
  extras.append("⚠️ sem faixa de Γ‘udio")
222
  if remover_duplicados:
223
+ extras.append("mpdecimate ativo β†’ decode forΓ§ado na CPU")
224
  if gpu_fallback:
225
  extras.append("⚠️ GPU indisponΓ­vel β†’ usou CPU")
226
 
 
231
  f"ReduΓ§Γ£o : {reducao}%\n"
232
  f"FPS : {fps}\n"
233
  f"CRF/CQ : {crf_valor}\n"
234
+ f"Codec : {'NVENC (pipeline GPU completo)' if full_gpu_pipeline else 'NVENC (encode GPU)' if use_gpu else 'CPU'}\n"
235
  f"Extras : {' | '.join(extras) if extras else 'nenhum'}"
236
  )
237
 
 
279
  normalizar_audio = gr.Checkbox(value=True,
280
  label="πŸ”Š Normalizar Γ‘udio (loudnorm -23 LUFS)")
281
  remover_duplicados = gr.Checkbox(value=True,
282
+ label="πŸ—‘οΈ Remover frames duplicados (mpdecimate β€” desative para pipeline GPU completo)")
283
 
284
  btn = gr.Button("πŸš€ RE-ENCODE AGORA", variant="primary", size="large")
285
 
 
294
  )
295
 
296
  demo.queue(max_size=5)
297
+ demo.launch(server_name="0.0.0.0", server_port=7860, theme=gr.themes.Soft())