You've already forked FrameTour-RenderWorker
fix(video): 解决视频时间戳处理和编码参数问题
- 统一归零视频起始时间戳,避免源素材非 0 起始 PTS 造成封装后首帧冻结 - 修改 setpts 滤镜表达式为 setpts=PTS-STARTPTS 格式 - 为所有速度调整场景应用标准化的时间戳处理 - 添加视频编码参数测试文件,确保 B 帧在各种硬件加速下被禁用 - 为软件、QSV 和 CUDA 硬件加速添加 B 帧禁用测试用例
This commit is contained in:
@@ -725,8 +725,11 @@ class RenderSegmentTsHandler(BaseHandler):
|
|||||||
break
|
break
|
||||||
|
|
||||||
combined_pts_factor = (1.0 / speed) * ospeed_factor
|
combined_pts_factor = (1.0 / speed) * ospeed_factor
|
||||||
|
# 统一归零视频起始时间戳,避免源素材非 0 起始 PTS 造成封装后首帧冻结
|
||||||
if combined_pts_factor != 1.0:
|
if combined_pts_factor != 1.0:
|
||||||
filters.append(f"setpts={combined_pts_factor}*PTS")
|
filters.append(f"setpts={combined_pts_factor}*(PTS-STARTPTS)")
|
||||||
|
else:
|
||||||
|
filters.append("setpts=PTS-STARTPTS")
|
||||||
|
|
||||||
# 2. LUT 调色
|
# 2. LUT 调色
|
||||||
if lut_file:
|
if lut_file:
|
||||||
|
|||||||
@@ -137,7 +137,22 @@ def test_ospeed_does_not_trigger_filter_complex(tmp_path):
|
|||||||
# 验证 setpts 滤镜
|
# 验证 setpts 滤镜
|
||||||
vf_idx = command.index('-vf')
|
vf_idx = command.index('-vf')
|
||||||
vf_value = command[vf_idx + 1]
|
vf_value = command[vf_idx + 1]
|
||||||
assert 'setpts=2.0*PTS' in vf_value
|
assert 'setpts=2.0*(PTS-STARTPTS)' in vf_value
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_speed_always_normalizes_pts(tmp_path):
|
||||||
|
handler = _create_handler(tmp_path)
|
||||||
|
render_spec = RenderSpec()
|
||||||
|
output_spec = OutputSpec(width=1080, height=1920, fps=30)
|
||||||
|
|
||||||
|
filters = handler._build_video_filters(
|
||||||
|
render_spec=render_spec,
|
||||||
|
output_spec=output_spec,
|
||||||
|
duration_ms=6000,
|
||||||
|
source_duration_sec=10.0,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert 'setpts=PTS-STARTPTS' in filters
|
||||||
|
|
||||||
|
|
||||||
def test_ospeed_combined_with_speed(tmp_path):
|
def test_ospeed_combined_with_speed(tmp_path):
|
||||||
@@ -153,7 +168,7 @@ def test_ospeed_combined_with_speed(tmp_path):
|
|||||||
source_duration_sec=10.0,
|
source_duration_sec=10.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert 'setpts=1.5*PTS' in filters
|
assert 'setpts=1.5*(PTS-STARTPTS)' in filters
|
||||||
|
|
||||||
|
|
||||||
def test_ospeed_with_complex_effects(tmp_path):
|
def test_ospeed_with_complex_effects(tmp_path):
|
||||||
@@ -171,7 +186,7 @@ def test_ospeed_with_complex_effects(tmp_path):
|
|||||||
# zoom 触发 filter_complex
|
# zoom 触发 filter_complex
|
||||||
assert '[v_base]' in filters
|
assert '[v_base]' in filters
|
||||||
# setpts 在 base_chain 中
|
# setpts 在 base_chain 中
|
||||||
assert 'setpts=2.0*PTS' in filters
|
assert 'setpts=2.0*(PTS-STARTPTS)' in filters
|
||||||
# zoom 正常处理
|
# zoom 正常处理
|
||||||
assert "overlay=0:0:enable='between(t,1.0,3.0)'" in filters
|
assert "overlay=0:0:enable='between(t,1.0,3.0)'" in filters
|
||||||
|
|
||||||
@@ -188,8 +203,8 @@ def test_only_first_ospeed_is_used(tmp_path):
|
|||||||
source_duration_sec=10.0,
|
source_duration_sec=10.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert 'setpts=2.0*PTS' in filters
|
assert 'setpts=2.0*(PTS-STARTPTS)' in filters
|
||||||
assert 'setpts=5.0*PTS' not in filters
|
assert 'setpts=5.0*(PTS-STARTPTS)' not in filters
|
||||||
|
|
||||||
|
|
||||||
def test_ospeed_affects_tpad_calculation(tmp_path):
|
def test_ospeed_affects_tpad_calculation(tmp_path):
|
||||||
|
|||||||
25
tests/unit/test_video_encode_args.py
Normal file
25
tests/unit/test_video_encode_args.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from constant import HW_ACCEL_CUDA, HW_ACCEL_NONE, HW_ACCEL_QSV
|
||||||
|
from handlers.base import get_video_encode_args
|
||||||
|
|
||||||
|
|
||||||
|
def _assert_bframe_disabled(args):
|
||||||
|
assert '-bf' in args
|
||||||
|
bf_index = args.index('-bf')
|
||||||
|
assert args[bf_index + 1] == '0'
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_video_encode_args_disable_b_frames_for_software():
|
||||||
|
args = get_video_encode_args(HW_ACCEL_NONE)
|
||||||
|
_assert_bframe_disabled(args)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_video_encode_args_disable_b_frames_for_qsv():
|
||||||
|
args = get_video_encode_args(HW_ACCEL_QSV)
|
||||||
|
_assert_bframe_disabled(args)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_video_encode_args_disable_b_frames_for_cuda():
|
||||||
|
args = get_video_encode_args(HW_ACCEL_CUDA)
|
||||||
|
_assert_bframe_disabled(args)
|
||||||
Reference in New Issue
Block a user