Skip to content
This repository was archived by the owner on Nov 11, 2024. It is now read-only.

Commit 99b81ef

Browse files
authored
Merge pull request #189 from QuPengfei/multi-device
Multi device
2 parents 2a14f6b + 35e8df0 commit 99b81ef

File tree

7 files changed

+78
-46
lines changed

7 files changed

+78
-46
lines changed

common/ffmpegcmd.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,22 @@
3838
"AVC": "libx264",
3939
"HEVC": "libsvt_hevc"
4040
},
41-
"hw": {
41+
"vaapi": {
4242
"AVC": "h264_vaapi",
4343
"HEVC": "hevc_vaapi"
44+
},
45+
"qsv": {
46+
"AVC": "h264_qsv",
47+
"HEVC": "hevc_qsv"
4448
}
4549
}
4650
class FFMpegCmd:
47-
def __init__(self, in_params, out_params, streaming_type, params, loop=0, hw="false"):
51+
def __init__(self, in_params, out_params, streaming_type, params, loop=0, acc_type="sw", device=None):
4852
self._in_file=in_params
4953
self._target=out_params
5054
self._tc_params=params if params else default_params["tc_params"]
5155
self._hls_dash_params=params["hls_dash_params"] if "hls_dash_params" in params.keys() else default_params["hls_dash_params"]
52-
self._hw=hw
53-
self._platform="hw" if hw == "true" else "sw"
56+
self._acc_type=acc_type
5457

5558
self._segment_num=self._hls_dash_params["segment_num"]
5659
self._duration=self._hls_dash_params["duration"]
@@ -65,8 +68,16 @@ def __init__(self, in_params, out_params, streaming_type, params, loop=0, hw="fa
6568
self._cmd_base=["ffmpeg", "-hide_banner", "-y"]
6669
if loop:
6770
self._cmd_base = self._cmd_base + ["-stream_loop", "-1"]
68-
if self._hw == "true":
69-
self._cmd_base = self._cmd_base + ["-hwaccel", "vaapi", "-hwaccel_device", "/dev/dri/renderD128", "-hwaccel_output_format", "vaapi"]
71+
72+
self._device=device
73+
if not device and self._acc_type != "sw":
74+
self._device = "/dev/dri/renderD128"
75+
76+
if self._acc_type == "vaapi":
77+
self._cmd_base = self._cmd_base + ["-hwaccel", "vaapi", "-hwaccel_device", self._device, "-hwaccel_output_format", "vaapi"]
78+
elif self._acc_type == "qsv":
79+
self._cmd_base = self._cmd_base + ["-hwaccel", "qsv", "-qsv_device", self._device, "-c:v", "h264_qsv"]
80+
7081
self._cmd_base = self._cmd_base + ["-i", self._in_file]
7182

7283
self._keyframe_interval = 0
@@ -83,7 +94,7 @@ def __init__(self, in_params, out_params, streaming_type, params, loop=0, hw="fa
8394
self._codec = self._get_codec()
8495
# hls and dash
8596
self._cmd_static = ["-c:v", self._codec, "-profile:v", "main", "-sc_threshold", "0", "-strict", "-2"]
86-
if self._hw == "true":
97+
if self._acc_type != "sw":
8798
self._cmd_static = ["-profile:v", "main", "-c:v", self._codec]
8899
self._cmd_static += ["-g", str(self._keyframe_interval)]
89100

@@ -92,7 +103,7 @@ def _to_kps(self, bitrate):
92103
return str(int(bitrate/1000))+"k"
93104

94105
def _get_codec(self):
95-
return codec_setting[self._platform][self._codec_type]
106+
return codec_setting[self._acc_type][self._codec_type]
96107

97108
def stream_info(self, in_file):
98109
ffprobe_cmd = ["ffprobe", "-v", "quiet", "-print_format", "json", "-show_streams", in_file]
@@ -130,8 +141,11 @@ def _hls(self):
130141
continue
131142

132143
cmd_1 = ["-vf", "scale=w="+str(width)+":"+"h="+str(height)]
133-
if self._hw == "true":
144+
if self._acc_type == "vaapi":
134145
cmd_1 = ["-vf", "scale_vaapi=w="+str(width)+":"+"h="+str(height)+":format=nv12"]
146+
elif self._acc_type == "qsv":
147+
cmd_1 = ["-vf", "scale_qsv=w="+str(width)+":"+"h="+str(height)+":format=nv12"]
148+
135149
cmd_2 = ["-b:v", v_bitrate, "-maxrate", maxrate]
136150
cmd_3 = ["-f", self._streaming_type]
137151
cmd_4 = ["-hls_segment_filename", self._target+"/"+name+"_"+"%03d.ts", self._target+"/"+name+".m3u8"]
@@ -160,8 +174,10 @@ def _dash(self):
160174
if self._frame_height < height:
161175
continue
162176
cmd_1 = ["-map", "[out"+str(count) +"]", "-b:v"+":"+str(count), v_bitrate, "-maxrate"+":"+str(count), maxrate]
163-
if self._hw == "true":
177+
if self._acc_type == "vaapi":
164178
cmd_scale += [";", "[mid"+str(count) +"]", "scale_vaapi=w="+str(width)+":"+"h="+str(height)+":format=nv12","[out"+str(count) +"]"]
179+
elif self._acc_type == "qsv":
180+
cmd_scale += [";", "[mid"+str(count) +"]", "scale_qsv=w="+str(width)+":"+"h="+str(height)+":format=nv12","[out"+str(count) +"]"]
165181
else:
166182
cmd_scale += [";", "[mid"+str(count) +"]", "scale=w="+str(width)+":"+"h="+str(height),"[out"+str(count) +"]"]
167183
cmd_abr += cmd_1
@@ -182,14 +198,17 @@ def _tc(self):
182198
maxrate = self._to_kps(item[2] * self._max_bitrate_ratio)
183199
name= self._target+"/"+self._codec_type+"_"+str(height)+"p."+self._streaming_type if self._streaming_type == "mp4" else self._target+"_"+self._codec_type+str(height)+"p"
184200

185-
if self._hw == "true":
201+
if self._acc_type == "vaapi":
186202
cmd_1 += ["-vf", "scale_vaapi=w="+str(width)+":"+"h="+str(height)+":format=nv12", "-c:v", self._codec]
187203
cmd_1 += ["-profile:v", "main", "-b:v", v_bitrate, "-maxrate", v_bitrate, "-r", params["framerate"],"-g", params["gop_size"], "-bf", params["bframe"], "-an", "-f", self._streaming_type, name]
204+
elif self._acc_type == "qsv":
205+
cmd_1 += ["-vf", "scale_qsv=w="+str(width)+":"+"h="+str(height)+":format=nv12", "-c:v", self._codec]
206+
cmd_1 += ["-profile:v", "main", "-b:v", v_bitrate, "-maxrate", v_bitrate, "-r", params["framerate"],"-g", params["gop_size"], "-bf", params["bframe"], "-an", "-f", self._streaming_type, name]
188207
else:
189208
cmd_1 += ["-vf", "scale=w="+str(width)+":"+"h="+str(height),"-c:v", self._codec, "-b:v", v_bitrate]
190209
cmd_1 += ["-r", params["framerate"],"-g", params["gop_size"], "-bf", params["bframe"], "-refs", params["refs"], "-preset", params["preset"], "-forced-idr", params["forced_idr"], "-an", "-f", self._streaming_type, name]
191210

192-
return cmd_1 + ["-abr_pipeline"]
211+
return cmd_1
193212

194213
def cmd(self):
195214
cmd = []

deployment/kubernetes/helm/cdn-transcode/templates/vod.yaml

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11

2+
{{- range $deviceIdx := until ( int ( $.Values.hwDeviceNum ) ) }}
3+
24
apiVersion: apps/v1
35
kind: Deployment
46
metadata:
57
labels:
6-
app: vod-service
7-
name: vod-service
8+
app: vod-service-{{ $deviceIdx }}
9+
name: vod-service-{{ $deviceIdx }}
810
spec:
911
selector:
1012
matchLabels:
11-
app: vod-service
12-
replicas: {{ .Values.vodTranscode.replicas }}
13+
app: vod-service-{{ $deviceIdx }}
14+
replicas: {{ $.Values.vodTranscode.replicas }}
1315
template:
1416
metadata:
1517
creationTimestamp: null
1618
labels:
17-
app: vod-service
19+
app: vod-service-{{ $deviceIdx }}
1820
spec:
1921
containers:
2022
- args:
@@ -23,11 +25,13 @@ spec:
2325
- /home/main.py
2426
image: {{ $.Values.registryPrefix }}tc_transcode_{{ lower $.Values.platform }}:latest
2527
imagePullPolicy: IfNotPresent
26-
name: vod-service
28+
name: vod-service-{{ $deviceIdx }}
2729
env:
2830
{{- if ne $.Values.platform "Xeon" }}
29-
- name: HW_ACCELERATOR
30-
value: "true"
31+
- name: HW_ACC_TYPE
32+
value: {{ $.Values.hwAccType }}
33+
- name: HW_DEVICE
34+
value: /dev/dri/renderD{{ add $deviceIdx 128 }}
3135
{{- end }}
3236
- name: NO_PROXY
3337
value: "*"
@@ -45,6 +49,7 @@ spec:
4549
# gpu.intel.com/i915: 1
4650
securityContext:
4751
privileged: true
52+
runAsUser: 0
4853
{{- end }}
4954
volumes:
5055
- name: archive
@@ -55,6 +60,10 @@ spec:
5560
claimName: video-cache
5661
restartPolicy: Always
5762

63+
---
64+
{{- end }}
65+
66+
5867
{{- if eq "transcode" $.Values.scenario }}
5968
---
6069

@@ -71,10 +80,6 @@ spec:
7180
image: {{ $.Values.registryPrefix }}tc_benchmark_service:latest
7281
imagePullPolicy: IfNotPresent
7382
env:
74-
{{- if ne $.Values.platform "Xeon" }}
75-
- name: HW_ACCELERATOR
76-
value: "true"
77-
{{- end }}
7883
- name: NO_PROXY
7984
value: "*"
8085
- name: no_proxy
@@ -85,13 +90,6 @@ spec:
8590
readOnly: true
8691
- mountPath: /var/www/video
8792
name: video-cache
88-
{{- if ne $.Values.platform "Xeon" }}
89-
# resources:
90-
# limits:
91-
# gpu.intel.com/i915: 1
92-
securityContext:
93-
privileged: true
94-
{{- end }}
9593
volumes:
9694
- name: video-archive
9795
persistentVolumeClaim:

deployment/kubernetes/helm/cdn-transcode/values.yaml.m4

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ registryPrefix: "defn(`REGISTRY_PREFIX')"
44
# platform specifies the target platform: Xeon or XeonE3.
55
platform: "defn(`PLATFORM')"
66

7+
# transcoding with HW QSV or VAAPI: qsv or vaapi.
8+
hwAccType: "qsv"
9+
hwDeviceNum: ifelse(defn(`PLATFORM'),`SG1',4,1)
10+
711
# scenario specifies the mode: cdn or batch.
812
scenario: "defn(`SCENARIO')"
913

deployment/kubernetes/yaml/configure.m4

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11

2+
define(`HW_ACC_PLUGIN_TYPE',`qsv')
3+
define(`HW_DEVICE_NUM',ifelse(defn(`PLATFORM'),`SG1',4,1))
4+
25
define(`CDN_CPU',2)
36
define(`CDN_MEMORY',2000)
47

deployment/kubernetes/yaml/platform.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
define(`PLATFORM_SUFFIX',translit(defn(`PLATFORM'),`A-Z',`a-z'))dnl
22
define(`PLATFORM_RESOURCES',dnl
3-
ifelse(defn(`PLATFORM'),`XeonE3',dnl
3+
ifelse(defn(`PLATFORM'),`Xeon',,dnl
44
# resources:
55
# limits:
66
# gpu.intel.com/i915: 1

deployment/kubernetes/yaml/vod.yaml.m4

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
1-
include(platform.m4)
1+
include(../../../script/loop.m4)
22
include(configure.m4)
3+
include(platform.m4)
4+
5+
loop(DEVICEIDX,0,eval(defn(`HW_DEVICE_NUM')-1),`
36

47
apiVersion: apps/v1
58
kind: Deployment
69
metadata:
7-
name: vod
10+
name: vod-defn(`DEVICEIDX')
811
labels:
9-
app: vod
12+
app: vod-defn(`DEVICEIDX')
1013
spec:
1114
replicas: defn(`NVODS')
1215
selector:
1316
matchLabels:
14-
app: vod
17+
app: vod-defn(`DEVICEIDX')
1518
template:
1619
metadata:
1720
labels:
18-
app: vod
21+
app: vod-defn(`DEVICEIDX')
1922
spec:
2023
enableServiceLinks: false
2124
containers:
22-
- name: vod
25+
- name: vod-defn(`DEVICEIDX')
2326
image: defn(`REGISTRY_PREFIX')`tc_transcode_'defn(`PLATFORM_SUFFIX'):latest
2427
imagePullPolicy: IfNotPresent
2528
ifelse(defn(`SCENARIO'),`transcode',`dnl
@@ -32,8 +35,12 @@ ifelse(defn(`SCENARIO'),`transcode',`dnl
3235
memory: eval(defn(`VOD_MEMORY')*2)Mi
3336
')dnl
3437
env:
35-
- name: HW_ACCELERATOR
36-
value: ifelse(defn(`PLATFORM'),`Xeon',"false","true")
38+
- name: HW_ACC_TYPE
39+
value: ifelse(defn(`PLATFORM'),`Xeon',"sw","defn(`HW_ACC_PLUGIN_TYPE')")
40+
ifelse(defn(`PLATFORM'),`Xeon',,`dnl
41+
- name: HW_DEVICE
42+
value: "`/dev/dri/renderD'eval(defn(`DEVICEIDX')+128)"
43+
')dnl
3744
- name: NO_PROXY
3845
value: "*"
3946
- name: no_proxy
@@ -54,6 +61,9 @@ defn(`PLATFORM_RESOURCES')dnl
5461
claimName: video-archive
5562
PLATFORM_NODE_SELECTOR(`Xeon')dnl
5663

64+
---
65+
')
66+
5767
ifelse(defn(`SCENARIO'),`transcode',`
5868
---
5969

@@ -70,8 +80,6 @@ spec:
7080
image: defn(`REGISTRY_PREFIX')tc_benchmark_service:latest
7181
imagePullPolicy: IfNotPresent
7282
env:
73-
- name: HW_ACCELERATOR
74-
value: ifelse(defn(`PLATFORM'),`Xeon',"false","true")
7583
- name: NO_PROXY
7684
value: "*"
7785
- name: no_proxy
@@ -82,7 +90,6 @@ spec:
8290
readOnly: true
8391
- mountPath: /var/www/video
8492
name: video-cache
85-
defn(`PLATFORM_RESOURCES')dnl
8693
volumes:
8794
- name: video-archive
8895
persistentVolumeClaim:

xcode-server/main.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
HLS_ROOT = "/var/www/video/hls"
2727
MP4_ROOT = "/var/www/video/mp4"
2828

29-
hw=os.environ["HW_ACCELERATOR"]
29+
HW_ACC_TYPE=os.getenv("HW_ACC_TYPE","sw")
30+
HW_DEVICE=os.getenv("HW_DEVICE",None)
3031

3132
fps_regex = re.compile(
3233
r"\s*frame=\s*(?P<frame_count>\d+)\s*fps=\s*(?P<fps>\d+\.?\d*).*"
@@ -109,7 +110,7 @@ def process_stream_vods(msg):
109110

110111
if zk.process_start():
111112
try:
112-
cmd = FFMpegCmd(ARCHIVE_ROOT+"/"+stream_name, target_root+"/"+stream_name, stream_type, params=stream_parameters, hw=hw, loop=loop).cmd()
113+
cmd = FFMpegCmd(ARCHIVE_ROOT+"/"+stream_name, target_root+"/"+stream_name, stream_type, params=stream_parameters, acc_type=HW_ACC_TYPE, loop=loop, device=HW_DEVICE).cmd()
113114
if cmd:
114115
print(cmd, flush=True)
115116
r = execute(idx, stream_name, cmd)
@@ -155,7 +156,7 @@ def process_stream_lives(msg):
155156

156157
if zk.process_start():
157158
try:
158-
cmd = FFMpegCmd(ARCHIVE_ROOT+"/"+stream_name, target_name, stream_type, params=stream_parameters, hw=hw, loop=loop).cmd()
159+
cmd = FFMpegCmd(ARCHIVE_ROOT+"/"+stream_name, target_name, stream_type, params=stream_parameters, acc_type=HW_ACC_TYPE, loop=loop, device=HW_DEVICE).cmd()
159160

160161
if cmd:
161162
print(cmd, flush=True)

0 commit comments

Comments
 (0)