Changes of Revision 41

obs-studio.changes Changed
x
 
1
@@ -1,4 +1,36 @@
2
 -------------------------------------------------------------------
3
+Tue Jan 17 23:38:37 UTC 2017 - jimmy@boombatower.com
4
+
5
+- Update to version 17.0.1:
6
+  * deps/libff: Fix VP8/VP9/webm alpha support
7
+  * rtmp-services: Increase video bitrate limit for YouTube
8
+  * obs-outputs: fix build error on freebsd
9
+  * Update translations from Crowdin
10
+  * [CI] Use prebuilt deps so we can build on 10.9
11
+  * CI: Build more features into FFMPEG deps
12
+  * CI: Update browser plugin ref and build scripts.
13
+  * CI: Fix zip permission issue on CEF plist files
14
+  * obs-x264: ignore opencl param
15
+  * enc-amf: Update to 1.4.3.8
16
+  * CI: Ability to make packages on travis
17
+  * CI: actually call packagesbuild from the right place 😑
18
+  * cmake: Remove unnecessary find_package calls
19
+  * libobs: Fix scale filtering bug when duplicating scenes
20
+  * win-capture: Don't use FindWindow for game capture keepalive
21
+  * CI: Install Packages and use the full version
22
+  * Revert "win-capture: Use FindWindowEx to traverse window list"
23
+  * obs-filters.c: Fix color correction filter OpenGL crash
24
+  * obs-filters.c: Fix color correction filter saturation
25
+  * Update translations from Crowdin
26
+  * UI: Fix bug with uncopied profile import/export files
27
+  * win-capture: Fix game capture size bug when rehooking
28
+  * libobs: Add func to enum active and inactive child tree
29
+  * libobs: Enumerate full tree when adding active child
30
+  * libobs: Add callback for enumerating all scene children
31
+  * obs-x264: Allow opencl through much longer alias
32
+  * libobs: Update to version 17.0.1
33
+
34
+-------------------------------------------------------------------
35
 Mon Dec 26 08:32:58 UTC 2016 - jimmy@boombatower.com
36
 
37
 - Update to version 0.17.0:
38
obs-studio.spec Changed
8
 
1
@@ -1,5 +1,5 @@
2
 Name:           obs-studio
3
-Version:        0.17.0
4
+Version:        17.0.1
5
 Release:        0
6
 Summary:        A recording/broadcasting program
7
 
8
_service Changed
10
 
1
@@ -1,7 +1,7 @@
2
 <services>
3
   <service name="tar_scm" mode="disabled">
4
     <param name="versionformat">@PARENT_TAG@</param>
5
-    <param name="revision">refs/tags/0.17.0</param>
6
+    <param name="revision">refs/tags/17.0.1</param>
7
     <param name="url">git://github.com/jp9000/obs-studio.git</param>
8
     <param name="scm">git</param>
9
     <param name="changesgenerate">enable</param>
10
_servicedata Changed
9
 
1
@@ -1,6 +1,6 @@
2
 <servicedata>
3
   <service name="tar_scm">
4
     <param name="url">git://github.com/jp9000/obs-studio.git</param>
5
-    <param name="changesrevision">93e084088f3c1f3979d78eea3c5d9220b1cea3f7</param>
6
+    <param name="changesrevision">5f5582b87efe396812131b7a2211f1e0e5e85768</param>
7
   </service>
8
 </servicedata>
9
obs-studio-0.17.0.tar.xz/CI/before-deploy-osx.sh -> obs-studio-17.0.1.tar.xz/CI/before-deploy-osx.sh Changed
15
 
1
@@ -1,8 +1,10 @@
2
 export GIT_HASH=$(git rev-parse --short HEAD)
3
 export FILE_DATE=$(date +%Y-%m-%d.%H:%M:%S)
4
-export FILENAME=$FILE_DATE-$GIT_HASH-osx.zip
5
+export FILENAME=$FILE_DATE-$GIT_HASH-osx.pkg
6
 mkdir nightly
7
 cd ./build
8
 sudo python ../CI/install/osx/build_app.py
9
-zip -r -X $FILENAME OBS.app
10
-mv ./$FILENAME ../nightly
11
+packagesbuild ../CI/install/osx/CMakeLists.pkgproj
12
+
13
+sudo cp OBS.pkg ./$FILENAME
14
+sudo mv ./$FILENAME ../nightly
15
obs-studio-0.17.0.tar.xz/CI/before-script-osx.sh -> obs-studio-17.0.1.tar.xz/CI/before-script-osx.sh Changed
8
 
1
@@ -1,3 +1,3 @@
2
 mkdir build
3
 cd build
4
-cmake -DBUILD_BROWSER=ON -DCEF_ROOT_DIR=$PWD/../../cef_binary_3.2704.1434.gec3e9ed_macosx64 ..
5
\ No newline at end of file
6
+cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 -DDepsPath=/tmp/obsdeps -DBUILD_BROWSER=ON -DCEF_ROOT_DIR=$PWD/../../cef_binary_3.2883.1540.gedbfb20_macosx64 ..
7
\ No newline at end of file
8
obs-studio-0.17.0.tar.xz/CI/install-dependencies-osx.sh -> obs-studio-17.0.1.tar.xz/CI/install-dependencies-osx.sh Changed
30
 
1
@@ -1,17 +1,22 @@
2
+curl -L -O https://s3-us-west-2.amazonaws.com/obs-nightly/Packages.pkg
3
+sudo installer -pkg ./Packages.pkg -target /
4
+
5
 brew update
6
 
7
 #Base OBS Deps
8
-brew install ffmpeg x264 qt5
9
+brew install qt5
10
+
11
+curl -L -O https://s3-us-west-2.amazonaws.com/obs-nightly/osx-deps.tar.gz
12
+tar -xf ./osx-deps.tar.gz -C /tmp
13
 
14
 # CEF Stuff
15
 cd ../
16
-curl -kLO http://opensource.spotify.com/cefbuilds/cef_binary_3.2704.1434.gec3e9ed_macosx64.tar.bz2
17
-tar -xf ./cef_binary_3.2704.1434.gec3e9ed_macosx64.tar.bz2
18
-cd ./cef_binary_3.2704.1434.gec3e9ed_macosx64
19
+curl -kLO http://opensource.spotify.com/cefbuilds/cef_binary_3.2883.1540.gedbfb20_macosx64.tar.bz2
20
+tar -xf ./cef_binary_3.2883.1540.gedbfb20_macosx64.tar.bz2
21
+cd ./cef_binary_3.2883.1540.gedbfb20_macosx64
22
 mkdir build
23
 cd ./build
24
-cmake -DCMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" -DCMAKE_EXE_LINKER_FLAGS="-std=c++11 -stdlib=libc++" ..
25
+cmake -DCMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" -DCMAKE_EXE_LINKER_FLAGS="-std=c++11 -stdlib=libc++" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 ..
26
 make -j4
27
 mkdir libcef_dll
28
-mv ./libcef_dll_wrapper/libcef_dll_wrapper.a ./libcef_dll/libcef_dll_wrapper.a
29
 cd ../../
30
obs-studio-17.0.1.tar.xz/CI/install/osx/CMakeLists.pkgproj Added
1023
 
1
@@ -0,0 +1,1021 @@
2
+<?xml version="1.0" encoding="UTF-8"?>
3
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
4
+<plist version="1.0">
5
+<dict>
6
+   <key>PACKAGES</key>
7
+   <array>
8
+       <dict>
9
+           <key>PACKAGE_FILES</key>
10
+           <dict>
11
+               <key>DEFAULT_INSTALL_LOCATION</key>
12
+               <string>/</string>
13
+               <key>HIERARCHY</key>
14
+               <dict>
15
+                   <key>CHILDREN</key>
16
+                   <array>
17
+                       <dict>
18
+                           <key>CHILDREN</key>
19
+                           <array>
20
+                               <dict>
21
+                                   <key>CHILDREN</key>
22
+                                   <array/>
23
+                                   <key>GID</key>
24
+                                   <integer>80</integer>
25
+                                   <key>PATH</key>
26
+                                   <string>../../../build/OBS.app</string>
27
+                                   <key>PATH_TYPE</key>
28
+                                   <integer>3</integer>
29
+                                   <key>PERMISSIONS</key>
30
+                                   <integer>493</integer>
31
+                                   <key>TYPE</key>
32
+                                   <integer>3</integer>
33
+                                   <key>UID</key>
34
+                                   <integer>0</integer>
35
+                               </dict>
36
+                               <dict>
37
+                                   <key>CHILDREN</key>
38
+                                   <array/>
39
+                                   <key>GID</key>
40
+                                   <integer>80</integer>
41
+                                   <key>PATH</key>
42
+                                   <string>Utilities</string>
43
+                                   <key>PATH_TYPE</key>
44
+                                   <integer>0</integer>
45
+                                   <key>PERMISSIONS</key>
46
+                                   <integer>493</integer>
47
+                                   <key>TYPE</key>
48
+                                   <integer>1</integer>
49
+                                   <key>UID</key>
50
+                                   <integer>0</integer>
51
+                               </dict>
52
+                           </array>
53
+                           <key>GID</key>
54
+                           <integer>80</integer>
55
+                           <key>PATH</key>
56
+                           <string>Applications</string>
57
+                           <key>PATH_TYPE</key>
58
+                           <integer>0</integer>
59
+                           <key>PERMISSIONS</key>
60
+                           <integer>509</integer>
61
+                           <key>TYPE</key>
62
+                           <integer>1</integer>
63
+                           <key>UID</key>
64
+                           <integer>0</integer>
65
+                       </dict>
66
+                       <dict>
67
+                           <key>CHILDREN</key>
68
+                           <array>
69
+                               <dict>
70
+                                   <key>CHILDREN</key>
71
+                                   <array>
72
+                                       <dict>
73
+                                           <key>CHILDREN</key>
74
+                                           <array>
75
+                                               <dict>
76
+                                                   <key>CHILDREN</key>
77
+                                                   <array>
78
+                                                       <dict>
79
+                                                           <key>CHILDREN</key>
80
+                                                           <array>
81
+                                                               <dict>
82
+                                                                   <key>CHILDREN</key>
83
+                                                                   <array>
84
+                                                                       <dict>
85
+                                                                           <key>CHILDREN</key>
86
+                                                                           <array/>
87
+                                                                           <key>GID</key>
88
+                                                                           <integer>80</integer>
89
+                                                                           <key>PATH</key>
90
+                                                                           <string>../../../build/plugins/obs-browser/CEF.app</string>
91
+                                                                           <key>PATH_TYPE</key>
92
+                                                                           <integer>3</integer>
93
+                                                                           <key>PERMISSIONS</key>
94
+                                                                           <integer>493</integer>
95
+                                                                           <key>TYPE</key>
96
+                                                                           <integer>3</integer>
97
+                                                                           <key>UID</key>
98
+                                                                           <integer>0</integer>
99
+                                                                       </dict>
100
+                                                                       <dict>
101
+                                                                           <key>CHILDREN</key>
102
+                                                                           <array/>
103
+                                                                           <key>GID</key>
104
+                                                                           <integer>80</integer>
105
+                                                                           <key>PATH</key>
106
+                                                                           <string>../../../build/plugins/obs-browser/obs-browser.so</string>
107
+                                                                           <key>PATH_TYPE</key>
108
+                                                                           <integer>3</integer>
109
+                                                                           <key>PERMISSIONS</key>
110
+                                                                           <integer>493</integer>
111
+                                                                           <key>TYPE</key>
112
+                                                                           <integer>3</integer>
113
+                                                                           <key>UID</key>
114
+                                                                           <integer>0</integer>
115
+                                                                       </dict>
116
+                                                                   </array>
117
+                                                                   <key>GID</key>
118
+                                                                   <integer>80</integer>
119
+                                                                   <key>PATH</key>
120
+                                                                   <string>bin</string>
121
+                                                                   <key>PATH_TYPE</key>
122
+                                                                   <integer>0</integer>
123
+                                                                   <key>PERMISSIONS</key>
124
+                                                                   <integer>493</integer>
125
+                                                                   <key>TYPE</key>
126
+                                                                   <integer>2</integer>
127
+                                                                   <key>UID</key>
128
+                                                                   <integer>0</integer>
129
+                                                               </dict>
130
+                                                           </array>
131
+                                                           <key>GID</key>
132
+                                                           <integer>80</integer>
133
+                                                           <key>PATH</key>
134
+                                                           <string>obs-browser</string>
135
+                                                           <key>PATH_TYPE</key>
136
+                                                           <integer>0</integer>
137
+                                                           <key>PERMISSIONS</key>
138
+                                                           <integer>493</integer>
139
+                                                           <key>TYPE</key>
140
+                                                           <integer>2</integer>
141
+                                                           <key>UID</key>
142
+                                                           <integer>0</integer>
143
+                                                       </dict>
144
+                                                   </array>
145
+                                                   <key>GID</key>
146
+                                                   <integer>80</integer>
147
+                                                   <key>PATH</key>
148
+                                                   <string>plugins</string>
149
+                                                   <key>PATH_TYPE</key>
150
+                                                   <integer>0</integer>
151
+                                                   <key>PERMISSIONS</key>
152
+                                                   <integer>493</integer>
153
+                                                   <key>TYPE</key>
154
+                                                   <integer>2</integer>
155
+                                                   <key>UID</key>
156
+                                                   <integer>0</integer>
157
+                                               </dict>
158
+                                           </array>
159
+                                           <key>GID</key>
160
+                                           <integer>80</integer>
161
+                                           <key>PATH</key>
162
+                                           <string>obs-studio</string>
163
+                                           <key>PATH_TYPE</key>
164
+                                           <integer>0</integer>
165
+                                           <key>PERMISSIONS</key>
166
+                                           <integer>493</integer>
167
+                                           <key>TYPE</key>
168
+                                           <integer>2</integer>
169
+                                           <key>UID</key>
170
+                                           <integer>0</integer>
171
+                                       </dict>
172
+                                   </array>
173
+                                   <key>GID</key>
174
+                                   <integer>80</integer>
175
+                                   <key>PATH</key>
176
+                                   <string>Application Support</string>
177
+                                   <key>PATH_TYPE</key>
178
+                                   <integer>0</integer>
179
+                                   <key>PERMISSIONS</key>
180
+                                   <integer>493</integer>
181
+                                   <key>TYPE</key>
182
+                                   <integer>1</integer>
183
+                                   <key>UID</key>
184
+                                   <integer>0</integer>
185
+                               </dict>
186
+                               <dict>
187
+                                   <key>CHILDREN</key>
188
+                                   <array/>
189
+                                   <key>GID</key>
190
+                                   <integer>0</integer>
191
+                                   <key>PATH</key>
192
+                                   <string>Documentation</string>
193
+                                   <key>PATH_TYPE</key>
194
+                                   <integer>0</integer>
195
+                                   <key>PERMISSIONS</key>
196
+                                   <integer>493</integer>
197
+                                   <key>TYPE</key>
198
+                                   <integer>1</integer>
199
+                                   <key>UID</key>
200
+                                   <integer>0</integer>
201
+                               </dict>
202
+                               <dict>
203
+                                   <key>CHILDREN</key>
204
+                                   <array/>
205
+                                   <key>GID</key>
206
+                                   <integer>0</integer>
207
+                                   <key>PATH</key>
208
+                                   <string>Filesystems</string>
209
+                                   <key>PATH_TYPE</key>
210
+                                   <integer>0</integer>
211
+                                   <key>PERMISSIONS</key>
212
+                                   <integer>493</integer>
213
+                                   <key>TYPE</key>
214
+                                   <integer>1</integer>
215
+                                   <key>UID</key>
216
+                                   <integer>0</integer>
217
+                               </dict>
218
+                               <dict>
219
+                                   <key>CHILDREN</key>
220
+                                   <array/>
221
+                                   <key>GID</key>
222
+                                   <integer>0</integer>
223
+                                   <key>PATH</key>
224
+                                   <string>Frameworks</string>
225
+                                   <key>PATH_TYPE</key>
226
+                                   <integer>0</integer>
227
+                                   <key>PERMISSIONS</key>
228
+                                   <integer>493</integer>
229
+                                   <key>TYPE</key>
230
+                                   <integer>1</integer>
231
+                                   <key>UID</key>
232
+                                   <integer>0</integer>
233
+                               </dict>
234
+                               <dict>
235
+                                   <key>CHILDREN</key>
236
+                                   <array/>
237
+                                   <key>GID</key>
238
+                                   <integer>0</integer>
239
+                                   <key>PATH</key>
240
+                                   <string>Input Methods</string>
241
+                                   <key>PATH_TYPE</key>
242
+                                   <integer>0</integer>
243
+                                   <key>PERMISSIONS</key>
244
+                                   <integer>493</integer>
245
+                                   <key>TYPE</key>
246
+                                   <integer>1</integer>
247
+                                   <key>UID</key>
248
+                                   <integer>0</integer>
249
+                               </dict>
250
+                               <dict>
251
+                                   <key>CHILDREN</key>
252
+                                   <array/>
253
+                                   <key>GID</key>
254
+                                   <integer>0</integer>
255
+                                   <key>PATH</key>
256
+                                   <string>Internet Plug-Ins</string>
257
+                                   <key>PATH_TYPE</key>
258
+                                   <integer>0</integer>
259
+                                   <key>PERMISSIONS</key>
260
+                                   <integer>493</integer>
261
+                                   <key>TYPE</key>
262
+                                   <integer>1</integer>
263
+                                   <key>UID</key>
264
+                                   <integer>0</integer>
265
+                               </dict>
266
+                               <dict>
267
+                                   <key>CHILDREN</key>
268
+                                   <array/>
269
+                                   <key>GID</key>
270
+                                   <integer>0</integer>
271
+                                   <key>PATH</key>
272
+                                   <string>LaunchAgents</string>
273
+                                   <key>PATH_TYPE</key>
274
+                                   <integer>0</integer>
275
+                                   <key>PERMISSIONS</key>
276
+                                   <integer>493</integer>
277
+                                   <key>TYPE</key>
278
+                                   <integer>1</integer>
279
+                                   <key>UID</key>
280
+                                   <integer>0</integer>
281
+                               </dict>
282
+                               <dict>
283
+                                   <key>CHILDREN</key>
284
+                                   <array/>
285
+                                   <key>GID</key>
286
+                                   <integer>0</integer>
287
+                                   <key>PATH</key>
288
+                                   <string>LaunchDaemons</string>
289
+                                   <key>PATH_TYPE</key>
290
+                                   <integer>0</integer>
291
+                                   <key>PERMISSIONS</key>
292
+                                   <integer>493</integer>
293
+                                   <key>TYPE</key>
294
+                                   <integer>1</integer>
295
+                                   <key>UID</key>
296
+                                   <integer>0</integer>
297
+                               </dict>
298
+                               <dict>
299
+                                   <key>CHILDREN</key>
300
+                                   <array/>
301
+                                   <key>GID</key>
302
+                                   <integer>0</integer>
303
+                                   <key>PATH</key>
304
+                                   <string>PreferencePanes</string>
305
+                                   <key>PATH_TYPE</key>
306
+                                   <integer>0</integer>
307
+                                   <key>PERMISSIONS</key>
308
+                                   <integer>493</integer>
309
+                                   <key>TYPE</key>
310
+                                   <integer>1</integer>
311
+                                   <key>UID</key>
312
+                                   <integer>0</integer>
313
+                               </dict>
314
+                               <dict>
315
+                                   <key>CHILDREN</key>
316
+                                   <array/>
317
+                                   <key>GID</key>
318
+                                   <integer>0</integer>
319
+                                   <key>PATH</key>
320
+                                   <string>Preferences</string>
321
+                                   <key>PATH_TYPE</key>
322
+                                   <integer>0</integer>
323
+                                   <key>PERMISSIONS</key>
324
+                                   <integer>493</integer>
325
+                                   <key>TYPE</key>
326
+                                   <integer>1</integer>
327
+                                   <key>UID</key>
328
+                                   <integer>0</integer>
329
+                               </dict>
330
+                               <dict>
331
+                                   <key>CHILDREN</key>
332
+                                   <array/>
333
+                                   <key>GID</key>
334
+                                   <integer>80</integer>
335
+                                   <key>PATH</key>
336
+                                   <string>Printers</string>
337
+                                   <key>PATH_TYPE</key>
338
+                                   <integer>0</integer>
339
+                                   <key>PERMISSIONS</key>
340
+                                   <integer>493</integer>
341
+                                   <key>TYPE</key>
342
+                                   <integer>1</integer>
343
+                                   <key>UID</key>
344
+                                   <integer>0</integer>
345
+                               </dict>
346
+                               <dict>
347
+                                   <key>CHILDREN</key>
348
+                                   <array/>
349
+                                   <key>GID</key>
350
+                                   <integer>0</integer>
351
+                                   <key>PATH</key>
352
+                                   <string>PrivilegedHelperTools</string>
353
+                                   <key>PATH_TYPE</key>
354
+                                   <integer>0</integer>
355
+                                   <key>PERMISSIONS</key>
356
+                                   <integer>493</integer>
357
+                                   <key>TYPE</key>
358
+                                   <integer>1</integer>
359
+                                   <key>UID</key>
360
+                                   <integer>0</integer>
361
+                               </dict>
362
+                               <dict>
363
+                                   <key>CHILDREN</key>
364
+                                   <array/>
365
+                                   <key>GID</key>
366
+                                   <integer>0</integer>
367
+                                   <key>PATH</key>
368
+                                   <string>QuickLook</string>
369
+                                   <key>PATH_TYPE</key>
370
+                                   <integer>0</integer>
371
+                                   <key>PERMISSIONS</key>
372
+                                   <integer>493</integer>
373
+                                   <key>TYPE</key>
374
+                                   <integer>1</integer>
375
+                                   <key>UID</key>
376
+                                   <integer>0</integer>
377
+                               </dict>
378
+                               <dict>
379
+                                   <key>CHILDREN</key>
380
+                                   <array/>
381
+                                   <key>GID</key>
382
+                                   <integer>0</integer>
383
+                                   <key>PATH</key>
384
+                                   <string>QuickTime</string>
385
+                                   <key>PATH_TYPE</key>
386
+                                   <integer>0</integer>
387
+                                   <key>PERMISSIONS</key>
388
+                                   <integer>493</integer>
389
+                                   <key>TYPE</key>
390
+                                   <integer>1</integer>
391
+                                   <key>UID</key>
392
+                                   <integer>0</integer>
393
+                               </dict>
394
+                               <dict>
395
+                                   <key>CHILDREN</key>
396
+                                   <array/>
397
+                                   <key>GID</key>
398
+                                   <integer>0</integer>
399
+                                   <key>PATH</key>
400
+                                   <string>Screen Savers</string>
401
+                                   <key>PATH_TYPE</key>
402
+                                   <integer>0</integer>
403
+                                   <key>PERMISSIONS</key>
404
+                                   <integer>493</integer>
405
+                                   <key>TYPE</key>
406
+                                   <integer>1</integer>
407
+                                   <key>UID</key>
408
+                                   <integer>0</integer>
409
+                               </dict>
410
+                               <dict>
411
+                                   <key>CHILDREN</key>
412
+                                   <array/>
413
+                                   <key>GID</key>
414
+                                   <integer>0</integer>
415
+                                   <key>PATH</key>
416
+                                   <string>Scripts</string>
417
+                                   <key>PATH_TYPE</key>
418
+                                   <integer>0</integer>
419
+                                   <key>PERMISSIONS</key>
420
+                                   <integer>493</integer>
421
+                                   <key>TYPE</key>
422
+                                   <integer>1</integer>
423
+                                   <key>UID</key>
424
+                                   <integer>0</integer>
425
+                               </dict>
426
+                               <dict>
427
+                                   <key>CHILDREN</key>
428
+                                   <array/>
429
+                                   <key>GID</key>
430
+                                   <integer>0</integer>
431
+                                   <key>PATH</key>
432
+                                   <string>Services</string>
433
+                                   <key>PATH_TYPE</key>
434
+                                   <integer>0</integer>
435
+                                   <key>PERMISSIONS</key>
436
+                                   <integer>493</integer>
437
+                                   <key>TYPE</key>
438
+                                   <integer>1</integer>
439
+                                   <key>UID</key>
440
+                                   <integer>0</integer>
441
+                               </dict>
442
+                               <dict>
443
+                                   <key>CHILDREN</key>
444
+                                   <array/>
445
+                                   <key>GID</key>
446
+                                   <integer>0</integer>
447
+                                   <key>PATH</key>
448
+                                   <string>Widgets</string>
449
+                                   <key>PATH_TYPE</key>
450
+                                   <integer>0</integer>
451
+                                   <key>PERMISSIONS</key>
452
+                                   <integer>493</integer>
453
+                                   <key>TYPE</key>
454
+                                   <integer>1</integer>
455
+                                   <key>UID</key>
456
+                                   <integer>0</integer>
457
+                               </dict>
458
+                           </array>
459
+                           <key>GID</key>
460
+                           <integer>0</integer>
461
+                           <key>PATH</key>
462
+                           <string>Library</string>
463
+                           <key>PATH_TYPE</key>
464
+                           <integer>0</integer>
465
+                           <key>PERMISSIONS</key>
466
+                           <integer>493</integer>
467
+                           <key>TYPE</key>
468
+                           <integer>1</integer>
469
+                           <key>UID</key>
470
+                           <integer>0</integer>
471
+                       </dict>
472
+                       <dict>
473
+                           <key>CHILDREN</key>
474
+                           <array>
475
+                               <dict>
476
+                                   <key>CHILDREN</key>
477
+                                   <array>
478
+                                       <dict>
479
+                                           <key>CHILDREN</key>
480
+                                           <array/>
481
+                                           <key>GID</key>
482
+                                           <integer>0</integer>
483
+                                           <key>PATH</key>
484
+                                           <string>Extensions</string>
485
+                                           <key>PATH_TYPE</key>
486
+                                           <integer>0</integer>
487
+                                           <key>PERMISSIONS</key>
488
+                                           <integer>493</integer>
489
+                                           <key>TYPE</key>
490
+                                           <integer>1</integer>
491
+                                           <key>UID</key>
492
+                                           <integer>0</integer>
493
+                                       </dict>
494
+                                   </array>
495
+                                   <key>GID</key>
496
+                                   <integer>0</integer>
497
+                                   <key>PATH</key>
498
+                                   <string>Library</string>
499
+                                   <key>PATH_TYPE</key>
500
+                                   <integer>0</integer>
501
+                                   <key>PERMISSIONS</key>
502
+                                   <integer>493</integer>
503
+                                   <key>TYPE</key>
504
+                                   <integer>1</integer>
505
+                                   <key>UID</key>
506
+                                   <integer>0</integer>
507
+                               </dict>
508
+                           </array>
509
+                           <key>GID</key>
510
+                           <integer>0</integer>
511
+                           <key>PATH</key>
512
+                           <string>System</string>
513
+                           <key>PATH_TYPE</key>
514
+                           <integer>0</integer>
515
+                           <key>PERMISSIONS</key>
516
+                           <integer>493</integer>
517
+                           <key>TYPE</key>
518
+                           <integer>1</integer>
519
+                           <key>UID</key>
520
+                           <integer>0</integer>
521
+                       </dict>
522
+                       <dict>
523
+                           <key>CHILDREN</key>
524
+                           <array>
525
+                               <dict>
526
+                                   <key>CHILDREN</key>
527
+                                   <array/>
528
+                                   <key>GID</key>
529
+                                   <integer>0</integer>
530
+                                   <key>PATH</key>
531
+                                   <string>Shared</string>
532
+                                   <key>PATH_TYPE</key>
533
+                                   <integer>0</integer>
534
+                                   <key>PERMISSIONS</key>
535
+                                   <integer>1023</integer>
536
+                                   <key>TYPE</key>
537
+                                   <integer>1</integer>
538
+                                   <key>UID</key>
539
+                                   <integer>0</integer>
540
+                               </dict>
541
+                           </array>
542
+                           <key>GID</key>
543
+                           <integer>80</integer>
544
+                           <key>PATH</key>
545
+                           <string>Users</string>
546
+                           <key>PATH_TYPE</key>
547
+                           <integer>0</integer>
548
+                           <key>PERMISSIONS</key>
549
+                           <integer>493</integer>
550
+                           <key>TYPE</key>
551
+                           <integer>1</integer>
552
+                           <key>UID</key>
553
+                           <integer>0</integer>
554
+                       </dict>
555
+                   </array>
556
+                   <key>GID</key>
557
+                   <integer>0</integer>
558
+                   <key>PATH</key>
559
+                   <string>/</string>
560
+                   <key>PATH_TYPE</key>
561
+                   <integer>0</integer>
562
+                   <key>PERMISSIONS</key>
563
+                   <integer>493</integer>
564
+                   <key>TYPE</key>
565
+                   <integer>1</integer>
566
+                   <key>UID</key>
567
+                   <integer>0</integer>
568
+               </dict>
569
+               <key>PAYLOAD_TYPE</key>
570
+               <integer>0</integer>
571
+               <key>VERSION</key>
572
+               <integer>2</integer>
573
+           </dict>
574
+           <key>PACKAGE_SCRIPTS</key>
575
+           <dict>
576
+               <key>POSTINSTALL_PATH</key>
577
+               <dict/>
578
+               <key>PREINSTALL_PATH</key>
579
+               <dict/>
580
+               <key>RESOURCES</key>
581
+               <array/>
582
+           </dict>
583
+           <key>PACKAGE_SETTINGS</key>
584
+           <dict>
585
+               <key>AUTHENTICATION</key>
586
+               <integer>1</integer>
587
+               <key>CONCLUSION_ACTION</key>
588
+               <integer>0</integer>
589
+               <key>IDENTIFIER</key>
590
+               <string>org.obsproject.pkg.obs-studio</string>
591
+               <key>NAME</key>
592
+               <string>OBS</string>
593
+               <key>OVERWRITE_PERMISSIONS</key>
594
+               <false/>
595
+               <key>VERSION</key>
596
+               <string>1.0</string>
597
+           </dict>
598
+           <key>UUID</key>
599
+           <string>19CCE3F2-8911-4364-B673-8B5BC3ABD4DA</string>
600
+       </dict>
601
+       <dict>
602
+           <key>PACKAGE_SETTINGS</key>
603
+           <dict>
604
+               <key>LOCATION</key>
605
+               <integer>0</integer>
606
+               <key>NAME</key>
607
+               <string>SyphonInject</string>
608
+           </dict>
609
+           <key>PATH</key>
610
+           <dict>
611
+               <key>PATH</key>
612
+               <string>SyphonInject.pkg</string>
613
+               <key>PATH_TYPE</key>
614
+               <integer>1</integer>
615
+           </dict>
616
+           <key>TYPE</key>
617
+           <integer>1</integer>
618
+           <key>UUID</key>
619
+           <string>0CC9C67E-4D14-4794-9930-019925513B1C</string>
620
+       </dict>
621
+   </array>
622
+   <key>PROJECT</key>
623
+   <dict>
624
+       <key>PROJECT_COMMENTS</key>
625
+       <dict>
626
+           <key>NOTES</key>
627
+           <data>
628
+           PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1M
629
+           IDQuMDEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQv
630
+           c3RyaWN0LmR0ZCI+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1l
631
+           cXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7
632
+           IGNoYXJzZXQ9VVRGLTgiPgo8bWV0YSBodHRwLWVxdWl2PSJDb250
633
+           ZW50LVN0eWxlLVR5cGUiIGNvbnRlbnQ9InRleHQvY3NzIj4KPHRp
634
+           dGxlPjwvdGl0bGU+CjxtZXRhIG5hbWU9IkdlbmVyYXRvciIgY29u
635
+           dGVudD0iQ29jb2EgSFRNTCBXcml0ZXIiPgo8bWV0YSBuYW1lPSJD
636
+           b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjE1MDQuNzYiPgo8c3R5bGUg
637
+           dHlwZT0idGV4dC9jc3MiPgo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5
638
+           Pgo8L2JvZHk+CjwvaHRtbD4K
639
+           </data>
640
+       </dict>
641
+       <key>PROJECT_PRESENTATION</key>
642
+       <dict>
643
+           <key>BACKGROUND</key>
644
+           <dict>
645
+               <key>ALIGNMENT</key>
646
+               <integer>4</integer>
647
+               <key>BACKGROUND_PATH</key>
648
+               <dict>
649
+                   <key>PATH</key>
650
+                   <string>obs.png</string>
651
+                   <key>PATH_TYPE</key>
652
+                   <integer>1</integer>
653
+               </dict>
654
+               <key>CUSTOM</key>
655
+               <integer>1</integer>
656
+               <key>SCALING</key>
657
+               <integer>0</integer>
658
+           </dict>
659
+           <key>INSTALLATION TYPE</key>
660
+           <dict>
661
+               <key>HIERARCHIES</key>
662
+               <dict>
663
+                   <key>INSTALLER</key>
664
+                   <dict>
665
+                       <key>LIST</key>
666
+                       <array>
667
+                           <dict>
668
+                               <key>DESCRIPTION</key>
669
+                               <array/>
670
+                               <key>OPTIONS</key>
671
+                               <dict>
672
+                                   <key>HIDDEN</key>
673
+                                   <false/>
674
+                                   <key>STATE</key>
675
+                                   <integer>0</integer>
676
+                               </dict>
677
+                               <key>PACKAGE_UUID</key>
678
+                               <string>19CCE3F2-8911-4364-B673-8B5BC3ABD4DA</string>
679
+                               <key>REQUIREMENTS</key>
680
+                               <array/>
681
+                               <key>TITLE</key>
682
+                               <array/>
683
+                               <key>TOOLTIP</key>
684
+                               <array/>
685
+                               <key>TYPE</key>
686
+                               <integer>0</integer>
687
+                               <key>UUID</key>
688
+                               <string>7C540711-59F4-479C-9CFD-8C4D6594992E</string>
689
+                           </dict>
690
+                           <dict>
691
+                               <key>DESCRIPTION</key>
692
+                               <array/>
693
+                               <key>OPTIONS</key>
694
+                               <dict>
695
+                                   <key>HIDDEN</key>
696
+                                   <false/>
697
+                                   <key>STATE</key>
698
+                                   <integer>1</integer>
699
+                               </dict>
700
+                               <key>PACKAGE_UUID</key>
701
+                               <string>0CC9C67E-4D14-4794-9930-019925513B1C</string>
702
+                               <key>REQUIREMENTS</key>
703
+                               <array/>
704
+                               <key>TITLE</key>
705
+                               <array/>
706
+                               <key>TOOLTIP</key>
707
+                               <array/>
708
+                               <key>TYPE</key>
709
+                               <integer>0</integer>
710
+                               <key>UUID</key>
711
+                               <string>BBDE08F6-D7EE-47CB-881F-7F208B3A604B</string>
712
+                           </dict>
713
+                       </array>
714
+                       <key>REMOVED</key>
715
+                       <dict/>
716
+                   </dict>
717
+               </dict>
718
+               <key>INSTALLATION TYPE</key>
719
+               <integer>0</integer>
720
+               <key>MODE</key>
721
+               <integer>0</integer>
722
+           </dict>
723
+           <key>INSTALLATION_STEPS</key>
724
+           <array>
725
+               <dict>
726
+                   <key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
727
+                   <string>ICPresentationViewIntroductionController</string>
728
+                   <key>INSTALLER_PLUGIN</key>
729
+                   <string>Introduction</string>
730
+                   <key>LIST_TITLE_KEY</key>
731
+                   <string>InstallerSectionTitle</string>
732
+               </dict>
733
+               <dict>
734
+                   <key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
735
+                   <string>ICPresentationViewReadMeController</string>
736
+                   <key>INSTALLER_PLUGIN</key>
737
+                   <string>ReadMe</string>
738
+                   <key>LIST_TITLE_KEY</key>
739
+                   <string>InstallerSectionTitle</string>
740
+               </dict>
741
+               <dict>
742
+                   <key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
743
+                   <string>ICPresentationViewLicenseController</string>
744
+                   <key>INSTALLER_PLUGIN</key>
745
+                   <string>License</string>
746
+                   <key>LIST_TITLE_KEY</key>
747
+                   <string>InstallerSectionTitle</string>
748
+               </dict>
749
+               <dict>
750
+                   <key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
751
+                   <string>ICPresentationViewDestinationSelectController</string>
752
+                   <key>INSTALLER_PLUGIN</key>
753
+                   <string>TargetSelect</string>
754
+                   <key>LIST_TITLE_KEY</key>
755
+                   <string>InstallerSectionTitle</string>
756
+               </dict>
757
+               <dict>
758
+                   <key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
759
+                   <string>ICPresentationViewInstallationTypeController</string>
760
+                   <key>INSTALLER_PLUGIN</key>
761
+                   <string>PackageSelection</string>
762
+                   <key>LIST_TITLE_KEY</key>
763
+                   <string>InstallerSectionTitle</string>
764
+               </dict>
765
+               <dict>
766
+                   <key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
767
+                   <string>ICPresentationViewInstallationController</string>
768
+                   <key>INSTALLER_PLUGIN</key>
769
+                   <string>Install</string>
770
+                   <key>LIST_TITLE_KEY</key>
771
+                   <string>InstallerSectionTitle</string>
772
+               </dict>
773
+               <dict>
774
+                   <key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
775
+                   <string>ICPresentationViewSummaryController</string>
776
+                   <key>INSTALLER_PLUGIN</key>
777
+                   <string>Summary</string>
778
+                   <key>LIST_TITLE_KEY</key>
779
+                   <string>InstallerSectionTitle</string>
780
+               </dict>
781
+           </array>
782
+           <key>INTRODUCTION</key>
783
+           <dict>
784
+               <key>LOCALIZATIONS</key>
785
+               <array/>
786
+           </dict>
787
+           <key>LICENSE</key>
788
+           <dict>
789
+               <key>KEYWORDS</key>
790
+               <dict/>
791
+               <key>LOCALIZATIONS</key>
792
+               <array/>
793
+               <key>MODE</key>
794
+               <integer>0</integer>
795
+           </dict>
796
+           <key>README</key>
797
+           <dict>
798
+               <key>LOCALIZATIONS</key>
799
+               <array/>
800
+           </dict>
801
+           <key>SUMMARY</key>
802
+           <dict>
803
+               <key>LOCALIZATIONS</key>
804
+               <array/>
805
+           </dict>
806
+           <key>TITLE</key>
807
+           <dict>
808
+               <key>LOCALIZATIONS</key>
809
+               <array>
810
+                   <dict>
811
+                       <key>LANGUAGE</key>
812
+                       <string>English</string>
813
+                       <key>VALUE</key>
814
+                       <string>OBS</string>
815
+                   </dict>
816
+               </array>
817
+           </dict>
818
+       </dict>
819
+       <key>PROJECT_REQUIREMENTS</key>
820
+       <dict>
821
+           <key>LIST</key>
822
+           <array/>
823
+           <key>POSTINSTALL_PATH</key>
824
+           <dict/>
825
+           <key>PREINSTALL_PATH</key>
826
+           <dict/>
827
+           <key>RESOURCES</key>
828
+           <array/>
829
+           <key>ROOT_VOLUME_ONLY</key>
830
+           <false/>
831
+       </dict>
832
+       <key>PROJECT_SETTINGS</key>
833
+       <dict>
834
+           <key>ADVANCED_OPTIONS</key>
835
+           <dict/>
836
+           <key>BUILD_FORMAT</key>
837
+           <integer>0</integer>
838
+           <key>BUILD_PATH</key>
839
+           <dict>
840
+               <key>PATH</key>
841
+               <string>../../../build</string>
842
+               <key>PATH_TYPE</key>
843
+               <integer>3</integer>
844
+           </dict>
845
+           <key>EXCLUDED_FILES</key>
846
+           <array>
847
+               <dict>
848
+                   <key>PATTERNS_ARRAY</key>
849
+                   <array>
850
+                       <dict>
851
+                           <key>REGULAR_EXPRESSION</key>
852
+                           <false/>
853
+                           <key>STRING</key>
854
+                           <string>.DS_Store</string>
855
+                           <key>TYPE</key>
856
+                           <integer>0</integer>
857
+                       </dict>
858
+                   </array>
859
+                   <key>PROTECTED</key>
860
+                   <true/>
861
+                   <key>PROXY_NAME</key>
862
+                   <string>Remove .DS_Store files</string>
863
+                   <key>PROXY_TOOLTIP</key>
864
+                   <string>Remove ".DS_Store" files created by the Finder.</string>
865
+                   <key>STATE</key>
866
+                   <true/>
867
+               </dict>
868
+               <dict>
869
+                   <key>PATTERNS_ARRAY</key>
870
+                   <array>
871
+                       <dict>
872
+                           <key>REGULAR_EXPRESSION</key>
873
+                           <false/>
874
+                           <key>STRING</key>
875
+                           <string>.pbdevelopment</string>
876
+                           <key>TYPE</key>
877
+                           <integer>0</integer>
878
+                       </dict>
879
+                   </array>
880
+                   <key>PROTECTED</key>
881
+                   <true/>
882
+                   <key>PROXY_NAME</key>
883
+                   <string>Remove .pbdevelopment files</string>
884
+                   <key>PROXY_TOOLTIP</key>
885
+                   <string>Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.</string>
886
+                   <key>STATE</key>
887
+                   <true/>
888
+               </dict>
889
+               <dict>
890
+                   <key>PATTERNS_ARRAY</key>
891
+                   <array>
892
+                       <dict>
893
+                           <key>REGULAR_EXPRESSION</key>
894
+                           <false/>
895
+                           <key>STRING</key>
896
+                           <string>CVS</string>
897
+                           <key>TYPE</key>
898
+                           <integer>1</integer>
899
+                       </dict>
900
+                       <dict>
901
+                           <key>REGULAR_EXPRESSION</key>
902
+                           <false/>
903
+                           <key>STRING</key>
904
+                           <string>.cvsignore</string>
905
+                           <key>TYPE</key>
906
+                           <integer>0</integer>
907
+                       </dict>
908
+                       <dict>
909
+                           <key>REGULAR_EXPRESSION</key>
910
+                           <false/>
911
+                           <key>STRING</key>
912
+                           <string>.cvspass</string>
913
+                           <key>TYPE</key>
914
+                           <integer>0</integer>
915
+                       </dict>
916
+                       <dict>
917
+                           <key>REGULAR_EXPRESSION</key>
918
+                           <false/>
919
+                           <key>STRING</key>
920
+                           <string>.svn</string>
921
+                           <key>TYPE</key>
922
+                           <integer>1</integer>
923
+                       </dict>
924
+                       <dict>
925
+                           <key>REGULAR_EXPRESSION</key>
926
+                           <false/>
927
+                           <key>STRING</key>
928
+                           <string>.git</string>
929
+                           <key>TYPE</key>
930
+                           <integer>1</integer>
931
+                       </dict>
932
+                       <dict>
933
+                           <key>REGULAR_EXPRESSION</key>
934
+                           <false/>
935
+                           <key>STRING</key>
936
+                           <string>.gitignore</string>
937
+                           <key>TYPE</key>
938
+                           <integer>0</integer>
939
+                       </dict>
940
+                   </array>
941
+                   <key>PROTECTED</key>
942
+                   <true/>
943
+                   <key>PROXY_NAME</key>
944
+                   <string>Remove SCM metadata</string>
945
+                   <key>PROXY_TOOLTIP</key>
946
+                   <string>Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.</string>
947
+                   <key>STATE</key>
948
+                   <true/>
949
+               </dict>
950
+               <dict>
951
+                   <key>PATTERNS_ARRAY</key>
952
+                   <array>
953
+                       <dict>
954
+                           <key>REGULAR_EXPRESSION</key>
955
+                           <false/>
956
+                           <key>STRING</key>
957
+                           <string>classes.nib</string>
958
+                           <key>TYPE</key>
959
+                           <integer>0</integer>
960
+                       </dict>
961
+                       <dict>
962
+                           <key>REGULAR_EXPRESSION</key>
963
+                           <false/>
964
+                           <key>STRING</key>
965
+                           <string>designable.db</string>
966
+                           <key>TYPE</key>
967
+                           <integer>0</integer>
968
+                       </dict>
969
+                       <dict>
970
+                           <key>REGULAR_EXPRESSION</key>
971
+                           <false/>
972
+                           <key>STRING</key>
973
+                           <string>info.nib</string>
974
+                           <key>TYPE</key>
975
+                           <integer>0</integer>
976
+                       </dict>
977
+                   </array>
978
+                   <key>PROTECTED</key>
979
+                   <true/>
980
+                   <key>PROXY_NAME</key>
981
+                   <string>Optimize nib files</string>
982
+                   <key>PROXY_TOOLTIP</key>
983
+                   <string>Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.</string>
984
+                   <key>STATE</key>
985
+                   <true/>
986
+               </dict>
987
+               <dict>
988
+                   <key>PATTERNS_ARRAY</key>
989
+                   <array>
990
+                       <dict>
991
+                           <key>REGULAR_EXPRESSION</key>
992
+                           <false/>
993
+                           <key>STRING</key>
994
+                           <string>Resources Disabled</string>
995
+                           <key>TYPE</key>
996
+                           <integer>1</integer>
997
+                       </dict>
998
+                   </array>
999
+                   <key>PROTECTED</key>
1000
+                   <true/>
1001
+                   <key>PROXY_NAME</key>
1002
+                   <string>Remove Resources Disabled folders</string>
1003
+                   <key>PROXY_TOOLTIP</key>
1004
+                   <string>Remove "Resources Disabled" folders.</string>
1005
+                   <key>STATE</key>
1006
+                   <true/>
1007
+               </dict>
1008
+               <dict>
1009
+                   <key>SEPARATOR</key>
1010
+                   <true/>
1011
+               </dict>
1012
+           </array>
1013
+           <key>NAME</key>
1014
+           <string>OBS</string>
1015
+       </dict>
1016
+   </dict>
1017
+   <key>TYPE</key>
1018
+   <integer>0</integer>
1019
+   <key>VERSION</key>
1020
+   <integer>2</integer>
1021
+</dict>
1022
+</plist>
1023
obs-studio-17.0.1.tar.xz/CI/install/osx/OBSPublicDSAKey.pem Added
38
 
1
@@ -0,0 +1,36 @@
2
+-----BEGIN PUBLIC KEY-----
3
+MIIGSDCCBDoGByqGSM44BAEwggQtAoICAQDDTtoCl3zVYY4jq2ZvJhY+jZB23BdR
4
+k+oTQH0lIUuIBjJR+S8NZqylr4SIGF2S76sCDdpK5P7Waj1y5WyBIJQDCPA7UI1T
5
+P8UeZgxLazl+oVPnDhUeiEWCNkZIcn746/pPgdoG5KNjb6CUNQ8X+zkUzq6LJ7w9
6
+Sn02g1FPf0HUlR0D9bx8KweetAZrBGYNP2Mv0RvUSE3TS+t1zJadOp7GsMcoRBxD
7
+XnJXirBiTjGu3pUZ5bJSLEw+Jm46DdEj0f+SSMpPjgRAG3Pn8ac7U+CVonGHEIRB
8
+4+yjHTqF9aPtsABIbAeSh63U54yYcmYuF/ioxTNjXXsNGNm5ZAeGq1/o0iT2eesu
9
+nC6yUYggWSBVZEdTD4uI9iYsYnpjbp+fAUoD53MxTRgKqdOESdtZTJ0HSUqTjngH
10
+kwzpvxN7WmCpxISzAjs5bknu90DcdP2R4KrJfiJJzAMFp0hmwuy4OaUX0+BWZzvW
11
+KxCbHsvJL2asHkX4kQpoGVnYmEglH0vOLuK3iJi96jDcGBDGGPO0OXgu6P00iALT
12
+JF1KylJNnyH0K1a7EbS1QJlF50+zW+okc5Da1iy4vktTP7gPxBHZWeFHPMRZOp1H
13
+CZeP6Lipf9NpE5dqzMuHLFmxWeKn/7CQ2T9LyeTIajbeGqRsoSII3qEgQd/nDM3k
14
+NYt6e7dKx6rk6QIhAJ8/wlS8dyJEnvMwVRqn5ER05q7NuHocmGGiX2V/ONLnAoIC
15
+AQCTFu8RESwHSQ4uR3O0CjlvQKwqEM3Vlv+nyEqYvfqJNAfxrncpV0TF05GvUV7M
16
+e31solt3eK31qjK1H3AMaD8ToCinSYMLaoyMt0AfGljGK5cNZKXn/xFVM4mq71id
17
+RzrIfmL2327+kH7wC/8sk7R3FB/mxPV1fRhKuBqG+Y6x9NX7vz57JnIio20OQKCE
18
+Sn7a18QWHgmt+e+n9R6x7JiVOj+ZTwuPPXpomNB6nPVnQftf3lwB7ug1wJyBxAqy
19
+NkIhzkAk4RDn4NzhP70ULD80GdS36swCIOg08uTSsYA6FMgrD6JLpmKC4Uha8vPM
20
+421qxX8Si/Dk3r4one6NUr2WD0sy754MKOCZ5aD8XUB2ylLzfvdSEaGo+G/IyPtC
21
+o71PMnIStEPXH6GkvzxJv17zvhqQcyKBciqxR7GCQhbwMimp96EPIA3/2UDXQ9UE
22
+O+/JulJKVEuu4HhWLW8+s+qKhyTyP1dRd0qzLoLj81JA3FcotB1Lncas8mtv+eET
23
+Z1tKuDy8f4esOh0fuGNrDiMnm3y+cnsa41k4XLDLPrqGbJHxiRTlGwCMLxLEMcFa
24
+0gjYU3UFFiEvNG0vFWr4h57taLBoyKoyBON+Cmn5hsrKs1J1kTBTc1EvDF5mXjoX
25
+RhlrPxd/6b5aa12d3xIYofcp70RyPBM1AZ7jfWeSgKhN6AOCAgYAAoICAQClbOeZ
26
+cnCCsOaZyXp7aiZmDmJ4dtvCRXc+uD+VzRHlg/8X3BYQ01KUMc5/m+fFT7x8w12w
27
+FEN/txOxTB+NzQBlnRFHWjBOioxHWqAnYLuADP4nZM+1bwaMUBCRUX0MHZbaMMSR
28
+/dBa45Y9quc4JTV8rpfIzXdw1NZjDmnKYwKQxQ6eD/WymJFNpWKkaniMda0HQVCU
29
+eBEEpLjW4UE1YUFQgKuIKUdZ1eBxeXHgX6uDpU53reK8gC5ry8xZXryJlcqhKyQ8
30
+TrDarZgmxhzAvAwPbtCutiOpPaVpCQCdgi4PgA3sAgmdGENXDqTxcSCbCcmCYMzl
31
+pJLh+giO74OwZMqWvHwHPY5wgZbx9Tnw4JS+gsjl3K3XUeY1+J6cgrFCK/9iaRUx
32
+7lBroEgQoi+O+yM9ikPeGZYKwgobWslmNuMdYvbZl+hQF+eo7dgnABl+WHLkHogv
33
+O0wfbENlYECAHXJ/ncyRWoiyd3d/HrZBwMfMFv0hv9JdQ1EjVePXGh9+cDxO0W+Y
34
+ZJhXsXEmQ82+Pg9cCVywLKdbNWi4qPgwYEKKagq4ack6JHCcwbLMmNTz/PaDZpfP
35
+wCCxYzVxKksGnV2tb2quAW1/GB+H9FcPSHvE1MMsPhRwAGAm4+aKuL1IvrvLh8fj
36
+0tZk6dhMjtrBOkZMfnBbSKDKQlcHvXM25yIjgA==
37
+-----END PUBLIC KEY-----
38
obs-studio-17.0.1.tar.xz/CI/install/osx/SyphonInject.pkg Added
obs-studio-17.0.1.tar.xz/CI/install/osx/obs.png Added
705
 
1
@@ -0,0 +1,703 @@
2
+
3
+
4
+
5
+
6
+<!DOCTYPE html>
7
+<html lang="en" class=" emoji-size-boost is-u2f-enabled">
8
+  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#">
9
+    <meta charset='utf-8'>
10
+    
11
+
12
+    <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-c9ae4d373fcb2c40952201451cd449e00d6dbcedc778b79c9dfb2d076d04993b.css" integrity="sha256-ya5NNz/LLECVIgFFHNRJ4A1tvO3HeLecnfstB20EmTs=" media="all" rel="stylesheet" />
13
+    <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-4d14493830801ffc6d6d6363f3fcef8a6e41fd9e74776dce15fa2c18b2a9bb72.css" integrity="sha256-TRRJODCAH/xtbWNj8/zvim5B/Z50d23OFfosGLKpu3I=" media="all" rel="stylesheet" />
14
+    
15
+    
16
+    
17
+    
18
+
19
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
20
+    <meta http-equiv="Content-Language" content="en">
21
+    <meta name="viewport" content="width=device-width">
22
+    
23
+    <title>obs-studio-utils/obs.png at master · kc5nra/obs-studio-utils</title>
24
+    <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
25
+    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
26
+    <link rel="apple-touch-icon" href="/apple-touch-icon.png">
27
+    <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
28
+    <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
29
+    <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
30
+    <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
31
+    <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
32
+    <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
33
+    <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
34
+    <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
35
+    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
36
+    <meta property="fb:app_id" content="1401488693436528">
37
+
38
+      <meta content="https://avatars0.githubusercontent.com/u/231018?v=3&amp;s=400" name="twitter:image:src" /><meta content="@github" name="twitter:site" /><meta content="summary" name="twitter:card" /><meta content="kc5nra/obs-studio-utils" name="twitter:title" /><meta content="Contribute to obs-studio-utils development by creating an account on GitHub." name="twitter:description" />
39
+      <meta content="https://avatars0.githubusercontent.com/u/231018?v=3&amp;s=400" property="og:image" /><meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="kc5nra/obs-studio-utils" property="og:title" /><meta content="https://github.com/kc5nra/obs-studio-utils" property="og:url" /><meta content="Contribute to obs-studio-utils development by creating an account on GitHub." property="og:description" />
40
+      <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
41
+    <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
42
+    <link rel="assets" href="https://assets-cdn.github.com/">
43
+    <link rel="web-socket" href="wss://live.github.com/_sockets/VjI6NTA0OTIxMTc6ZDJjMjcyYzA1MjZiMGM4MGI5MmU2NzBkMTMyMWNiYWZhMjZiZGQ0MGQxOGY1MWNkYmI1NzA0NjhlZTdjM2E2OA==--561fd74d4042c982502dd897714172236351f238">
44
+    <meta name="pjax-timeout" content="1000">
45
+    <link rel="sudo-modal" href="/sessions/sudo_modal">
46
+    <meta name="request-id" content="683BCFFA:2DABC:EE980D1:587831B3" data-pjax-transient>
47
+
48
+    <meta name="msapplication-TileImage" content="/windows-tile.png">
49
+    <meta name="msapplication-TileColor" content="#ffffff">
50
+    <meta name="selected-link" value="repo_source" data-pjax-transient>
51
+
52
+    <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
53
+<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
54
+    <meta name="google-analytics" content="UA-3769691-2">
55
+
56
+<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="683BCFFA:2DABC:EE980D1:587831B3" name="octolytics-dimension-request_id" /><meta content="207897" name="octolytics-actor-id" /><meta content="DDRBoxman" name="octolytics-actor-login" /><meta content="951d1462a992f6b4236b5008d6b11c4331eba4c658fe50ec7c9882e14af522bd" name="octolytics-actor-hash" />
57
+<meta content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-pjax-transient="true" name="analytics-location" />
58
+
59
+
60
+
61
+  <meta class="js-ga-set" name="dimension1" content="Logged In">
62
+
63
+
64
+
65
+        <meta name="hostname" content="github.com">
66
+    <meta name="user-login" content="DDRBoxman">
67
+
68
+        <meta name="expected-hostname" content="github.com">
69
+      <meta name="js-proxy-site-detection-payload" content="ZDQzNzZjM2MwNTlmYWFjNzhmNWJlMzY0MzNkMjdiOThhM2U2OTI0ZjlmMzFlYzJmODdjYjMxNDQ5OTBkNjc4NXx7InJlbW90ZV9hZGRyZXNzIjoiMTA0LjU5LjIwNy4yNTAiLCJyZXF1ZXN0X2lkIjoiNjgzQkNGRkE6MkRBQkM6RUU5ODBEMTo1ODc4MzFCMyIsInRpbWVzdGFtcCI6MTQ4NDI3MjA1NiwiaG9zdCI6ImdpdGh1Yi5jb20ifQ==">
70
+
71
+
72
+      <link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#000000">
73
+      <link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
74
+
75
+    <meta name="html-safe-nonce" content="0a420a0a7ff0cff8568da5f27c46880ec53370cf">
76
+
77
+    <meta http-equiv="x-pjax-version" content="f36bd54ef0fdb145d68369e21555ea6f">
78
+    
79
+
80
+      
81
+  <meta name="description" content="Contribute to obs-studio-utils development by creating an account on GitHub.">
82
+  <meta name="go-import" content="github.com/kc5nra/obs-studio-utils git https://github.com/kc5nra/obs-studio-utils.git">
83
+
84
+  <meta content="231018" name="octolytics-dimension-user_id" /><meta content="kc5nra" name="octolytics-dimension-user_login" /><meta content="24656398" name="octolytics-dimension-repository_id" /><meta content="kc5nra/obs-studio-utils" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="24656398" name="octolytics-dimension-repository_network_root_id" /><meta content="kc5nra/obs-studio-utils" name="octolytics-dimension-repository_network_root_nwo" />
85
+  <link href="https://github.com/kc5nra/obs-studio-utils/commits/master.atom" rel="alternate" title="Recent Commits to obs-studio-utils:master" type="application/atom+xml">
86
+
87
+
88
+      <link rel="canonical" href="https://github.com/kc5nra/obs-studio-utils/blob/master/install/osx/obs.png" data-pjax-transient>
89
+  </head>
90
+
91
+
92
+  <body class="logged-in  env-production macintosh vis-public page-blob">
93
+    <div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
94
+    <a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a>
95
+
96
+    
97
+    
98
+    
99
+
100
+
101
+
102
+        <div class="header header-logged-in true" role="banner">
103
+  <div class="container clearfix">
104
+
105
+    <a class="header-logo-invertocat" href="https://github.com/" data-hotkey="g d" aria-label="Homepage" data-ga-click="Header, go to dashboard, icon:logo">
106
+  <svg aria-hidden="true" class="octicon octicon-mark-github" height="28" version="1.1" viewBox="0 0 16 16" width="28"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
107
+</a>
108
+
109
+
110
+        <div class="header-search scoped-search site-scoped-search js-site-search" role="search">
111
+  <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/kc5nra/obs-studio-utils/search" class="js-site-search-form" data-scoped-search-url="/kc5nra/obs-studio-utils/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
112
+    <label class="form-control header-search-wrapper js-chromeless-input-container">
113
+      <div class="header-search-scope">This repository</div>
114
+      <input type="text"
115
+        class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
116
+        data-hotkey="s"
117
+        name="q"
118
+        placeholder="Search"
119
+        aria-label="Search this repository"
120
+        data-unscoped-placeholder="Search GitHub"
121
+        data-scoped-placeholder="Search"
122
+        autocapitalize="off">
123
+    </label>
124
+</form></div>
125
+
126
+
127
+      <ul class="header-nav float-left" role="navigation">
128
+        <li class="header-nav-item">
129
+          <a href="/pulls" aria-label="Pull requests you created" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:pulls context:user" data-hotkey="g p" data-selected-links="/pulls /pulls/assigned /pulls/mentioned /pulls">
130
+            Pull requests
131
+</a>        </li>
132
+        <li class="header-nav-item">
133
+          <a href="/issues" aria-label="Issues you created" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:issues context:user" data-hotkey="g i" data-selected-links="/issues /issues/assigned /issues/mentioned /issues">
134
+            Issues
135
+</a>        </li>
136
+          <li class="header-nav-item">
137
+            <a class="header-nav-link" href="https://gist.github.com/" data-ga-click="Header, go to gist, text:gist">Gist</a>
138
+          </li>
139
+      </ul>
140
+
141
+    
142
+<ul class="header-nav user-nav float-right" id="user-links">
143
+  <li class="header-nav-item">
144
+    
145
+    <a href="/notifications" aria-label="You have no unread notifications" class="header-nav-link notification-indicator tooltipped tooltipped-s js-socket-channel js-notification-indicator" data-channel="tenant:1:notification-changed:207897" data-ga-click="Header, go to notifications, icon:read" data-hotkey="g n">
146
+        <span class="mail-status "></span>
147
+        <svg aria-hidden="true" class="octicon octicon-bell" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 12v1H0v-1l.73-.58c.77-.77.81-2.55 1.19-4.42C2.69 3.23 6 2 6 2c0-.55.45-1 1-1s1 .45 1 1c0 0 3.39 1.23 4.16 5 .38 1.88.42 3.66 1.19 4.42l.66.58H14zm-7 4c1.11 0 2-.89 2-2H5c0 1.11.89 2 2 2z"/></svg>
148
+</a>
149
+  </li>
150
+
151
+  <li class="header-nav-item dropdown js-menu-container">
152
+    <a class="header-nav-link tooltipped tooltipped-s js-menu-target" href="/new"
153
+       aria-label="Create new…"
154
+       data-ga-click="Header, create new, icon:add">
155
+      <svg aria-hidden="true" class="octicon octicon-plus float-left" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 9H7v5H5V9H0V7h5V2h2v5h5z"/></svg>
156
+      <span class="dropdown-caret"></span>
157
+    </a>
158
+
159
+    <div class="dropdown-menu-content js-menu-content">
160
+      <ul class="dropdown-menu dropdown-menu-sw">
161
+        
162
+<a class="dropdown-item" href="/new" data-ga-click="Header, create new repository">
163
+  New repository
164
+</a>
165
+
166
+  <a class="dropdown-item" href="/new/import" data-ga-click="Header, import a repository">
167
+    Import repository
168
+  </a>
169
+
170
+<a class="dropdown-item" href="https://gist.github.com/" data-ga-click="Header, create new gist">
171
+  New gist
172
+</a>
173
+
174
+  <a class="dropdown-item" href="/organizations/new" data-ga-click="Header, create new organization">
175
+    New organization
176
+  </a>
177
+
178
+
179
+
180
+  <div class="dropdown-divider"></div>
181
+  <div class="dropdown-header">
182
+    <span title="kc5nra/obs-studio-utils">This repository</span>
183
+  </div>
184
+    <a class="dropdown-item" href="/kc5nra/obs-studio-utils/issues/new" data-ga-click="Header, create new issue">
185
+      New issue
186
+    </a>
187
+
188
+      </ul>
189
+    </div>
190
+  </li>
191
+
192
+  <li class="header-nav-item dropdown js-menu-container">
193
+    <a class="header-nav-link name tooltipped tooltipped-sw js-menu-target" href="/DDRBoxman"
194
+       aria-label="View profile and more"
195
+       data-ga-click="Header, show menu, icon:avatar">
196
+      <img alt="@DDRBoxman" class="avatar" height="20" src="https://avatars3.githubusercontent.com/u/207897?v=3&amp;s=40" width="20" />
197
+      <span class="dropdown-caret"></span>
198
+    </a>
199
+
200
+    <div class="dropdown-menu-content js-menu-content">
201
+      <div class="dropdown-menu dropdown-menu-sw">
202
+        <div class="dropdown-header header-nav-current-user css-truncate">
203
+          Signed in as <strong class="css-truncate-target">DDRBoxman</strong>
204
+        </div>
205
+
206
+        <div class="dropdown-divider"></div>
207
+
208
+        <a class="dropdown-item" href="/DDRBoxman" data-ga-click="Header, go to profile, text:your profile">
209
+          Your profile
210
+        </a>
211
+        <a class="dropdown-item" href="/DDRBoxman?tab=stars" data-ga-click="Header, go to starred repos, text:your stars">
212
+          Your stars
213
+        </a>
214
+        <a class="dropdown-item" href="/explore" data-ga-click="Header, go to explore, text:explore">
215
+          Explore
216
+        </a>
217
+          <a class="dropdown-item" href="/integrations" data-ga-click="Header, go to integrations, text:integrations">
218
+            Integrations
219
+          </a>
220
+        <a class="dropdown-item" href="https://help.github.com" data-ga-click="Header, go to help, text:help">
221
+          Help
222
+        </a>
223
+
224
+        <div class="dropdown-divider"></div>
225
+
226
+        <a class="dropdown-item" href="/settings/profile" data-ga-click="Header, go to settings, icon:settings">
227
+          Settings
228
+        </a>
229
+
230
+        <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/logout" class="logout-form" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="mbjQPqcKKO6Yuqt3Dvczikt53JctIh6E47+gkXyZ3vFinTikSLP4X/o4pVzB6UDZReamEALdVHKN3UNUxVdRFQ==" /></div>
231
+          <button type="submit" class="dropdown-item dropdown-signout" data-ga-click="Header, sign out, icon:logout">
232
+            Sign out
233
+          </button>
234
+</form>      </div>
235
+    </div>
236
+  </li>
237
+</ul>
238
+
239
+
240
+    
241
+  </div>
242
+</div>
243
+
244
+
245
+      
246
+
247
+
248
+    <div id="start-of-content" class="accessibility-aid"></div>
249
+
250
+      <div id="js-flash-container">
251
+</div>
252
+
253
+
254
+    <div role="main">
255
+        <div itemscope itemtype="http://schema.org/SoftwareSourceCode">
256
+    <div id="js-repo-pjax-container" data-pjax-container>
257
+      
258
+<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
259
+  <div class="container repohead-details-container">
260
+
261
+    
262
+
263
+<ul class="pagehead-actions">
264
+
265
+  <li>
266
+        <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/notifications/subscribe" class="js-social-container" data-autosubmit="true" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="7woW5zqjJpvg5IbCp+Gf47Op+jJvsrXFlv5u5Cwuwg3CsPTT6eYZ7inxEYqPhx9rxluEnL+P7mYdgOYTMzC6HQ==" /></div>      <input class="form-control" id="repository_id" name="repository_id" type="hidden" value="24656398" />
267
+
268
+        <div class="select-menu js-menu-container js-select-menu">
269
+          <a href="/kc5nra/obs-studio-utils/subscription"
270
+            class="btn btn-sm btn-with-count select-menu-button js-menu-target" role="button" tabindex="0" aria-haspopup="true"
271
+            data-ga-click="Repository, click Watch settings, action:blob#show">
272
+            <span class="js-select-button">
273
+              <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
274
+              Watch
275
+            </span>
276
+          </a>
277
+          <a class="social-count js-social-count"
278
+            href="/kc5nra/obs-studio-utils/watchers"
279
+            aria-label="6 users are watching this repository">
280
+            6
281
+          </a>
282
+
283
+        <div class="select-menu-modal-holder">
284
+          <div class="select-menu-modal subscription-menu-modal js-menu-content" aria-hidden="true">
285
+            <div class="select-menu-header js-navigation-enable" tabindex="-1">
286
+              <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
287
+              <span class="select-menu-title">Notifications</span>
288
+            </div>
289
+
290
+              <div class="select-menu-list js-navigation-container" role="menu">
291
+
292
+                <div class="select-menu-item js-navigation-item selected" role="menuitem" tabindex="0">
293
+                  <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
294
+                  <div class="select-menu-item-text">
295
+                    <input checked="checked" id="do_included" name="do" type="radio" value="included" />
296
+                    <span class="select-menu-item-heading">Not watching</span>
297
+                    <span class="description">Be notified when participating or @mentioned.</span>
298
+                    <span class="js-select-button-text hidden-select-button-text">
299
+                      <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
300
+                      Watch
301
+                    </span>
302
+                  </div>
303
+                </div>
304
+
305
+                <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
306
+                  <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
307
+                  <div class="select-menu-item-text">
308
+                    <input id="do_subscribed" name="do" type="radio" value="subscribed" />
309
+                    <span class="select-menu-item-heading">Watching</span>
310
+                    <span class="description">Be notified of all conversations.</span>
311
+                    <span class="js-select-button-text hidden-select-button-text">
312
+                      <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
313
+                      Unwatch
314
+                    </span>
315
+                  </div>
316
+                </div>
317
+
318
+                <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
319
+                  <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
320
+                  <div class="select-menu-item-text">
321
+                    <input id="do_ignore" name="do" type="radio" value="ignore" />
322
+                    <span class="select-menu-item-heading">Ignoring</span>
323
+                    <span class="description">Never be notified.</span>
324
+                    <span class="js-select-button-text hidden-select-button-text">
325
+                      <svg aria-hidden="true" class="octicon octicon-mute" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8 2.81v10.38c0 .67-.81 1-1.28.53L3 10H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.81 8 2.14 8 2.81zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06L11.44 8 9.47 9.97l1.06 1.06 1.97-1.97 1.97 1.97 1.06-1.06L13.56 8l1.97-1.97z"/></svg>
326
+                      Stop ignoring
327
+                    </span>
328
+                  </div>
329
+                </div>
330
+
331
+              </div>
332
+
333
+            </div>
334
+          </div>
335
+        </div>
336
+</form>
337
+  </li>
338
+
339
+  <li>
340
+      <div class="js-toggler-container js-social-container starring-container ">
341
+    <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/kc5nra/obs-studio-utils/unstar" class="starred" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="uNPwxvmyPhwAsjUibCbKxZPg+6FNyS0wqv8HPlluJPjUflJmxafLWYbN3BQrvfH8Lc0ZHtLc/rWvAedO7AIezw==" /></div>
342
+      <button
343
+        type="submit"
344
+        class="btn btn-sm btn-with-count js-toggler-target"
345
+        aria-label="Unstar this repository" title="Unstar kc5nra/obs-studio-utils"
346
+        data-ga-click="Repository, click unstar button, action:blob#show; text:Unstar">
347
+        <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"/></svg>
348
+        Unstar
349
+      </button>
350
+        <a class="social-count js-social-count" href="/kc5nra/obs-studio-utils/stargazers"
351
+           aria-label="8 users starred this repository">
352
+          8
353
+        </a>
354
+</form>
355
+    <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/kc5nra/obs-studio-utils/star" class="unstarred" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="/sSbA/aj/l81g7HuzKrbvT/fZClJWTOY1T6jjNOGbTpB0vtZBytYMlHPt25VUZnhDcnvUHq56bYpHx4cSnYfgA==" /></div>
356
+      <button
357
+        type="submit"
358
+        class="btn btn-sm btn-with-count js-toggler-target"
359
+        aria-label="Star this repository" title="Star kc5nra/obs-studio-utils"
360
+        data-ga-click="Repository, click star button, action:blob#show; text:Star">
361
+        <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"/></svg>
362
+        Star
363
+      </button>
364
+        <a class="social-count js-social-count" href="/kc5nra/obs-studio-utils/stargazers"
365
+           aria-label="8 users starred this repository">
366
+          8
367
+        </a>
368
+</form>  </div>
369
+
370
+  </li>
371
+
372
+  <li>
373
+          <a href="#fork-destination-box" class="btn btn-sm btn-with-count"
374
+              title="Fork your own copy of kc5nra/obs-studio-utils to your account"
375
+              aria-label="Fork your own copy of kc5nra/obs-studio-utils to your account"
376
+              rel="facebox"
377
+              data-ga-click="Repository, show fork modal, action:blob#show; text:Fork">
378
+              <svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
379
+            Fork
380
+          </a>
381
+
382
+          <div id="fork-destination-box" style="display: none;">
383
+            <h2 class="facebox-header" data-facebox-id="facebox-header">Where should we fork this repository?</h2>
384
+            <include-fragment src=""
385
+                class="js-fork-select-fragment fork-select-fragment"
386
+                data-url="/kc5nra/obs-studio-utils/fork?fragment=1">
387
+              <img alt="Loading" height="64" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-128.gif" width="64" />
388
+            </include-fragment>
389
+          </div>
390
+
391
+    <a href="/kc5nra/obs-studio-utils/network" class="social-count"
392
+       aria-label="4 users forked this repository">
393
+      4
394
+    </a>
395
+  </li>
396
+</ul>
397
+
398
+    <h1 class="public ">
399
+  <svg aria-hidden="true" class="octicon octicon-repo" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"/></svg>
400
+  <span class="author" itemprop="author"><a href="/kc5nra" class="url fn" rel="author">kc5nra</a></span><!--
401
+--><span class="path-divider">/</span><!--
402
+--><strong itemprop="name"><a href="/kc5nra/obs-studio-utils" data-pjax="#js-repo-pjax-container">obs-studio-utils</a></strong>
403
+
404
+</h1>
405
+
406
+  </div>
407
+  <div class="container">
408
+    
409
+<nav class="reponav js-repo-nav js-sidenav-container-pjax"
410
+     itemscope
411
+     itemtype="http://schema.org/BreadcrumbList"
412
+     role="navigation"
413
+     data-pjax="#js-repo-pjax-container">
414
+
415
+  <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
416
+    <a href="/kc5nra/obs-studio-utils" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /kc5nra/obs-studio-utils" itemprop="url">
417
+      <svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"/></svg>
418
+      <span itemprop="name">Code</span>
419
+      <meta itemprop="position" content="1">
420
+</a>  </span>
421
+
422
+    <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
423
+      <a href="/kc5nra/obs-studio-utils/issues" class="js-selected-navigation-item reponav-item" data-hotkey="g i" data-selected-links="repo_issues repo_labels repo_milestones /kc5nra/obs-studio-utils/issues" itemprop="url">
424
+        <svg aria-hidden="true" class="octicon octicon-issue-opened" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg>
425
+        <span itemprop="name">Issues</span>
426
+        <span class="counter">1</span>
427
+        <meta itemprop="position" content="2">
428
+</a>    </span>
429
+
430
+  <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
431
+    <a href="/kc5nra/obs-studio-utils/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /kc5nra/obs-studio-utils/pulls" itemprop="url">
432
+      <svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
433
+      <span itemprop="name">Pull requests</span>
434
+      <span class="counter">0</span>
435
+      <meta itemprop="position" content="3">
436
+</a>  </span>
437
+
438
+  <a href="/kc5nra/obs-studio-utils/projects" class="js-selected-navigation-item reponav-item" data-selected-links="repo_projects new_repo_project repo_project /kc5nra/obs-studio-utils/projects">
439
+    <svg aria-hidden="true" class="octicon octicon-project" height="16" version="1.1" viewBox="0 0 15 16" width="15"><path fill-rule="evenodd" d="M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z"/></svg>
440
+    Projects
441
+    <span class="counter">0</span>
442
+</a>
443
+    <a href="/kc5nra/obs-studio-utils/wiki" class="js-selected-navigation-item reponav-item" data-hotkey="g w" data-selected-links="repo_wiki /kc5nra/obs-studio-utils/wiki">
444
+      <svg aria-hidden="true" class="octicon octicon-book" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z"/></svg>
445
+      Wiki
446
+</a>
447
+
448
+  <a href="/kc5nra/obs-studio-utils/pulse" class="js-selected-navigation-item reponav-item" data-selected-links="pulse /kc5nra/obs-studio-utils/pulse">
449
+    <svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z"/></svg>
450
+    Pulse
451
+</a>
452
+  <a href="/kc5nra/obs-studio-utils/graphs" class="js-selected-navigation-item reponav-item" data-selected-links="repo_graphs repo_contributors /kc5nra/obs-studio-utils/graphs">
453
+    <svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"/></svg>
454
+    Graphs
455
+</a>
456
+
457
+</nav>
458
+
459
+  </div>
460
+</div>
461
+
462
+<div class="container new-discussion-timeline experiment-repo-nav">
463
+  <div class="repository-content">
464
+
465
+    
466
+
467
+<a href="/kc5nra/obs-studio-utils/blob/b3ffed1c23a254e44d3dcdd2af3f9b13f63d7939/install/osx/obs.png" class="d-none js-permalink-shortcut" data-hotkey="y">Permalink</a>
468
+
469
+<!-- blob contrib key: blob_contributors:v21:6c7ce207313616b1dc79697595d24fe7 -->
470
+
471
+<div class="file-navigation js-zeroclipboard-container">
472
+  
473
+<div class="select-menu branch-select-menu js-menu-container js-select-menu float-left">
474
+  <button class="btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
475
+    
476
+    type="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true">
477
+    <i>Branch:</i>
478
+    <span class="js-select-button css-truncate-target">master</span>
479
+  </button>
480
+
481
+  <div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true">
482
+
483
+    <div class="select-menu-modal">
484
+      <div class="select-menu-header">
485
+        <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
486
+        <span class="select-menu-title">Switch branches/tags</span>
487
+      </div>
488
+
489
+      <div class="select-menu-filters">
490
+        <div class="select-menu-text-filter">
491
+          <input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Filter branches/tags">
492
+        </div>
493
+        <div class="select-menu-tabs">
494
+          <ul>
495
+            <li class="select-menu-tab">
496
+              <a href="#" data-tab-filter="branches" data-filter-placeholder="Filter branches/tags" class="js-select-menu-tab" role="tab">Branches</a>
497
+            </li>
498
+            <li class="select-menu-tab">
499
+              <a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
500
+            </li>
501
+          </ul>
502
+        </div>
503
+      </div>
504
+
505
+      <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
506
+
507
+        <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
508
+
509
+
510
+            <a class="select-menu-item js-navigation-item js-navigation-open selected"
511
+               href="/kc5nra/obs-studio-utils/blob/master/install/osx/obs.png"
512
+               data-name="master"
513
+               data-skip-pjax="true"
514
+               rel="nofollow">
515
+              <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
516
+              <span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
517
+                master
518
+              </span>
519
+            </a>
520
+        </div>
521
+
522
+          <div class="select-menu-no-results">Nothing to show</div>
523
+      </div>
524
+
525
+      <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
526
+        <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
527
+
528
+
529
+        </div>
530
+
531
+        <div class="select-menu-no-results">Nothing to show</div>
532
+      </div>
533
+
534
+    </div>
535
+  </div>
536
+</div>
537
+
538
+  <div class="BtnGroup float-right">
539
+    <a href="/kc5nra/obs-studio-utils/find/master"
540
+          class="js-pjax-capture-input btn btn-sm BtnGroup-item"
541
+          data-pjax
542
+          data-hotkey="t">
543
+      Find file
544
+    </a>
545
+    <button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm BtnGroup-item tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
546
+  </div>
547
+  <div class="breadcrumb js-zeroclipboard-target">
548
+    <span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/kc5nra/obs-studio-utils"><span>obs-studio-utils</span></a></span></span><span class="separator">/</span><span class="js-path-segment"><a href="/kc5nra/obs-studio-utils/tree/master/install"><span>install</span></a></span><span class="separator">/</span><span class="js-path-segment"><a href="/kc5nra/obs-studio-utils/tree/master/install/osx"><span>osx</span></a></span><span class="separator">/</span><strong class="final-path">obs.png</strong>
549
+  </div>
550
+</div>
551
+
552
+
553
+  <div class="commit-tease">
554
+      <span class="float-right">
555
+        <a class="commit-tease-sha" href="/kc5nra/obs-studio-utils/commit/b83a806a64ffd96f547029d64ed28aad49e20d5b" data-pjax>
556
+          b83a806
557
+        </a>
558
+        <relative-time datetime="2014-10-01T22:46:15Z">Oct 1, 2014</relative-time>
559
+      </span>
560
+      <div>
561
+        <img alt="@kc5nra" class="avatar" height="20" src="https://avatars3.githubusercontent.com/u/231018?v=3&amp;s=40" width="20" />
562
+        <a href="/kc5nra" class="user-mention" rel="author">kc5nra</a>
563
+          <a href="/kc5nra/obs-studio-utils/commit/b83a806a64ffd96f547029d64ed28aad49e20d5b" class="message" data-pjax="true" title="Png more transparent, obs bundle id and img loc">Png more transparent, obs bundle id and img loc</a>
564
+      </div>
565
+
566
+    <div class="commit-tease-contributors">
567
+      <button type="button" class="btn-link muted-link contributors-toggle" data-facebox="#blob_contributors_box">
568
+        <strong>1</strong>
569
+         contributor
570
+      </button>
571
+      
572
+    </div>
573
+
574
+    <div id="blob_contributors_box" style="display:none">
575
+      <h2 class="facebox-header" data-facebox-id="facebox-header">Users who have contributed to this file</h2>
576
+      <ul class="facebox-user-list" data-facebox-id="facebox-description">
577
+          <li class="facebox-user-list-item">
578
+            <img alt="@kc5nra" height="24" src="https://avatars1.githubusercontent.com/u/231018?v=3&amp;s=48" width="24" />
579
+            <a href="/kc5nra">kc5nra</a>
580
+          </li>
581
+      </ul>
582
+    </div>
583
+  </div>
584
+
585
+
586
+<div class="file">
587
+  <div class="file-header">
588
+  <div class="file-actions">
589
+
590
+    <div class="BtnGroup">
591
+      <a href="/kc5nra/obs-studio-utils/raw/master/install/osx/obs.png" class="btn btn-sm BtnGroup-item" id="raw-url">Download</a>
592
+      <a href="/kc5nra/obs-studio-utils/commits/master/install/osx/obs.png" class="btn btn-sm BtnGroup-item" rel="nofollow">History</a>
593
+    </div>
594
+
595
+        <a class="btn-octicon tooltipped tooltipped-nw"
596
+           href="github-mac://openRepo/https://github.com/kc5nra/obs-studio-utils?branch=master&amp;filepath=install%2Fosx%2Fobs.png"
597
+           aria-label="Open this file in GitHub Desktop"
598
+           data-ga-click="Repository, open with desktop, type:mac">
599
+            <svg aria-hidden="true" class="octicon octicon-device-desktop" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M15 2H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5.34c-.25.61-.86 1.39-2.34 2h8c-1.48-.61-2.09-1.39-2.34-2H15c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm0 9H1V3h14v8z"/></svg>
600
+        </a>
601
+
602
+        <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/kc5nra/obs-studio-utils/delete/master/install/osx/obs.png" class="inline-form" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="uGzTDUGxcZBqCvnvwWvHWxzog35RyhtwqPCf9WmjMskKj0JcMzGgzzfI9Vg2tnJjAjFGp9psbMbIg54+M9+7/A==" /></div>
603
+          <button class="btn-octicon btn-octicon-danger tooltipped tooltipped-nw" type="submit"
604
+            aria-label="Delete the file in your fork of this project" data-disable-with>
605
+            <svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"/></svg>
606
+          </button>
607
+</form>  </div>
608
+
609
+  <div class="file-info">
610
+    52.8 KB
611
+  </div>
612
+</div>
613
+
614
+  
615
+
616
+  <div itemprop="text" class="blob-wrapper data type-text">
617
+      <div class="image">
618
+          <span class="border-wrap"><img src="/kc5nra/obs-studio-utils/blob/master/install/osx/obs.png?raw=true" alt="obs.png"></span>
619
+      </div>
620
+  </div>
621
+
622
+</div>
623
+
624
+<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="d-none">Jump to Line</button>
625
+<div id="jump-to-line" style="display:none">
626
+  <!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
627
+    <input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" aria-label="Jump to line" autofocus>
628
+    <button type="submit" class="btn">Go</button>
629
+</form></div>
630
+
631
+  </div>
632
+  <div class="modal-backdrop js-touch-events"></div>
633
+</div>
634
+
635
+
636
+    </div>
637
+  </div>
638
+
639
+    </div>
640
+
641
+        <div class="container site-footer-container">
642
+  <div class="site-footer" role="contentinfo">
643
+    <ul class="site-footer-links float-right">
644
+        <li><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact GitHub</a></li>
645
+      <li><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
646
+      <li><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
647
+      <li><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
648
+        <li><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
649
+        <li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
650
+
651
+    </ul>
652
+
653
+    <a href="https://github.com" aria-label="Homepage" class="site-footer-mark" title="GitHub">
654
+      <svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
655
+</a>
656
+    <ul class="site-footer-links">
657
+      <li>&copy; 2017 <span title="0.13223s from github-fe143-cp1-prd.iad.github.net">GitHub</span>, Inc.</li>
658
+        <li><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
659
+        <li><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
660
+        <li><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
661
+        <li><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
662
+        <li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
663
+    </ul>
664
+  </div>
665
+</div>
666
+
667
+
668
+
669
+    
670
+
671
+    <div id="ajax-error-message" class="ajax-error-message flash flash-error">
672
+      <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
673
+      <button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
674
+        <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
675
+      </button>
676
+      You can't perform that action at this time.
677
+    </div>
678
+
679
+
680
+      
681
+      <script crossorigin="anonymous" integrity="sha256-uzmufYSNQNbwHmc1XigpZPVPo5E3wOzJ/E7Dfn1GlQg=" src="https://assets-cdn.github.com/assets/frameworks-bb39ae7d848d40d6f01e67355e282964f54fa39137c0ecc9fc4ec37e7d469508.js"></script>
682
+      <script async="async" crossorigin="anonymous" integrity="sha256-/48DIbQkaCd8FbKJGEm8s5jOpo2/L4j5LZ+RY+umtSU=" src="https://assets-cdn.github.com/assets/github-ff8f0321b42468277c15b2891849bcb398cea68dbf2f88f92d9f9163eba6b525.js"></script>
683
+      
684
+      
685
+      
686
+      
687
+    <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
688
+      <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
689
+      <span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
690
+      <span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
691
+    </div>
692
+    <div class="facebox" id="facebox" style="display:none;">
693
+  <div class="facebox-popup">
694
+    <div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
695
+    </div>
696
+    <button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
697
+      <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
698
+    </button>
699
+  </div>
700
+</div>
701
+
702
+  </body>
703
+</html>
704
+
705
obs-studio-17.0.1.tar.xz/CI/install/osx/package_util.py Added
96
 
1
@@ -0,0 +1,94 @@
2
+def cmd(cmd):
3
+    import subprocess
4
+    import shlex
5
+    return subprocess.check_output(shlex.split(cmd)).rstrip('\r\n')
6
+
7
+def get_tag_info(tag):
8
+    rev = cmd('git rev-parse {0}'.format(latest_tag))
9
+    anno = cmd('git cat-file -p {0}'.format(rev))
10
+    tag_info = []
11
+    for i, v in enumerate(anno.splitlines()):
12
+        if i <= 4:
13
+            continue
14
+        tag_info.append(v.lstrip())
15
+
16
+    return tag_info
17
+
18
+def gen_html(github_user, latest_tag):
19
+
20
+    url = 'https://github.com/{0}/obs-studio/commit/%H'.format(github_user)
21
+
22
+    with open('readme.html', 'w') as f:
23
+        f.write("<html><body>")
24
+        log_cmd = """git log {0}...HEAD --pretty=format:'<li>&bull; <a href="{1}">(view)</a> %s</li>'"""
25
+        log_res = cmd(log_cmd.format(latest_tag, url))
26
+        if len(log_res.splitlines()):
27
+            f.write('<p>Changes since {0}: (Newest to oldest)</p>'.format(latest_tag))
28
+            f.write(log_res)
29
+
30
+        ul = False
31
+        f.write('<p>')
32
+        import re
33
+
34
+        for l in get_tag_info(latest_tag):
35
+            if not len(l):
36
+                continue
37
+            if l.startswith('*'):
38
+                ul = True
39
+                if not ul:
40
+                    f.write('<ul>')
41
+                f.write('<li>&bull; {0}</li>'.format(re.sub(r'^(\s*)?[*](\s*)?', '', l)))
42
+            else:
43
+                if ul:
44
+                    f.write('</ul><p/>')
45
+                ul = False
46
+                f.write('<p>{0}</p>'.format(l))
47
+        if ul:
48
+            f.write('</ul>')
49
+        f.write('</p></body></html>')
50
+
51
+    cmd('textutil -convert rtf readme.html -output readme.rtf')
52
+    cmd("""sed -i '' 's/Times-Roman/Verdana/g' readme.rtf""")
53
+
54
+def save_manifest(latest_tag, user, jenkins_build, branch, stable):
55
+    log = cmd('git log --pretty=oneline {0}...HEAD'.format(latest_tag))
56
+    manifest = {}
57
+    manifest['commits'] = []
58
+    for v in log.splitlines():
59
+        manifest['commits'].append(v)
60
+    manifest['tag'] = {
61
+        'name': latest_tag,
62
+        'description': get_tag_info(latest_tag)
63
+    }
64
+
65
+    manifest['version'] = cmd('git rev-list HEAD --count')
66
+    manifest['sha1'] = cmd('git rev-parse HEAD')
67
+    manifest['jenkins_build'] = jenkins_build
68
+
69
+    manifest['user'] = user
70
+    manifest['branch'] = branch
71
+    manifest['stable'] = stable
72
+
73
+    import cPickle
74
+    with open('manifest', 'w') as f:
75
+        cPickle.dump(manifest, f)
76
+
77
+def prepare_pkg(project, package_id):
78
+    cmd('packagesutil --file "{0}" set package-1 identifier {1}'.format(project, package_id))
79
+    cmd('packagesutil --file "{0}" set package-1 version {1}'.format(project, '1.0'))
80
+
81
+
82
+import argparse
83
+parser = argparse.ArgumentParser(description='obs-studio package util')
84
+parser.add_argument('-u', '--user', dest='user', default='jp9000')
85
+parser.add_argument('-p', '--package-id', dest='package_id', default='org.obsproject.pkg.obs-studio')
86
+parser.add_argument('-f', '--project-file', dest='project', default='OBS.pkgproj')
87
+parser.add_argument('-j', '--jenkins-build', dest='jenkins_build', default='0')
88
+parser.add_argument('-b', '--branch', dest='branch', default='master')
89
+parser.add_argument('-s', '--stable', dest='stable', required=False, action='store_true', default=False)
90
+args = parser.parse_args()
91
+
92
+latest_tag = cmd('git describe --tags --abbrev=0')
93
+gen_html(args.user, latest_tag)
94
+prepare_pkg(args.project, args.package_id)
95
+save_manifest(latest_tag, args.user, args.jenkins_build, args.branch, args.stable)
96
obs-studio-17.0.1.tar.xz/CI/util Added
2
 
1
+(directory)
2
obs-studio-17.0.1.tar.xz/CI/util/build-package-deps-osx.sh Added
133
 
1
@@ -0,0 +1,130 @@
2
+#!/usr/bin/env bash
3
+
4
+CURDIR=$(pwd)
5
+
6
+# the temp directory
7
+WORK_DIR=`mktemp -d`
8
+
9
+# deletes the temp directory
10
+function cleanup {
11
+  #rm -rf "$WORK_DIR"
12
+  echo "Deleted temp working directory $WORK_DIR"
13
+}
14
+
15
+# register the cleanup function to be called on the EXIT signal
16
+trap cleanup EXIT
17
+
18
+cd $WORK_DIR
19
+
20
+DEPS_DEST=$WORK_DIR/obsdeps
21
+
22
+# make dest dirs
23
+mkdir $DEPS_DEST
24
+mkdir $DEPS_DEST/bin
25
+mkdir $DEPS_DEST/include
26
+
27
+# OSX COMPAT
28
+export MACOSX_DEPLOYMENT_TARGET=10.9
29
+
30
+# If you need an olders SDK and Xcode won't give it to you
31
+# https://github.com/phracker/MacOSX-SDKs
32
+
33
+# libopus
34
+curl -L -O http://downloads.xiph.org/releases/opus/opus-1.1.3.tar.gz
35
+tar -xf opus-1.1.3.tar.gz
36
+cd ./opus-1.1.3
37
+mkdir build
38
+cd ./build
39
+../configure --disable-shared --enable-static --prefix="/tmp/obsdeps"
40
+make -j 12
41
+make install
42
+
43
+cd $WORK_DIR
44
+
45
+# libogg
46
+curl -L -O http://downloads.xiph.org/releases/ogg/libogg-1.3.2.tar.gz
47
+tar -xf libogg-1.3.2.tar.gz
48
+cd ./libogg-1.3.2
49
+mkdir build
50
+cd ./build
51
+../configure --disable-shared --enable-static --prefix="/tmp/obsdeps"
52
+make -j 12
53
+make install
54
+
55
+cd $WORK_DIR
56
+
57
+# libvorbis
58
+curl -L -O http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.5.tar.gz
59
+tar -xf libvorbis-1.3.5.tar.gz
60
+cd ./libvorbis-1.3.5
61
+mkdir build
62
+cd ./build
63
+../configure --disable-shared --enable-static --prefix="/tmp/obsdeps"
64
+make -j 12
65
+make install
66
+
67
+cd $WORK_DIR
68
+
69
+# libvpx
70
+curl -L -O http://storage.googleapis.com/downloads.webmproject.org/releases/webm/libvpx-1.6.0.tar.bz2
71
+tar -xf libvpx-1.6.0.tar.bz2
72
+cd ./libvpx-1.6.0
73
+mkdir build
74
+cd ./build
75
+../configure --disable-shared --libdir="/tmp/obsdeps/bin"
76
+make -j 12
77
+make install
78
+
79
+cd $WORK_DIR
80
+
81
+# x264
82
+git clone git://git.videolan.org/x264.git
83
+cd ./x264
84
+mkdir build
85
+cd ./build
86
+../configure --extra-ldflags="-mmacosx-version-min=10.9" --enable-static --prefix="/tmp/obsdeps"
87
+make -j 12
88
+make install
89
+../configure --extra-ldflags="-mmacosx-version-min=10.9" --enable-shared --libdir="/tmp/obsdeps/bin" --prefix="/tmp/obsdeps"
90
+make -j 12
91
+ln -f -s libx264.*.dylib libx264.dylib
92
+find . -name \*.dylib -exec cp \{\} $DEPS_DEST/bin/ \;
93
+rsync -avh --include="*/" --include="*.h" --exclude="*" ../* $DEPS_DEST/include/
94
+rsync -avh --include="*/" --include="*.h" --exclude="*" ./* $DEPS_DEST/include/
95
+
96
+cd $WORK_DIR
97
+
98
+# janson
99
+curl -L -O http://www.digip.org/jansson/releases/jansson-2.9.tar.gz
100
+tar -xf jansson-2.9.tar.gz
101
+cd jansson-2.9
102
+mkdir build
103
+cd ./build
104
+../configure --libdir="/tmp/obsdeps/bin" --enable-shared --disable-static
105
+make -j 12
106
+find . -name \*.dylib -exec cp \{\} $DEPS_DEST/bin/ \;
107
+rsync -avh --include="*/" --include="*.h" --exclude="*" ../* $DEPS_DEST/include/
108
+rsync -avh --include="*/" --include="*.h" --exclude="*" ./* $DEPS_DEST/include/
109
+
110
+cd $WORK_DIR
111
+
112
+export LDFLAGS="-L/tmp/obsdeps/lib"
113
+export CFLAGS="-I/tmp/obsdeps/include"
114
+
115
+# FFMPEG
116
+curl -L -O https://github.com/FFmpeg/FFmpeg/archive/n3.2.2.zip
117
+unzip ./n3.2.2.zip
118
+cd ./FFmpeg-n3.2.2
119
+mkdir build
120
+cd ./build
121
+../configure --extra-ldflags="-mmacosx-version-min=10.9" --enable-shared --disable-static --shlibdir="/tmp/obsdeps/bin" --enable-gpl --disable-doc --enable-libx264 --enable-libopus --enable-libvorbis --enable-libvpx
122
+make -j 12
123
+find . -name \*.dylib -exec cp \{\} $DEPS_DEST/bin/ \;
124
+rsync -avh --include="*/" --include="*.h" --exclude="*" ../* $DEPS_DEST/include/
125
+rsync -avh --include="*/" --include="*.h" --exclude="*" ./* $DEPS_DEST/include/
126
+
127
+cd $WORK_DIR
128
+
129
+tar -czf osx-deps.tar.gz obsdeps
130
+
131
+cp ./osx-deps.tar.gz $CURDIR
132
\ No newline at end of file
133
obs-studio-17.0.1.tar.xz/CI/util/win32.sh Added
71
 
1
@@ -0,0 +1,69 @@
2
+#/bin/bash
3
+
4
+cd x264
5
+make clean
6
+LDFLAGS="-static-libgcc" ./configure --enable-shared --enable-win32thread --disable-avs --disable-ffms --disable-gpac --disable-interlaced --disable-lavf --cross-prefix=i686-w64-mingw32- --host=i686-pc-mingw32 --prefix="/home/jim/packages/win32"
7
+make -j6 fprofiled VIDS="CITY_704x576_60_orig_01.yuv"
8
+make install
9
+i686-w64-mingw32-dlltool -z /home/jim/packages/win32/bin/x264.orig.def --export-all-symbols /home/jim/packages/win32/bin/libx264-148.dll
10
+grep "EXPORTS\|x264" /home/jim/packages/win32/bin/x264.orig.def > /home/jim/packages/win32/bin/x264.def
11
+rm -f /home/jim/packages/win32/bin/x264.org.def
12
+sed -i -e "/\\t.*DATA/d" -e "/\\t\".*/d" -e "s/\s@.*//" /home/jim/packages/win32/bin/x264.def
13
+i686-w64-mingw32-dlltool -m i386 -d /home/jim/packages/win32/bin/x264.def -l /home/jim/packages/win32/bin/x264.lib -D /home/jim/win32/packages/bin/libx264-148.dll
14
+cd ..
15
+
16
+cd opus
17
+make clean
18
+LDFLAGS="-static-libgcc" ./configure -host=i686-w64-mingw32 --prefix="/home/jim/packages/win32" --enable-shared
19
+make -j6
20
+make install
21
+cd ..
22
+
23
+cd zlib/build32
24
+make clean
25
+cmake .. -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_INSTALL_PREFIX=/home/jim/packages/win32 -DINSTALL_PKGCONFIG_DIR=/home/jim/packages/win32/lib/pkgconfig -DCMAKE_RC_COMPILER=i686-w64-mingw32-windres -DCMAKE_SHARED_LINKER_FLAGS="-static-libgcc"
26
+make -j6
27
+make install
28
+mv ../../win32/lib/libzlib.dll.a ../../win32/lib/libz.dll.a
29
+mv ../../win32/lib/libzlibstatic.a ../../win32/lib/libz.a
30
+cp ../win32/zlib.def /home/jim/packages/win32/bin
31
+i686-w64-mingw32-dlltool -m i386 -d ../win32/zlib.def -l /home/jim/packages/win32/bin/zlib.lib -D /home/jim/win32/packages/bin/zlib.dll
32
+cd ../..
33
+
34
+cd libpng
35
+make clean
36
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win32/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win32/include" ./configure -host=i686-w64-mingw32 --prefix="/home/jim/packages/win32" --enable-shared
37
+make -j6
38
+make install
39
+cd ..
40
+
41
+cd libogg
42
+make clean
43
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win32/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win32/include" ./configure -host=i686-w64-mingw32 --prefix="/home/jim/packages/win32" --enable-shared
44
+make -j6
45
+make install
46
+cd ..
47
+
48
+cd libvorbis
49
+make clean
50
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win32/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win32/include" ./configure -host=i686-w64-mingw32 --prefix="/home/jim/packages/win32" --enable-shared --with-ogg="/home/jim/packages/win32"
51
+make -j6
52
+make install
53
+cd ..
54
+
55
+cd libvpxbuild
56
+make clean
57
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" CROSS=i686-w64-mingw32- LDFLAGS="-static-libgcc" ../libvpx/configure --prefix=/home/jim/packages/win32 --enable-vp8 --enable-vp9 --disable-docs --disable-examples --enable-shared --disable-static --enable-runtime-cpu-detect --enable-realtime-only --disable-install-bins --disable-install-docs --disable-unit-tests --target=x86-win32-gcc
58
+make -j6
59
+make install
60
+i686-w64-mingw32-dlltool -m i386 -d libvpx.def -l /home/jim/packages/win32/bin/vpx.lib -D /home/jim/win32/packages/bin/libvpx-1.dll
61
+cd ..
62
+
63
+cd ffmpeg
64
+make clean
65
+cp /media/sf_linux/nvEncodeAPI.h /home/jim/packages/win32/include
66
+PKG_CONFIG_PATH="/home/jim/packages/win32/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win32/lib -static-libgcc" CFLAGS="-I/home/jim/packages/win32/include" ./configure --enable-memalign-hack --enable-gpl --disable-programs --disable-doc --arch=x86 --enable-shared --enable-nvenc --enable-libx264 --enable-libopus --enable-libvorbis --enable-libvpx --disable-debug --cross-prefix=i686-w64-mingw32- --target-os=mingw32 --pkg-config=pkg-config --prefix="/home/jim/packages/win32" --disable-postproc
67
+read -n1 -r -p "Press any key to continue building FFmpeg..." key
68
+make -j6
69
+make install
70
+cd ..
71
obs-studio-17.0.1.tar.xz/CI/util/win64.sh Added
71
 
1
@@ -0,0 +1,69 @@
2
+#/bin/bash
3
+
4
+cd x264
5
+make clean
6
+LDFLAGS="-static-libgcc" ./configure --enable-shared --enable-win32thread --disable-avs --disable-ffms --disable-gpac --disable-interlaced --disable-lavf --cross-prefix=x86_64-w64-mingw32- --host=x86_64-pc-mingw32 --prefix="/home/jim/packages/win64"
7
+make -j6 fprofiled VIDS="CITY_704x576_60_orig_01.yuv"
8
+make install
9
+x86_64-w64-mingw32-dlltool -z /home/jim/packages/win64/bin/x264.orig.def --export-all-symbols /home/jim/packages/win64/bin/libx264-148.dll
10
+grep "EXPORTS\|x264" /home/jim/packages/win64/bin/x264.orig.def > /home/jim/packages/win64/bin/x264.def
11
+rm -f /home/jim/packages/win64/bin/x264.org.def
12
+sed -i -e "/\\t.*DATA/d" -e "/\\t\".*/d" -e "s/\s@.*//" /home/jim/packages/win64/bin/x264.def
13
+x86_64-w64-mingw32-dlltool -m i386:x86-64 -d /home/jim/packages/win64/bin/x264.def -l /home/jim/packages/win64/bin/x264.lib -D /home/jim/win64/packages/bin/libx264-148.dll
14
+cd ..
15
+
16
+cd opus
17
+make clean
18
+LDFLAGS="-static-libgcc" ./configure -host=x86_64-w64-mingw32 --prefix="/home/jim/packages/win64" --enable-shared
19
+make -j6
20
+make install
21
+cd ..
22
+
23
+cd zlib/build64
24
+make clean
25
+cmake .. -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_INSTALL_PREFIX=/home/jim/packages/win64 -DCMAKE_RC_COMPILER=x86_64-w64-mingw32-windres -DCMAKE_SHARED_LINKER_FLAGS="-static-libgcc"
26
+make -j6
27
+make install
28
+mv ../../win64/lib/libzlib.dll.a ../../win64/lib/libz.dll.a
29
+mv ../../win64/lib/libzlibstatic.a ../../win64/lib/libz.a
30
+cp ../win64/zlib.def /home/jim/packages/win64/bin
31
+x86_64-w64-mingw32-dlltool -m i386:x86-64 -d ../win32/zlib.def -l /home/jim/packages/win64/bin/zlib.lib -D /home/jim/win64/packages/bin/zlib.dll
32
+cd ../..
33
+
34
+cd libpng
35
+make clean
36
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win64/lib" CPPFLAGS="-I/home/jim/packages/win64/include" ./configure -host=x86_64-w64-mingw32 --prefix="/home/jim/packages/win64" --enable-shared
37
+make -j6
38
+make install
39
+cd ..
40
+
41
+cd libogg
42
+make clean
43
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win64/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win64/include" ./configure -host=x86_64-w64-mingw32 --prefix="/home/jim/packages/win64" --enable-shared
44
+make -j6
45
+make install
46
+cd ..
47
+
48
+cd libvorbis
49
+make clean
50
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win64/lib -static-libgcc" CPPFLAGS="-I/home/jim/packages/win64/include" ./configure -host=x86_64-w64-mingw32 --prefix="/home/jim/packages/win64" --enable-shared --with-ogg="/home/jim/packages/win64"
51
+make -j6
52
+make install
53
+cd ..
54
+
55
+cd libvpxbuild
56
+make clean
57
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" CROSS=x86_64-w64-mingw32- LDFLAGS="-static-libgcc" ../libvpx/configure --prefix=/home/jim/packages/win64 --enable-vp8 --enable-vp9 --disable-docs --disable-examples --enable-shared --disable-static --enable-runtime-cpu-detect --enable-realtime-only --disable-install-bins --disable-install-docs --disable-unit-tests --target=x86_64-win64-gcc
58
+make -j6
59
+make install
60
+x86_64-w64-mingw32-dlltool -m i386:x86-64 -d libvpx.def -l /home/jim/packages/win64/bin/vpx.lib -D /home/jim/win64/packages/bin/libvpx-1.dll
61
+cd ..
62
+
63
+cd ffmpeg
64
+make clean
65
+cp /media/sf_linux/nvEncodeAPI.h /home/jim/packages/win64/include
66
+PKG_CONFIG_PATH="/home/jim/packages/win64/lib/pkgconfig" LDFLAGS="-L/home/jim/packages/win64/lib" CPPFLAGS="-I/home/jim/packages/win64/include" ./configure --enable-memalign-hack --enable-gpl --disable-doc --arch=x86_64 --enable-shared --enable-nvenc --enable-libx264 --enable-libopus --enable-libvorbis --enable-libvpx --disable-debug --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32 --pkg-config=pkg-config --prefix="/home/jim/packages/win64" --disable-postproc
67
+read -n1 -r -p "Press any key to continue building FFmpeg..." key
68
+make -j6
69
+make install
70
+cd ..
71
obs-studio-0.17.0.tar.xz/UI/data/locale/ca-ES.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/ca-ES.ini Changed
96
 
1
@@ -52,6 +52,10 @@
2
 Hours="Hores"
3
 Minutes="Minuts"
4
 Seconds="Segons"
5
+Deprecated="Obsolet"
6
+ReplayBuffer="Memòria intermèdia de reproducció"
7
+Import="Importa"
8
+Export="Exporta"
9
 
10
 QuickTransitions.SwapScenes="Canvia la vista prèvia i sortida d'escenes després de la transició"
11
 QuickTransitions.SwapScenesTT="Canvia la vista prèvia i sortida d'escenes després de la transició (si encara existeix l'escena original de la sortida). \nAixò no desfarà qualsevol canvi que pugui haver fet a l'escena original de la sortida."
12
@@ -106,6 +110,8 @@
13
 Output.RecordNoSpace.Msg="No hi ha prou espai de disc per continuar la gravació."
14
 Output.RecordError.Title="Error en l'enregistrament"
15
 Output.RecordError.Msg="S'ha produït un error desconegut mentre es gravava."
16
+Output.ReplayBuffer.NoHotkey.Title="Cap tecla d'accés ràpid!"
17
+Output.ReplayBuffer.NoHotkey.Msg="Cap tecla d'accés ràpid establerta per la memòria intermèdia de reproducció. Configureu la tecla d'accés \"Desa\" per desar els enregistraments de reproducció."
18
 
19
 Output.BadPath.Title="Ruta de l'arxiu incorrecta"
20
 Output.BadPath.Text="La ruta configurada pel fitxer de sortida no és vàlida.  Si us plau, comproveu la configuració per confirmar que s'ha creat una ruta de fitxer vàlida."
21
@@ -261,9 +267,12 @@
22
 Basic.Main.Sources="Orígens"
23
 Basic.Main.Connecting="S'està connectant..."
24
 Basic.Main.StartRecording="Inicia l'enregistrament"
25
-Basic.Main.StartStreaming="Inicia l'enregistrament"
26
+Basic.Main.StartReplayBuffer="Inicia la reproducció de la memòria intermèdia"
27
+Basic.Main.StartStreaming="Inicia la transmissió"
28
 Basic.Main.StopRecording="Atura l'enregistrament"
29
 Basic.Main.StoppingRecording="Aturant l'enregistrament..."
30
+Basic.Main.StopReplayBuffer="Atura la reproducció de la memòria intermèdia"
31
+Basic.Main.StoppingReplayBuffer="S'està aturant la reproducció de la memòria intermèdia..."
32
 Basic.Main.StopStreaming="Atura l'enregistrament"
33
 Basic.Main.StoppingStreaming="Aturant la transmissió..."
34
 Basic.Main.ForceStopStreaming="Atura l'enregistrament (descarta el retard)"
35
@@ -273,7 +282,7 @@
36
 Basic.MainMenu.File.Import="&Importa"
37
 Basic.MainMenu.File.ShowRecordings="Mostra els en&registraments"
38
 Basic.MainMenu.File.Remux="Converteix format de gravacions"
39
-Basic.MainMenu.File.Settings="&Paràmetres"
40
+Basic.MainMenu.File.Settings="&Configuració"
41
 Basic.MainMenu.File.ShowSettingsFolder="Mostrar carpeta de configuració"
42
 Basic.MainMenu.File.ShowProfileFolder="Mostra la carpeta del perfil"
43
 Basic.MainMenu.AlwaysOnTop="&Sempre al davant"
44
@@ -285,8 +294,14 @@
45
 Basic.MainMenu.Edit.UndoAction="&Desfés $1"
46
 Basic.MainMenu.Edit.RedoAction="&Refés $1"
47
 Basic.MainMenu.Edit.LockPreview="&Bloquejar vista prèvia"
48
+Basic.MainMenu.Edit.Scale="Vista prèvia i escalat"
49
+Basic.MainMenu.Edit.Scale.Window="Ajusta a la finestra"
50
+Basic.MainMenu.Edit.Scale.Canvas="Tela (%1x%2)"
51
+Basic.MainMenu.Edit.Scale.Output="Sortida (%1x%2)"
52
 Basic.MainMenu.Edit.Transform="&Transforma"
53
 Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformació..."
54
+Basic.MainMenu.Edit.Transform.CopyTransform="Copia la transformació"
55
+Basic.MainMenu.Edit.Transform.PasteTransform="Enganxa la transformació"
56
 Basic.MainMenu.Edit.Transform.ResetTransform="&Reinicialitza Transformació"
57
 Basic.MainMenu.Edit.Transform.Rotate90CW="Gira 90 graus a la dreta"
58
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Gira 90 graus a l'esquerra"
59
@@ -311,6 +326,12 @@
60
 
61
 Basic.MainMenu.SceneCollection="&Col·lecció d'escenes"
62
 Basic.MainMenu.Profile="&Perfil"
63
+Basic.MainMenu.Profile.Import="Importació del perfil"
64
+Basic.MainMenu.Profile.Export="Exportació del perfil"
65
+Basic.MainMenu.SceneCollection.Import="Importa col·lecció d'escenes"
66
+Basic.MainMenu.SceneCollection.Export="Exporta la col·lecció d'escenes"
67
+Basic.MainMenu.Profile.Exists="El perfil ja existeix"
68
+Basic.MainMenu.SceneCollection.Exists="La col·lecció d'escenes ja existeix"
69
 
70
 Basic.MainMenu.Tools="&Eines"
71
 
72
@@ -357,6 +378,14 @@
73
 Basic.Settings.Output.Mode.Simple="Simple"
74
 Basic.Settings.Output.Mode.Adv="Avançat"
75
 Basic.Settings.Output.Mode.FFmpeg="Sortida FFmpeg"
76
+Basic.Settings.Output.UseReplayBuffer="Activa la reproducció de la memòria intermèdia"
77
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Temps de reproducció màxim (segons)"
78
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memòria màxima (MB)"
79
+Basic.Settings.Output.ReplayBuffer.Estimate="Ús aproximat de memòria: %1 MB"
80
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="No es pot estimar l'ús de memòria. Establiu el límit màxim de memòria."
81
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Assegureu-vos d'establir una tecla d'accés ràpid per la memòria intermèdia de reproducció a la secció de tecles ràpides)"
82
+Basic.Settings.Output.ReplayBuffer.Prefix="Prefix del nom del fitxer de la memòria intermèdia"
83
+Basic.Settings.Output.ReplayBuffer.Suffix="Sufix"
84
 Basic.Settings.Output.Simple.SavePath="Camí d'enregistrament"
85
 Basic.Settings.Output.Simple.RecordingQuality="Qualitat de l'enregistrament"
86
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Mateixa que en directe"
87
@@ -394,6 +423,8 @@
88
 Basic.Settings.Output.Adv.Audio.Track2="Pista 2"
89
 Basic.Settings.Output.Adv.Audio.Track3="Pista 3"
90
 Basic.Settings.Output.Adv.Audio.Track4="Pista 4"
91
+Basic.Settings.Output.Adv.Audio.Track5="Pista 5"
92
+Basic.Settings.Output.Adv.Audio.Track6="Pista 6"
93
 
94
 Basic.Settings.Output.Adv.Recording="Enregistrament"
95
 Basic.Settings.Output.Adv.Recording.Type="Tipus"
96
obs-studio-0.17.0.tar.xz/UI/data/locale/cs-CZ.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/cs-CZ.ini Changed
10
 
1
@@ -423,6 +423,8 @@
2
 Basic.Settings.Output.Adv.Audio.Track2="Stopa 2"
3
 Basic.Settings.Output.Adv.Audio.Track3="Stopa 3"
4
 Basic.Settings.Output.Adv.Audio.Track4="Stopa 4"
5
+Basic.Settings.Output.Adv.Audio.Track5="Stopa 5"
6
+Basic.Settings.Output.Adv.Audio.Track6="Stopa 6"
7
 
8
 Basic.Settings.Output.Adv.Recording="Nahrávání"
9
 Basic.Settings.Output.Adv.Recording.Type="Typ"
10
obs-studio-0.17.0.tar.xz/UI/data/locale/de-DE.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/de-DE.ini Changed
10
 
1
@@ -3,7 +3,7 @@
2
 Region="Deutschland"
3
 
4
 OK="OK"
5
-Apply="Anwenden"
6
+Apply="Übernehmen"
7
 Cancel="Abbrechen"
8
 Close="Schließen"
9
 Save="Speichern"
10
obs-studio-0.17.0.tar.xz/UI/data/locale/fi-FI.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/fi-FI.ini Changed
10
 
1
@@ -423,6 +423,8 @@
2
 Basic.Settings.Output.Adv.Audio.Track2="Raita 2"
3
 Basic.Settings.Output.Adv.Audio.Track3="Raita 3"
4
 Basic.Settings.Output.Adv.Audio.Track4="Raita 4"
5
+Basic.Settings.Output.Adv.Audio.Track5="Raita 5"
6
+Basic.Settings.Output.Adv.Audio.Track6="Raita 6"
7
 
8
 Basic.Settings.Output.Adv.Recording="Tallennus"
9
 Basic.Settings.Output.Adv.Recording.Type="Tyyppi"
10
obs-studio-0.17.0.tar.xz/UI/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/hu-HU.ini Changed
65
 
1
@@ -281,7 +281,7 @@
2
 Basic.MainMenu.File.Export="&Exportálás"
3
 Basic.MainMenu.File.Import="&Importálás"
4
 Basic.MainMenu.File.ShowRecordings="&Felvételek megjelenítése"
5
-Basic.MainMenu.File.Remux="Re&mux felvételek"
6
+Basic.MainMenu.File.Remux="Felvételek re&muxolása"
7
 Basic.MainMenu.File.Settings="&Beállítások"
8
 Basic.MainMenu.File.ShowSettingsFolder="Beállítási mappa megjelenítése"
9
 Basic.MainMenu.File.ShowProfileFolder="Profilmappa megjelenítése"
10
@@ -295,7 +295,7 @@
11
 Basic.MainMenu.Edit.RedoAction="&Ismét $1"
12
 Basic.MainMenu.Edit.LockPreview="&Előnézet zárolás"
13
 Basic.MainMenu.Edit.Scale="Előnézet &méretezés"
14
-Basic.MainMenu.Edit.Scale.Window="Ablakhoz skálázás"
15
+Basic.MainMenu.Edit.Scale.Window="Ablakhoz igazítás"
16
 Basic.MainMenu.Edit.Scale.Canvas="Vászon (%1x%2)"
17
 Basic.MainMenu.Edit.Scale.Output="Kimenet (%1x%2)"
18
 Basic.MainMenu.Edit.Transform="&Alakítás"
19
@@ -336,12 +336,12 @@
20
 Basic.MainMenu.Tools="&Eszközök"
21
 
22
 Basic.MainMenu.Help="&Segítség"
23
-Basic.MainMenu.Help.Website="Weboldal meglátogatása"
24
+Basic.MainMenu.Help.Website="Weboldal megtekintése"
25
 Basic.MainMenu.Help.Logs="&Naplófájlok"
26
 Basic.MainMenu.Help.Logs.ShowLogs="&Naplófájlok megjelenítése"
27
 Basic.MainMenu.Help.Logs.UploadCurrentLog="&Aktuális Naplófájl feltöltése"
28
 Basic.MainMenu.Help.Logs.UploadLastLog="&Utolsó Naplófájl feltöltése"
29
-Basic.MainMenu.Help.Logs.ViewCurrentLog="&Jelenlegi napló megtekintése"
30
+Basic.MainMenu.Help.Logs.ViewCurrentLog="&Jelenlegi Naplófájl megtekintése"
31
 Basic.MainMenu.Help.CheckForUpdates="Frissítések ellenőrzése"
32
 
33
 Basic.Settings.ProgramRestart="A beállítások érvénybe lépéséhez a program újraindítása szükséges."
34
@@ -373,7 +373,7 @@
35
 Basic.Settings.Output.Encoder="Kódoló"
36
 Basic.Settings.Output.SelectDirectory="Felvételi könyvtár kiválasztása"
37
 Basic.Settings.Output.SelectFile="Felvétel fájljának kiválasztása"
38
-Basic.Settings.Output.EnforceBitrate="Stream kiszolgáló bitráta korlátainak kényszerítése"
39
+Basic.Settings.Output.EnforceBitrate="Stream kiszolgáló bitsebesség korlátainak kényszerítése"
40
 Basic.Settings.Output.Mode="Kimeneti mód"
41
 Basic.Settings.Output.Mode.Simple="Egyszerű"
42
 Basic.Settings.Output.Mode.Adv="Haladó"
43
@@ -392,8 +392,8 @@
44
 Basic.Settings.Output.Simple.RecordingQuality.Small="Jó minőség, közepes fájlméret"
45
 Basic.Settings.Output.Simple.RecordingQuality.HQ="Megkülönböztethetetlen minőség, nagy fájlméret"
46
 Basic.Settings.Output.Simple.RecordingQuality.Lossless="Veszteségmentes minőség, hatalmas fájlméret"
47
-Basic.Settings.Output.Simple.Warn.VideoBitrate="Figyelem: Az adás videó bitrátája %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitráta korlátainak kényszerítése\" opciót."
48
-Basic.Settings.Output.Simple.Warn.AudioBitrate="Figyelem: Az adás audio bitrátája %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitráta korlátainak kényszerítése\" opciót."
49
+Basic.Settings.Output.Simple.Warn.VideoBitrate="Figyelem: Az adás videó bitsebessége %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitsebesség korlátainak kényszerítése\" opciót."
50
+Basic.Settings.Output.Simple.Warn.AudioBitrate="Figyelem: Az adás audio bitsebessége %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitsebesség korlátainak kényszerítése\" opciót."
51
 Basic.Settings.Output.Simple.Warn.Encoder="Figyelem: A streamtől eltérő minőséggel történő rögzítés, további CPU erőforrásokat igényel, ha egyidejűleg használja mindkettőt."
52
 Basic.Settings.Output.Simple.Warn.Lossless="Figyelem: A veszteségmentes minőséggel történő felvétel hatalmas fájlméretet generál. Ezzel a minőséggel percenként akár 7 gigabájt adatot is generálhat nagy felbontáson és képkockasebességen. Ez az eljárás nem ajánlott hosszú felvételekhez, kivéve ha hatalmas lemezterület áll rendelkezésre."
53
 Basic.Settings.Output.Simple.Warn.Lossless.Msg="Biztos benne, hogy veszteségmentes minőséget kíván használni?"
54
@@ -404,8 +404,8 @@
55
 Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardver (AMD)"
56
 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardver (NVENC)"
57
 Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Szoftveres (x264 alacsony CPU használati készlet, növekvő fájlméret)"
58
-Basic.Settings.Output.VideoBitrate="Videó bitráta"
59
-Basic.Settings.Output.AudioBitrate="Audio bitráta"
60
+Basic.Settings.Output.VideoBitrate="Videó bitsebesség"
61
+Basic.Settings.Output.AudioBitrate="Audio bitsebesség"
62
 Basic.Settings.Output.Reconnect="Automatikus újracsatlakozás"
63
 Basic.Settings.Output.RetryDelay="Újrapróbálkozás késleltetése (másodperc)"
64
 Basic.Settings.Output.MaxRetries="Újrapróbálkozások maximális száma"
65
obs-studio-0.17.0.tar.xz/UI/data/locale/it-IT.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/it-IT.ini Changed
226
 
1
@@ -20,7 +20,7 @@
2
 MoveUp="Sposta su"
3
 MoveDown="Sposta giù"
4
 Settings="Impostazioni"
5
-Display="Display"
6
+Display="Schermo"
7
 Name="Nome"
8
 Exit="Esci"
9
 Mixer="Mixer"
10
@@ -28,36 +28,39 @@
11
 Mono="Mono"
12
 Stereo="Stereo"
13
 DroppedFrames="Fotogrammi persi %1 (%2%)"
14
-PreviewProjector="Proiettore Schermo intero (Anteprima)"
15
-SceneProjector="Proiettore Schermo intero (Scena)"
16
-SourceProjector="Proiettore Schermo intero (Sorgente)"
17
+PreviewProjector="Proiettore a schermo intero (anteprima)"
18
+SceneProjector="Proiettore a schermo intero (scena)"
19
+SourceProjector="Proiettore a schermo intero (sorgente)"
20
 Clear="Svuota"
21
 Revert="Ripristina"
22
 Show="Mostra"
23
 Hide="Nascondi"
24
-Untitled="Senza Titolo"
25
+Untitled="Senza titolo"
26
 New="Nuovo"
27
 Duplicate="Duplica"
28
 Enable="Abilita"
29
-DisableOSXVSync="Disabilita il V-Sync OSX"
30
-ResetOSXVSyncOnExit="Reimpostare V-Sync OSX in uscita"
31
-HighResourceUsage="Codifica in sovraccarico!  È consigliabile abbassare le impostazioni video o utilizzare un settaggio predefinito di codifica più veloce."
32
+DisableOSXVSync="Disabilita V-Sync OSX"
33
+ResetOSXVSyncOnExit="Reimposta V-Sync OSX in uscita"
34
+HighResourceUsage="Codifica in sovraccarico!  È consigliabile abbassare le impostazioni video o utilizzare una preimpostazione predefinita di codifica più veloce."
35
 Transition="Transizione"
36
 QuickTransitions="Transizioni rapide"
37
 Left="Sinistra"
38
 Right="Destra"
39
 Top="Alto"
40
 Bottom="Basso"
41
-Reset="Reset"
42
+Reset="Ripristina"
43
 Hours="Ore"
44
 Minutes="Minuti"
45
 Seconds="Secondi"
46
 Deprecated="Deprecato"
47
-
48
-QuickTransitions.SwapScenes="Scambia Scena Preview/Uscita dopo la Transizione"
49
-QuickTransitions.SwapScenesTT="Scambia la scena in uniscita con quella in preview dopo la transizione (ammesso che la scena in uscita originale ci sia ancora).\nQuesto non modificherà eventuali cambiamenti apportati alla scena di uscita originale."
50
-QuickTransitions.DuplicateScene="Duplica Scena"
51
-QuickTransitions.DuplicateSceneTT="Quando si modifica la stessa scena, permette di modificare la trasformazione/visibilità di source senza modificare l'output. \nPer modificare le proprietà delle source senza modificare l'output, abilità 'Source duplicate'.\nCambiare questo valore resetterà la scena output attuale (se esite ancora)."
52
+ReplayBuffer="Buffer di replay"
53
+Import="Importa"
54
+Export="Esporta"
55
+
56
+QuickTransitions.SwapScenes="Scambia scene di anteprima/uscita dopo la transizione"
57
+QuickTransitions.SwapScenesTT="Scambia le scene di uscita con quella in anteprima dopo la transizione (ammesso che la scena in uscita originale ci sia ancora).\nQuesto non modificherà eventuali cambiamenti apportati alla scena di uscita originale."
58
+QuickTransitions.DuplicateScene="Duplica scena"
59
+QuickTransitions.DuplicateSceneTT="Quando si modifica la stessa scena, permette di modificare la trasformazione/visibilità delle sorgenti senza modificare l'uscita.\nPer modificare le proprietà delle source senza modificare l'uscita, abilità 'Sorgenti duplicate'.\nCambiare questo valore ripristinerà la scena di uscita attuale (se esiste ancora)."
60
 QuickTransitions.EditProperties="Duplica Risorsa"
61
 QuickTransitions.EditPropertiesTT="Quando si modifica la stessa scena, consente la modifica di risorse senza modificarne l'output. \nQuesto può essere usato solo se 'Scene doppia' è attivo. \nCerte risorse (come media o catture) non lo supportano e devono essere modificate separatamente. \nCambiare questo valore resetterà l'attuale scena di output (se esiste ancora). \n\nAttenzione: Dato che la risorsa verrà duplicata, questo potrebbe richiedere risorse di sistema o video aggiuntive."
62
 QuickTransitions.HotkeyName="Transizioni rapide: %1"
63
@@ -69,7 +72,7 @@
64
 Basic.TransitionDuration="Durata"
65
 Basic.TogglePreviewProgramMode="Modalità studio"
66
 
67
-TransitionNameDlg.Text="Per favore inserisci il nome della transizione"
68
+TransitionNameDlg.Text="Inserisci il nome della transizione"
69
 TransitionNameDlg.Title="Nome transizione"
70
 
71
 TitleBar.Profile="Profilo"
72
@@ -81,13 +84,13 @@
73
 NoNameEntered.Title="Inserisci un nome valido"
74
 NoNameEntered.Text="Non è possibile utilizzare nomi vuoti."
75
 
76
-ConfirmStart.Title="Inizia diretta?"
77
+ConfirmStart.Title="Vuoi iniziare la trasmissione?"
78
 ConfirmStart.Text="Sei sicuro di voler iniziare una diretta?"
79
 
80
-ConfirmStop.Title="Interrompere diretta?"
81
-ConfirmStop.Text="Sei sicuro di voler interrompere questa diretta?"
82
+ConfirmStop.Title="Vuoi fermare la trasmissione?"
83
+ConfirmStop.Text="Sei sicuro di voler interrompere questa trasmissione?"
84
 
85
-ConfirmExit.Title="Uscire da OBS?"
86
+ConfirmExit.Title="Vuoi uscire da OBS?"
87
 ConfirmExit.Text="OBS è attualmente attivo. Tutte le dirette/registrazioni saranno fermate. Sei sicuro di voler uscire?"
88
 
89
 ConfirmRemove.Title="Conferma la rimozione"
90
@@ -107,6 +110,8 @@
91
 Output.RecordNoSpace.Msg="Non c'è abbastanza spazio su disco per continuazre la registrazione."
92
 Output.RecordError.Title="Errore di registrazione"
93
 Output.RecordError.Msg="Si è verificato un errore non specificato durante la registrazione."
94
+Output.ReplayBuffer.NoHotkey.Title="Nessuna scorciatoia assegnata!"
95
+Output.ReplayBuffer.NoHotkey.Msg="Nessuna scorciatoia impostata per salvare il buffer di replay. Impostare la scorciatoia \"Salva\" per poter salvare le registrazioni in replay."
96
 
97
 Output.BadPath.Title="Percorso di file invalido"
98
 Output.BadPath.Text="Il percorso configurato per il file di output non è valido. Controlla le tue impostazioni per confermare che un percorso di file valido è stato impostato."
99
@@ -127,8 +132,8 @@
100
 Remux.OBSRecording="Registrazione OBS"
101
 Remux.FinishedTitle="Conversione finita"
102
 Remux.Finished="Registrazione convertita"
103
-Remux.FinishedError="Registrazione convertita, ma il file potrebbe essere incompleta"
104
-Remux.SelectRecording="Selezionare registrazione OBS …"
105
+Remux.FinishedError="Registrazione convertita, ma il file potrebbe essere incompleto"
106
+Remux.SelectRecording="Selezionare registrazione OBS…"
107
 Remux.SelectTarget="Selezionare il file di destinazione…"
108
 Remux.FileExistsTitle="Il file di destinazione esiste"
109
 Remux.FileExists="Il file di destinazione esiste, si desidera sostituirlo?"
110
@@ -148,7 +153,7 @@
111
 Basic.Scene="Scena"
112
 Basic.DisplayCapture="Mostra cattura"
113
 
114
-Basic.Main.PreviewConextMenu.Enable="Abilita Anteprima"
115
+Basic.Main.PreviewConextMenu.Enable="Abilita anteprima"
116
 
117
 ScaleFiltering="Scala di filtraggio"
118
 ScaleFiltering.Point="Punto"
119
@@ -262,9 +267,12 @@
120
 Basic.Main.Sources="Origini"
121
 Basic.Main.Connecting="Connessione..."
122
 Basic.Main.StartRecording="Avvia registrazione"
123
+Basic.Main.StartReplayBuffer="Avvia Buffer di Replay"
124
 Basic.Main.StartStreaming="Avvia trasmissione"
125
 Basic.Main.StopRecording="Ferma registrazione"
126
 Basic.Main.StoppingRecording="Fermando la registrazione..."
127
+Basic.Main.StopReplayBuffer="Termina Buffer di Replay"
128
+Basic.Main.StoppingReplayBuffer="Fermando il Buffer di Replay..."
129
 Basic.Main.StopStreaming="Ferma trasmissione"
130
 Basic.Main.StoppingStreaming="Arresto diretta..."
131
 Basic.Main.ForceStopStreaming="Ferma Diretta (annulla ritardo)"
132
@@ -278,20 +286,22 @@
133
 Basic.MainMenu.File.ShowSettingsFolder="Visualizza cartella impostazioni"
134
 Basic.MainMenu.File.ShowProfileFolder="Mostra la cartella del profilo"
135
 Basic.MainMenu.AlwaysOnTop="&Sempre in primo piano"
136
-Basic.MainMenu.File.Exit="Esci (&X)"
137
+Basic.MainMenu.File.Exit="E&sci"
138
 
139
 Basic.MainMenu.Edit="&Modifica"
140
 Basic.MainMenu.Edit.Undo="&Annulla"
141
 Basic.MainMenu.Edit.Redo="&Ripristina"
142
 Basic.MainMenu.Edit.UndoAction="&Ripristina $1"
143
 Basic.MainMenu.Edit.RedoAction="&Ripristina $1"
144
-Basic.MainMenu.Edit.LockPreview="&Blocca Anteprima"
145
-Basic.MainMenu.Edit.Scale="Anteprima & ridimensionamento"
146
+Basic.MainMenu.Edit.LockPreview="&Blocca anteprima"
147
+Basic.MainMenu.Edit.Scale="Anteprima ridimen&sionamento"
148
 Basic.MainMenu.Edit.Scale.Window="Scala alla finestra"
149
 Basic.MainMenu.Edit.Scale.Canvas="Tela (%1x%2)"
150
 Basic.MainMenu.Edit.Scale.Output="Uscita (%1x%2)"
151
 Basic.MainMenu.Edit.Transform="&Trasforma"
152
 Basic.MainMenu.Edit.Transform.EditTransform="&Modifica e trasforma..."
153
+Basic.MainMenu.Edit.Transform.CopyTransform="Copia Trasformazione"
154
+Basic.MainMenu.Edit.Transform.PasteTransform="Incolla Trasformazione"
155
 Basic.MainMenu.Edit.Transform.ResetTransform="&Reset e trasforma"
156
 Basic.MainMenu.Edit.Transform.Rotate90CW="Ruota di 90 gradi DW"
157
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Ruota di 90 gradi CCW"
158
@@ -306,7 +316,7 @@
159
 Basic.MainMenu.Edit.Order.MoveDown="Sposta in &basso"
160
 Basic.MainMenu.Edit.Order.MoveToTop="Sposta in &primo piano"
161
 Basic.MainMenu.Edit.Order.MoveToBottom="Sposta in &fondo"
162
-Basic.MainMenu.Edit.AdvAudio="Proprietà Audio &Avanzate"
163
+Basic.MainMenu.Edit.AdvAudio="Proprietà audio &avanzate"
164
 
165
 Basic.MainMenu.View="&Visualizza"
166
 Basic.MainMenu.View.Toolbars="&Barre degli strumenti"
167
@@ -316,10 +326,16 @@
168
 
169
 Basic.MainMenu.SceneCollection="&Collezione scene"
170
 Basic.MainMenu.Profile="&Profilo"
171
+Basic.MainMenu.Profile.Import="Importa profilo"
172
+Basic.MainMenu.Profile.Export="Esporta profilo"
173
+Basic.MainMenu.SceneCollection.Import="Importa collezione scene"
174
+Basic.MainMenu.SceneCollection.Export="Esporta collezione scene"
175
+Basic.MainMenu.Profile.Exists="Il profilo esiste già"
176
+Basic.MainMenu.SceneCollection.Exists="La collezione di scene già esiste"
177
 
178
 Basic.MainMenu.Tools="&Strumenti"
179
 
180
-Basic.MainMenu.Help="Aiuto (&H)"
181
+Basic.MainMenu.Help="&Aiuto"
182
 Basic.MainMenu.Help.Website="Visita il sito"
183
 Basic.MainMenu.Help.Logs="File di &log"
184
 Basic.MainMenu.Help.Logs.ShowLogs="&Visualizza i file di Log"
185
@@ -362,6 +378,14 @@
186
 Basic.Settings.Output.Mode.Simple="Semplice"
187
 Basic.Settings.Output.Mode.Adv="Avanzate"
188
 Basic.Settings.Output.Mode.FFmpeg="Uscita FFmpeg"
189
+Basic.Settings.Output.UseReplayBuffer="Abilita il Buffer di Replay"
190
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo massimo di Replay (Secondi)"
191
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memoria Massima (Megabytes)"
192
+Basic.Settings.Output.ReplayBuffer.Estimate="Uso della memoria stimato: %1 MB"
193
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossibile stimare la memoria utilizzata. Impostare un limite massimo di memoria."
194
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Assicurati di aver impostato una hotkey per il Buffer di Replay nella sezione delle hotkeys)"
195
+Basic.Settings.Output.ReplayBuffer.Prefix="Prefisso del file per i Buffer di Replay"
196
+Basic.Settings.Output.ReplayBuffer.Suffix="Suffisso"
197
 Basic.Settings.Output.Simple.SavePath="Percorso registrazione"
198
 Basic.Settings.Output.Simple.RecordingQuality="Qualità della registrazione"
199
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Stesso della diretta"
200
@@ -399,13 +423,15 @@
201
 Basic.Settings.Output.Adv.Audio.Track2="Traccia 2"
202
 Basic.Settings.Output.Adv.Audio.Track3="Traccia 3"
203
 Basic.Settings.Output.Adv.Audio.Track4="Traccia 4"
204
+Basic.Settings.Output.Adv.Audio.Track5="Traccia 5"
205
+Basic.Settings.Output.Adv.Audio.Track6="Traccia 6"
206
 
207
 Basic.Settings.Output.Adv.Recording="Registrazione"
208
 Basic.Settings.Output.Adv.Recording.Type="Tipo"
209
 Basic.Settings.Output.Adv.Recording.Type.Standard="Standard"
210
 Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Output personalizzato (FFmpeg)"
211
 Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utilizzare il codificatore del flusso)"
212
-Basic.Settings.Output.Adv.Recording.Filename="Formattazione del nome del file"
213
+Basic.Settings.Output.Adv.Recording.Filename="Formattazione nome del file"
214
 Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Sovrascrivi il file se già esistente"
215
 Basic.Settings.Output.Adv.FFmpeg.Type="Tipo di Output FFmpeg"
216
 Basic.Settings.Output.Adv.FFmpeg.Type.URL="Output in URL"
217
@@ -486,7 +512,7 @@
218
 Basic.Settings.Advanced.Network="Rete"
219
 Basic.Settings.Advanced.Network.BindToIP="Associa a IP"
220
 
221
-Basic.AdvAudio="Proprietà Audio Avanzate"
222
+Basic.AdvAudio="Proprietà audio avanzate"
223
 Basic.AdvAudio.Name="Nome"
224
 Basic.AdvAudio.Volume="Volume (%)"
225
 Basic.AdvAudio.Mono="Downmix to Mono"
226
obs-studio-0.17.0.tar.xz/UI/data/locale/pt-BR.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/pt-BR.ini Changed
87
 
1
@@ -52,6 +52,9 @@
2
 Hours="Horas"
3
 Minutes="Minutos"
4
 Seconds="Segundos"
5
+Deprecated="Obsoleto"
6
+ReplayBuffer="Buffer do Replay"
7
+Export="Exportar"
8
 
9
 QuickTransitions.SwapScenes="Trocar Cenas de Prévia/Saída após a Transição"
10
 QuickTransitions.SwapScenesTT="Troca a preview e a saída após transicionar (se a a cena original de saída ainda exisitr).\nIsto não irá desfazer nenhuma mudança que foi feita na cena original da saída."
11
@@ -106,6 +109,8 @@
12
 Output.RecordNoSpace.Msg="Não há espaço em disco suficiente para continuar a gravação."
13
 Output.RecordError.Title="Erro de gravação"
14
 Output.RecordError.Msg="Ocorreu um erro não especificado durante a gravação."
15
+Output.ReplayBuffer.NoHotkey.Title="Tecla de Atalho não configurada!"
16
+Output.ReplayBuffer.NoHotkey.Msg="Tecla de Atalho para salvar o Buffer do replay não definida. Por favor, configure uma tecla de atalho para salvar gravações de replays."
17
 
18
 Output.BadPath.Title="Caminho de Arquivo Inválido"
19
 Output.BadPath.Text="O caminho do arquivo de saída é inválido. Por Favor, certifique-se de que um caminho válido foi informado."
20
@@ -153,6 +158,7 @@
21
 ScaleFiltering.Point="Ponto"
22
 ScaleFiltering.Bilinear="Bilinear"
23
 ScaleFiltering.Bicubic="Bicúbico"
24
+ScaleFiltering.Lanczos="Lanczos"
25
 
26
 Deinterlacing="Desentrelaçamento"
27
 Deinterlacing.Discard="Descartar"
28
@@ -260,9 +266,12 @@
29
 Basic.Main.Sources="Fontes"
30
 Basic.Main.Connecting="Conectando..."
31
 Basic.Main.StartRecording="Iniciar gravação"
32
+Basic.Main.StartReplayBuffer="Iniciar Buffer do Replay"
33
 Basic.Main.StartStreaming="Iniciar Transmissão"
34
 Basic.Main.StopRecording="Parar Gravação"
35
 Basic.Main.StoppingRecording="Parando de Gravar..."
36
+Basic.Main.StopReplayBuffer="Parar Buffer do Replay"
37
+Basic.Main.StoppingReplayBuffer="Parando Buffer do Replay..."
38
 Basic.Main.StopStreaming="Parar Transmissão"
39
 Basic.Main.StoppingStreaming="Parando Transmissão..."
40
 Basic.Main.ForceStopStreaming="Pare de transmitir (descartar atraso)"
41
@@ -290,6 +299,8 @@
42
 Basic.MainMenu.Edit.Scale.Output="Saída (%1x%2)"
43
 Basic.MainMenu.Edit.Transform="&Transformar"
44
 Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformação..."
45
+Basic.MainMenu.Edit.Transform.CopyTransform="Copiar Transformação"
46
+Basic.MainMenu.Edit.Transform.PasteTransform="Colar Transformação"
47
 Basic.MainMenu.Edit.Transform.ResetTransform="&Limpar Transformação"
48
 Basic.MainMenu.Edit.Transform.Rotate90CW="Girar 90º sentido Horário"
49
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Girar 90º sentido Anti-Horário"
50
@@ -314,6 +325,12 @@
51
 
52
 Basic.MainMenu.SceneCollection="&Coleção de cena"
53
 Basic.MainMenu.Profile="&Perfil"
54
+Basic.MainMenu.Profile.Import="Importar Perfil"
55
+Basic.MainMenu.Profile.Export="Exportar Perfil"
56
+Basic.MainMenu.SceneCollection.Import="Importar Grupo de Cenas"
57
+Basic.MainMenu.SceneCollection.Export="Exportar Grupo de Cenas"
58
+Basic.MainMenu.Profile.Exists="Perfil já existe"
59
+Basic.MainMenu.SceneCollection.Exists="O Grupo de Cenas já existe"
60
 
61
 Basic.MainMenu.Tools="Ferramentas (&T)"
62
 
63
@@ -360,6 +377,14 @@
64
 Basic.Settings.Output.Mode.Simple="Simples"
65
 Basic.Settings.Output.Mode.Adv="Avançado"
66
 Basic.Settings.Output.Mode.FFmpeg="Saída de FFmpeg"
67
+Basic.Settings.Output.UseReplayBuffer="Habilitar Buffer de Repetição"
68
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo de Replay máximo (Segundos)"
69
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memória Máxima (Megabytes)"
70
+Basic.Settings.Output.ReplayBuffer.Estimate="Uso de memória estimado: %1 MB"
71
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossível estimar o uso de memória. Por favor, defina o limite máximo de memória."
72
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Não se esqueça de configurar uma Tecla de Atalho para o Buffer de Replay na seção Teclas de Atalhos)"
73
+Basic.Settings.Output.ReplayBuffer.Prefix="Prefixo do Buffer de Repetição"
74
+Basic.Settings.Output.ReplayBuffer.Suffix="Sufixo"
75
 Basic.Settings.Output.Simple.SavePath="Caminho de gravação"
76
 Basic.Settings.Output.Simple.RecordingQuality="Qualidade da gravação"
77
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Mesmo que a stream"
78
@@ -397,6 +422,8 @@
79
 Basic.Settings.Output.Adv.Audio.Track2="Faixa 2"
80
 Basic.Settings.Output.Adv.Audio.Track3="Faixa 3"
81
 Basic.Settings.Output.Adv.Audio.Track4="Faixa 4"
82
+Basic.Settings.Output.Adv.Audio.Track5="Faixa 5"
83
+Basic.Settings.Output.Adv.Audio.Track6="Faixa 6"
84
 
85
 Basic.Settings.Output.Adv.Recording="Gravação"
86
 Basic.Settings.Output.Adv.Recording.Type="Tipo"
87
obs-studio-0.17.0.tar.xz/UI/data/locale/ru-RU.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/ru-RU.ini Changed
83
 
1
@@ -52,6 +52,10 @@
2
 Hours="Часов"
3
 Minutes="Минут"
4
 Seconds="Секунд"
5
+Deprecated="Устаревшее"
6
+ReplayBuffer="Буфер повтора"
7
+Import="Импорт"
8
+Export="Экспорт"
9
 
10
 QuickTransitions.SwapScenes="Замена Просмотра/Вывода Сцены После Перехода"
11
 QuickTransitions.SwapScenesTT="Замена просмотра и вывода сцены после перехода (если выходная оригинальная сцена до сих пор существует).\nЭто будет не отмена каких-либо изменений, что, возможно, было сделано в выходной оригинальной сцены."
12
@@ -107,6 +111,7 @@
13
 Output.RecordError.Title="Ошибка записи"
14
 Output.RecordError.Msg="Во время записи произошла неопознанная ошибка."
15
 Output.ReplayBuffer.NoHotkey.Title="Нет набора горячих клавиш!"
16
+Output.ReplayBuffer.NoHotkey.Msg="Не установлено клавиши для сохранения повтора. Пожалуйста, установите горячую клавишу для сохранения записей повторов."
17
 
18
 Output.BadPath.Title="Неправильный путь к файлу"
19
 Output.BadPath.Text="Некорректный путь к файлу.  Пожалуйста, проверьте настройки, чтобы убедиться в корректности установленного пути."
20
@@ -262,9 +267,12 @@
21
 Basic.Main.Sources="Источники"
22
 Basic.Main.Connecting="Соединение..."
23
 Basic.Main.StartRecording="Начать запись"
24
+Basic.Main.StartReplayBuffer="Запустить повтор"
25
 Basic.Main.StartStreaming="Запустить трансляцию"
26
 Basic.Main.StopRecording="Остановить запись"
27
 Basic.Main.StoppingRecording="Остановка Записи..."
28
+Basic.Main.StopReplayBuffer="Остановить повтор"
29
+Basic.Main.StoppingReplayBuffer="Остановка повтора..."
30
 Basic.Main.StopStreaming="Остановить трансляцию"
31
 Basic.Main.StoppingStreaming="Остановка вещания..."
32
 Basic.Main.ForceStopStreaming="Остановить передачу (отменить задержку)"
33
@@ -288,8 +296,12 @@
34
 Basic.MainMenu.Edit.LockPreview="&Заблокировать предпросмотр"
35
 Basic.MainMenu.Edit.Scale="Просмотр и масштабирование"
36
 Basic.MainMenu.Edit.Scale.Window="Масштаб окна"
37
+Basic.MainMenu.Edit.Scale.Canvas="Холст (%1x%2)"
38
+Basic.MainMenu.Edit.Scale.Output="Вывод (%1x%2)"
39
 Basic.MainMenu.Edit.Transform="&Преобразовать"
40
 Basic.MainMenu.Edit.Transform.EditTransform="&Изменить преобразование..."
41
+Basic.MainMenu.Edit.Transform.CopyTransform="Копировать преобразование"
42
+Basic.MainMenu.Edit.Transform.PasteTransform="Вставить преобразование"
43
 Basic.MainMenu.Edit.Transform.ResetTransform="&Сбросить преобразование"
44
 Basic.MainMenu.Edit.Transform.Rotate90CW="Повернуть на 90 градусов по часовой"
45
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Повернуть на 90 градусов против часовой"
46
@@ -314,6 +326,12 @@
47
 
48
 Basic.MainMenu.SceneCollection="Коллекция сцен"
49
 Basic.MainMenu.Profile="Профиль"
50
+Basic.MainMenu.Profile.Import="Импортировать профиль"
51
+Basic.MainMenu.Profile.Export="Экспортировать профиль"
52
+Basic.MainMenu.SceneCollection.Import="Импортировать коллекцию сцен"
53
+Basic.MainMenu.SceneCollection.Export="Экспортировать коллекцию сцен"
54
+Basic.MainMenu.Profile.Exists="Профиль уже существует"
55
+Basic.MainMenu.SceneCollection.Exists="Коллекция сцен уже существует"
56
 
57
 Basic.MainMenu.Tools="&Инструменты"
58
 
59
@@ -360,8 +378,14 @@
60
 Basic.Settings.Output.Mode.Simple="Простой"
61
 Basic.Settings.Output.Mode.Adv="Расширенные"
62
 Basic.Settings.Output.Mode.FFmpeg="Вывод FFmpeg"
63
+Basic.Settings.Output.UseReplayBuffer="Включить Буфер повтора"
64
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимальное время повтора (секунд)"
65
+Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимальный объем памяти (МБ)"
66
 Basic.Settings.Output.ReplayBuffer.Estimate="Предполагаемое использование памяти: %1 МБ"
67
 Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Невозможно оценить использование памяти.  Пожалуйста, установите максимальный объем памяти."
68
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Примечание: Убедитесь, что установили горячую клавишу для воспроизведения буфера в разделе горячие клавиши)"
69
+Basic.Settings.Output.ReplayBuffer.Prefix="Префикс имени файла повтора"
70
+Basic.Settings.Output.ReplayBuffer.Suffix="Суффикс"
71
 Basic.Settings.Output.Simple.SavePath="Путь к записи"
72
 Basic.Settings.Output.Simple.RecordingQuality="Качество записи"
73
 Basic.Settings.Output.Simple.RecordingQuality.Stream="То же, что у трансляции"
74
@@ -399,6 +423,8 @@
75
 Basic.Settings.Output.Adv.Audio.Track2="Дорожка 2"
76
 Basic.Settings.Output.Adv.Audio.Track3="Дорожка 3"
77
 Basic.Settings.Output.Adv.Audio.Track4="Дорожка 4"
78
+Basic.Settings.Output.Adv.Audio.Track5="Дорожка 5"
79
+Basic.Settings.Output.Adv.Audio.Track6="Дорожка 6"
80
 
81
 Basic.Settings.Output.Adv.Recording="Запись"
82
 Basic.Settings.Output.Adv.Recording.Type="Тип"
83
obs-studio-0.17.0.tar.xz/UI/data/locale/sv-SE.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/sv-SE.ini Changed
78
 
1
@@ -53,6 +53,9 @@
2
 Minutes="minuter"
3
 Seconds="sekunder"
4
 Deprecated="Föråldrat"
5
+ReplayBuffer="Reprisbuffert"
6
+Import="Importera"
7
+Export="Exportera"
8
 
9
 QuickTransitions.SwapScenes="Byt plats på Förhandsvisnings-/utdatascenerna efter skifte"
10
 QuickTransitions.SwapScenesTT="Byter plats på förhandsvisnings- och utdatascenerna efter övergång (om utdatans originalscen fortfarande finns). \nDet här kommer inte att ångra några förändringar i utdatans originalscen."
11
@@ -108,6 +111,7 @@
12
 Output.RecordError.Title="Inspelningsfel"
13
 Output.RecordError.Msg="Ett okänt fel uppstod vid inspelning."
14
 Output.ReplayBuffer.NoHotkey.Title="Ingen angivet kortkommando!"
15
+Output.ReplayBuffer.NoHotkey.Msg="Inget kortkommando för att spara reprisbufferten har angivits. Ange kortkommandot \"Spara\" för att kunna spara reprisinspelningar."
16
 
17
 Output.BadPath.Title="Ogiltig sökväg"
18
 Output.BadPath.Text="Den angivna sökvägen för utmatningsfil är ogiltig. Kontrollera att dina inställningar är korrekta och att en giltig sökväg har angetts."
19
@@ -263,9 +267,12 @@
20
 Basic.Main.Sources="Källor"
21
 Basic.Main.Connecting="Ansluter..."
22
 Basic.Main.StartRecording="Starta inspelning"
23
+Basic.Main.StartReplayBuffer="Starta reprisbuffert"
24
 Basic.Main.StartStreaming="Börja strömma"
25
 Basic.Main.StopRecording="Stoppa inspelning"
26
 Basic.Main.StoppingRecording="Stoppar inspelning..."
27
+Basic.Main.StopReplayBuffer="Stoppa reprisbuffert"
28
+Basic.Main.StoppingReplayBuffer="Stoppar reprisbuffert..."
29
 Basic.Main.StopStreaming="Sluta strömma"
30
 Basic.Main.StoppingStreaming="Stoppar ström..."
31
 Basic.Main.ForceStopStreaming="Sluta strömma (ignorera fördröjning)"
32
@@ -293,6 +300,8 @@
33
 Basic.MainMenu.Edit.Scale.Output="Utmatning (%1x%2)"
34
 Basic.MainMenu.Edit.Transform="&Omvandla"
35
 Basic.MainMenu.Edit.Transform.EditTransform="&Redigera omvandling..."
36
+Basic.MainMenu.Edit.Transform.CopyTransform="Kopiera transformering"
37
+Basic.MainMenu.Edit.Transform.PasteTransform="Klistra in transformering"
38
 Basic.MainMenu.Edit.Transform.ResetTransform="&Återställ omvandling"
39
 Basic.MainMenu.Edit.Transform.Rotate90CW="Rotera 90 grader medsols &>"
40
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotera 90 grader motsols &<"
41
@@ -317,6 +326,12 @@
42
 
43
 Basic.MainMenu.SceneCollection="&Scensamling"
44
 Basic.MainMenu.Profile="&Profil"
45
+Basic.MainMenu.Profile.Import="Importera profil"
46
+Basic.MainMenu.Profile.Export="Exportera profil"
47
+Basic.MainMenu.SceneCollection.Import="Importera scensamling"
48
+Basic.MainMenu.SceneCollection.Export="Exportera scensamling"
49
+Basic.MainMenu.Profile.Exists="Profilen finns redan"
50
+Basic.MainMenu.SceneCollection.Exists="Scensamlingen finns redan"
51
 
52
 Basic.MainMenu.Tools="&Verktyg"
53
 
54
@@ -363,8 +378,14 @@
55
 Basic.Settings.Output.Mode.Simple="Simpel"
56
 Basic.Settings.Output.Mode.Adv="Avancerat"
57
 Basic.Settings.Output.Mode.FFmpeg="FFmpeg-utmatning"
58
+Basic.Settings.Output.UseReplayBuffer="Aktivera reprisbuffert"
59
+Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximal repristid (sekunder)"
60
 Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximalt minne (Megabyte)"
61
 Basic.Settings.Output.ReplayBuffer.Estimate="Uppskattad minnesanvändning: %1 MB"
62
+Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Kan inte uppskatta minnesanvändningen. Ange maximal minnesgräns."
63
+Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(OBS: Se till att ange ett kortkommando för reprisbufferten i avsnittet för kortkommandon)"
64
+Basic.Settings.Output.ReplayBuffer.Prefix="Filnamnsprefix för reprisbuffert"
65
+Basic.Settings.Output.ReplayBuffer.Suffix="Suffix"
66
 Basic.Settings.Output.Simple.SavePath="Inspelningssökväg"
67
 Basic.Settings.Output.Simple.RecordingQuality="Inspelningskvalitet"
68
 Basic.Settings.Output.Simple.RecordingQuality.Stream="Samma som ström"
69
@@ -402,6 +423,8 @@
70
 Basic.Settings.Output.Adv.Audio.Track2="Spår 2"
71
 Basic.Settings.Output.Adv.Audio.Track3="Spår 3"
72
 Basic.Settings.Output.Adv.Audio.Track4="Spår 4"
73
+Basic.Settings.Output.Adv.Audio.Track5="Spår 5"
74
+Basic.Settings.Output.Adv.Audio.Track6="Spår 6"
75
 
76
 Basic.Settings.Output.Adv.Recording="Inspelning"
77
 Basic.Settings.Output.Adv.Recording.Type="Typ"
78
obs-studio-0.17.0.tar.xz/UI/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/tr-TR.ini Changed
36
 
1
@@ -40,6 +40,7 @@
2
 Duplicate="Çoğalt"
3
 Enable="Etkinleştir"
4
 DisableOSXVSync="OSX V-Sync Devre Dışı Bırakma"
5
+ResetOSXVSyncOnExit="OSX V-Sync'i Çıkışta Sıfırla"
6
 HighResourceUsage="Kodlama aşırı yüklendi!  Video ayarlarını kapatmayı veya daha hızlı bir kodlama ön ayarını kullanmayı düşünün."
7
 Transition="Geçiş"
8
 QuickTransitions="Hızlı Geçiş"
9
@@ -169,7 +170,7 @@
10
 Basic.Main.AddSceneDlg.Title="Sahne Ekle"
11
 Basic.Main.AddSceneDlg.Text="Lütfen sahne adını giriniz"
12
 
13
-Basic.Main.DefaultSceneName.Text="%1 Sahnesi"
14
+Basic.Main.DefaultSceneName.Text="Sahne %1"
15
 
16
 Basic.Main.AddSceneCollection.Title="Sahne Koleksiyonu Ekle"
17
 Basic.Main.AddSceneCollection.Text="Sahne koleksiyonunun isimini giriniz"
18
@@ -460,6 +461,9 @@
19
 Basic.Settings.Video.CurrentlyActive="Video çıkışı şu anda etkin durumda.  Video ayarlarını değiştirmek için lütfen bütün çıkışları kapalı duruma getirin."
20
 Basic.Settings.Video.DisableAero="Aero'yu Devre Dışı Bırak"
21
 
22
+Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (En hızlı, ancak boyutlandırmada bulanık görüntü)"
23
+Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Keskinleştirilmiş boyutlandırma, 16 örnek)"
24
+Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Keskinleştirilmiş boyutlandırma, 32 örnek)"
25
 
26
 Basic.Settings.Audio="Ses"
27
 Basic.Settings.Audio.SampleRate="Örnekleme Sıklığı"
28
@@ -550,6 +554,7 @@
29
 
30
 Mute="Sesi Kapat"
31
 Unmute="Sesi Aç"
32
+Push-to-mute="Bas-Sessize Al"
33
 Push-to-talk="Bas konuş"
34
 
35
 SceneItemShow="'%1' Göster"
36
obs-studio-0.17.0.tar.xz/UI/data/locale/uk-UA.ini -> obs-studio-17.0.1.tar.xz/UI/data/locale/uk-UA.ini Changed
32
 
1
@@ -300,6 +300,8 @@
2
 Basic.MainMenu.Edit.Scale.Output="Як Вивід (%1x%2)"
3
 Basic.MainMenu.Edit.Transform="&Розміри"
4
 Basic.MainMenu.Edit.Transform.EditTransform="Редагуват&и Розміри..."
5
+Basic.MainMenu.Edit.Transform.CopyTransform="Копіювати Розміри"
6
+Basic.MainMenu.Edit.Transform.PasteTransform="Вставити Розміри"
7
 Basic.MainMenu.Edit.Transform.ResetTransform="Розміри за &замовчуванням"
8
 Basic.MainMenu.Edit.Transform.Rotate90CW="Повернути на 90 За годинниковою стрілкою"
9
 Basic.MainMenu.Edit.Transform.Rotate90CCW="Повернути на 90 Проти годинникової стрілки"
10
@@ -324,6 +326,12 @@
11
 
12
 Basic.MainMenu.SceneCollection="&Набір Сцен"
13
 Basic.MainMenu.Profile="&Профіль"
14
+Basic.MainMenu.Profile.Import="Імпорт Профілю"
15
+Basic.MainMenu.Profile.Export="Експорт Профілю"
16
+Basic.MainMenu.SceneCollection.Import="Імпорт Набору Сцен"
17
+Basic.MainMenu.SceneCollection.Export="Експорт Набору Сцен"
18
+Basic.MainMenu.Profile.Exists="Профіль вже існує"
19
+Basic.MainMenu.SceneCollection.Exists="Набір Сцен вже існує"
20
 
21
 Basic.MainMenu.Tools="Додаткові &засоби"
22
 
23
@@ -415,6 +423,8 @@
24
 Basic.Settings.Output.Adv.Audio.Track2="Доріжка 2"
25
 Basic.Settings.Output.Adv.Audio.Track3="Доріжка 3"
26
 Basic.Settings.Output.Adv.Audio.Track4="Доріжка 4"
27
+Basic.Settings.Output.Adv.Audio.Track5="Доріжка 5"
28
+Basic.Settings.Output.Adv.Audio.Track6="Доріжка 6"
29
 
30
 Basic.Settings.Output.Adv.Recording="Запис"
31
 Basic.Settings.Output.Adv.Recording.Type="Тип"
32
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini Changed
17
 
1
@@ -11,10 +11,15 @@
2
 Start="Inicia"
3
 Stop="Atura"
4
 
5
+Captions="Subtítols (Experimental)"
6
+Captions.AudioSource="Font d'àudio"
7
+Captions.CurrentSystemLanguage="Idioma actual del sistema (%1)"
8
 
9
 OutputTimer="Temporitzador de sortida"
10
 OutputTimer.Stream="Atura la transmissió després de:"
11
 OutputTimer.Record="Atura la gravació després de:"
12
 OutputTimer.Stream.StoppingIn="La transmissió s'aturarà en:"
13
 OutputTimer.Record.StoppingIn="La gravació s'aturarà en:"
14
+OutputTimer.Stream.EnableEverytime="Activa el temporitzador en cada transmissió"
15
+OutputTimer.Record.EnableEverytime="Activa el temporitzador en cada enregistrament"
16
 
17
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Spustit"
3
 Stop="Zastavit"
4
 
5
+Captions="Titulky (experiment.)"
6
+Captions.AudioSource="Zdroj zvuku"
7
+Captions.CurrentSystemLanguage="Aktuální systémový jazyk (%1)"
8
 
9
 OutputTimer="Časovač"
10
 OutputTimer.Stream="Přestat vysílat po:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini Changed
11
 
1
@@ -12,7 +12,8 @@
2
 Stop="Stop"
3
 
4
 Captions="Untertitel (experimentell)"
5
-Captions.AudioSource="Audioquelle:"
6
+Captions.AudioSource="Audioquelle"
7
+Captions.CurrentSystemLanguage="Aktuelle Systemsprache (%1)"
8
 
9
 OutputTimer="Ausgabetimer"
10
 OutputTimer.Stream="Stoppe Stream nach:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Iniciar"
3
 Stop="Detener"
4
 
5
+Captions="Subtítulos (Experimental)"
6
+Captions.AudioSource="Fuente de audio"
7
+Captions.CurrentSystemLanguage="Idioma actual del sistema (%1)"
8
 
9
 OutputTimer="Temporizador de salida"
10
 OutputTimer.Stream="Detener la transmisión después de:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Hasi"
3
 Stop="Gelditu"
4
 
5
+Captions="Epigrafeak (esperimentala)"
6
+Captions.AudioSource="Audio-iturburua"
7
+Captions.CurrentSystemLanguage="Sistemaren hizkuntza (%1)"
8
 
9
 OutputTimer="Irteera tenporizadorea"
10
 OutputTimer.Stream="Gelditu transmisioa hau pasata:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/fi-FI.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/fi-FI.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Käynnistä"
3
 Stop="Pysäytä"
4
 
5
+Captions="Kuvatekstit (Experimental)"
6
+Captions.AudioSource="Äänilähde"
7
+Captions.CurrentSystemLanguage="Järjestelmän kieli (%1)"
8
 
9
 OutputTimer="Ulostulo-ajastin"
10
 OutputTimer.Stream="Pysäyttää lähetyksen:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Démarrer"
3
 Stop="Arrêter"
4
 
5
+Captions="Sous-titres (expérimental)"
6
+Captions.AudioSource="Source audio"
7
+Captions.CurrentSystemLanguage="Langue du système (%1)"
8
 
9
 OutputTimer="Minuterie des sorties"
10
 OutputTimer.Stream="Arrêter le streaming dans :"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Start"
3
 Stop="Stop"
4
 
5
+Captions="Feliratok (Kísérleti)"
6
+Captions.AudioSource="Audio forrás"
7
+Captions.CurrentSystemLanguage="Rendszer aktuális nyelve (%1)"
8
 
9
 OutputTimer="Kimeneti időzítő"
10
 OutputTimer.Stream="Stream leállítása:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini Changed
17
 
1
@@ -11,10 +11,15 @@
2
 Start="Inizio"
3
 Stop="Stop"
4
 
5
+Captions="Sottotitoli (Sperimentale)"
6
+Captions.AudioSource="Fonte audio"
7
+Captions.CurrentSystemLanguage="Lingua del sistema in uso (%1)"
8
 
9
 OutputTimer="Timer Output"
10
 OutputTimer.Stream="Termina diretta dopo:"
11
 OutputTimer.Record="Termina registrazione dopo:"
12
 OutputTimer.Stream.StoppingIn="La diretta terminerà in:"
13
 OutputTimer.Record.StoppingIn="La registrazione terminerà in:"
14
+OutputTimer.Stream.EnableEverytime="Abilita il timer per lo streaming ogni volta"
15
+OutputTimer.Record.EnableEverytime="Abilita il timer per la registrazione ogni volta"
16
 
17
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="開始"
3
 Stop="停止"
4
 
5
+Captions="見出し (実験的)"
6
+Captions.AudioSource="音声ソース"
7
+Captions.CurrentSystemLanguage="現在のシステム言語 (%1)"
8
 
9
 OutputTimer="出力タイマー"
10
 OutputTimer.Stream="配信停止の時間設定:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="시작"
3
 Stop="중단"
4
 
5
+Captions="자막 (실험적 기능)"
6
+Captions.AudioSource="오디오 소스"
7
+Captions.CurrentSystemLanguage="현재 시스템 언어 (%1)"
8
 
9
 OutputTimer="출력 시간 설정"
10
 OutputTimer.Stream="이 시간 이후 방송 중단:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Start"
3
 Stop="Stop"
4
 
5
+Captions="Ondertiteling (Experimenteel)"
6
+Captions.AudioSource="Audiobron"
7
+Captions.CurrentSystemLanguage="Huidige Systeemtaal (%1)"
8
 
9
 OutputTimer="Uitvoertimer"
10
 OutputTimer.Stream="Stop met streamen na:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Start"
3
 Stop="Stop"
4
 
5
+Captions="Podpisy (eksperymentalne)"
6
+Captions.AudioSource="Źródła dźwięku"
7
+Captions.CurrentSystemLanguage="Obecny język systemu (%1)"
8
 
9
 OutputTimer="Wyłącznik czasowy"
10
 OutputTimer.Stream="Zatrzymaj stream po:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Запустить"
3
 Stop="Остановить"
4
 
5
+Captions="Субтитры (экспериментально)"
6
+Captions.AudioSource="Источник звука"
7
+Captions.CurrentSystemLanguage="Текущий язык системы (%1)"
8
 
9
 OutputTimer="Таймер записи и стрима"
10
 OutputTimer.Stream="Завершить стрим через:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Starta"
3
 Stop="Stoppa"
4
 
5
+Captions="Undertexter (experimentell)"
6
+Captions.AudioSource="Ljudkälla"
7
+Captions.CurrentSystemLanguage="Aktuellt systemspråk (%1)"
8
 
9
 OutputTimer="Utdatatimer"
10
 OutputTimer.Stream="Sluta streama efter:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini Changed
27
 
1
@@ -1,17 +1,25 @@
2
 SceneSwitcher="Otomatik Sahne Değiştirici"
3
+SceneSwitcher.OnNoMatch="Hiçbir pencere ile eşleşmez ise:"
4
 SceneSwitcher.OnNoMatch.DontSwitch="Geçiş yapma"
5
 SceneSwitcher.OnNoMatch.SwitchTo="Şuna geç:"
6
 SceneSwitcher.CheckInterval="Etkin pencere başlığını kontrol et:"
7
 SceneSwitcher.ActiveOrNotActive="Sahne Değiştirici:"
8
+InvalidRegex.Title="Geçersiz Kurallı İfade"
9
+InvalidRegex.Text="Girdiğiniz kurallı ifade geçersiz."
10
 Active="Etkin"
11
 Inactive="Devre Dışı"
12
 Start="Başlat"
13
 Stop="Durdur"
14
 
15
+Captions="Altyazı (Deneysel)"
16
+Captions.AudioSource="Ses kaynağı"
17
+Captions.CurrentSystemLanguage="Geçerli Sistem Dili (%1)"
18
 
19
 OutputTimer="Çıkış Zamanlayıcısı"
20
 OutputTimer.Stream="Şuradan sonra yayını durdur:"
21
 OutputTimer.Record="Şuradan sonra kaydı durdur:"
22
+OutputTimer.Stream.StoppingIn="Yayın durduruluyor:"
23
+OutputTimer.Record.StoppingIn="Kayıt durduruluyor:"
24
 OutputTimer.Stream.EnableEverytime="Her zaman yayın zamanlayıcıyı etkinleştir"
25
 OutputTimer.Record.EnableEverytime="Her zaman kayıt zamanlayıcıyı etkinleştir"
26
 
27
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="Запустити"
3
 Stop="Зупинити"
4
 
5
+Captions="Субтитри (експериментально)"
6
+Captions.AudioSource="Джерело Аудіо"
7
+Captions.CurrentSystemLanguage="Поточна мова Системи (%1)"
8
 
9
 OutputTimer="Таймер для Виводу"
10
 OutputTimer.Stream="Закінчити трансляцію за:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="开始"
3
 Stop="停止"
4
 
5
+Captions="标题(实验)"
6
+Captions.AudioSource="音频源"
7
+Captions.CurrentSystemLanguage="当前系统语言 (%1)"
8
 
9
 OutputTimer="输出计时器"
10
 OutputTimer.Stream="停止流处理后:"
11
obs-studio-0.17.0.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini -> obs-studio-17.0.1.tar.xz/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini Changed
11
 
1
@@ -11,6 +11,9 @@
2
 Start="開始"
3
 Stop="停止"
4
 
5
+Captions="標題 (實驗)"
6
+Captions.AudioSource="音訊源"
7
+Captions.CurrentSystemLanguage="目前系統語言 (%1)"
8
 
9
 OutputTimer="輸出計時器"
10
 OutputTimer.Stream="在下面時間後停止串流:"
11
obs-studio-0.17.0.tar.xz/UI/window-basic-main-profiles.cpp -> obs-studio-17.0.1.tar.xz/UI/window-basic-main-profiles.cpp Changed
23
 
1
@@ -481,6 +481,10 @@
2
                    profileDir + "/basic.ini");
3
            QFile::copy(dir + "/service.json",
4
                    profileDir + "/service.json");
5
+           QFile::copy(dir + "/streamEncoder.json",
6
+                   profileDir + "/streamEncoder.json");
7
+           QFile::copy(dir + "/recordEncoder.json",
8
+                   profileDir + "/recordEncoder.json");
9
            RefreshProfiles();
10
        } else {
11
            QMessageBox::information(this,
12
@@ -524,6 +528,10 @@
13
                    outputDir + "/basic.ini");
14
            QFile::copy(inputPath + currentProfile + "/service.json",
15
                    outputDir + "/service.json");
16
+           QFile::copy(inputPath + currentProfile + "/streamEncoder.json",
17
+                   outputDir + "/streamEncoder.json");
18
+           QFile::copy(inputPath + currentProfile + "/recordEncoder.json",
19
+                   outputDir + "/recordEncoder.json");
20
        }
21
    }
22
 }
23
obs-studio-0.17.0.tar.xz/cmake/Modules/CopyMSVCBins.cmake -> obs-studio-17.0.1.tar.xz/cmake/Modules/CopyMSVCBins.cmake Changed
14
 
1
@@ -19,12 +19,6 @@
2
    set(_bin_suffix 32)
3
 endif()
4
 
5
-find_package(Libavcodec QUIET)
6
-find_package(Libx264 QUIET)
7
-find_package(Libfdk QUIET)
8
-find_package(ssl QUIET)
9
-find_package(Qt5Core QUIET)
10
-
11
 file(GLOB FFMPEG_BIN_FILES
12
    "${FFMPEG_avcodec_INCLUDE_DIR}/../bin/avcodec-*.dll"
13
    "${FFMPEG_avcodec_INCLUDE_DIR}/../bin${_bin_suffix}/avcodec-*.dll"
14
obs-studio-0.17.0.tar.xz/deps/libff/libff/ff-demuxer.c -> obs-studio-17.0.1.tar.xz/deps/libff/libff/ff-demuxer.c Changed
16
 
1
@@ -297,7 +297,13 @@
2
    }
3
 
4
    if (codec == NULL) {
5
-       codec = avcodec_find_decoder(codec_context->codec_id);
6
+       if (codec_context->codec_id == AV_CODEC_ID_VP8)
7
+           codec = avcodec_find_decoder_by_name("libvpx");
8
+       else if (codec_context->codec_id == AV_CODEC_ID_VP9)
9
+           codec = avcodec_find_decoder_by_name("libvpx-vp9");
10
+
11
+       if (!codec)
12
+           codec = avcodec_find_decoder(codec_context->codec_id);
13
        if (codec == NULL) {
14
            av_log(NULL, AV_LOG_WARNING, "no decoder found for"
15
                                                      " codec with id %d",
16
obs-studio-0.17.0.tar.xz/libobs/obs-config.h -> obs-studio-17.0.1.tar.xz/libobs/obs-config.h Changed
10
 
1
@@ -41,7 +41,7 @@
2
  *
3
  * Reset to zero each major or minor version
4
  */
5
-#define LIBOBS_API_PATCH_VER  0
6
+#define LIBOBS_API_PATCH_VER  1
7
 
8
 #define MAKE_SEMANTIC_VERSION(major, minor, patch) \
9
                              ((major << 24) | \
10
obs-studio-0.17.0.tar.xz/libobs/obs-scene.c -> obs-studio-17.0.1.tar.xz/libobs/obs-scene.c Changed
59
 
1
@@ -162,7 +162,7 @@
2
 
3
 static void scene_enum_sources(void *data,
4
        obs_source_enum_proc_t enum_callback,
5
-       void *param)
6
+       void *param, bool active)
7
 {
8
    struct obs_scene *scene = data;
9
    struct obs_scene_item *item;
10
@@ -175,7 +175,7 @@
11
        next = item->next;
12
 
13
        obs_sceneitem_addref(item);
14
-       if (os_atomic_load_long(&item->active_refs) > 0)
15
+       if (!active || os_atomic_load_long(&item->active_refs) > 0)
16
            enum_callback(scene->source, item->source, param);
17
        obs_sceneitem_release(item);
18
 
19
@@ -185,6 +185,20 @@
20
    full_unlock(scene);
21
 }
22
 
23
+static void scene_enum_active_sources(void *data,
24
+       obs_source_enum_proc_t enum_callback,
25
+       void *param)
26
+{
27
+   scene_enum_sources(data, enum_callback, param, true);
28
+}
29
+
30
+static void scene_enum_all_sources(void *data,
31
+       obs_source_enum_proc_t enum_callback,
32
+       void *param)
33
+{
34
+   scene_enum_sources(data, enum_callback, param, false);
35
+}
36
+
37
 static inline void detach_sceneitem(struct obs_scene_item *item)
38
 {
39
    if (item->prev)
40
@@ -957,7 +971,8 @@
41
    .get_height    = scene_getheight,
42
    .load          = scene_load,
43
    .save          = scene_save,
44
-   .enum_active_sources = scene_enum_sources
45
+   .enum_active_sources = scene_enum_active_sources,
46
+   .enum_all_sources = scene_enum_all_sources
47
 };
48
 
49
 obs_scene_t *obs_scene_create(const char *name)
50
@@ -1072,6 +1087,8 @@
51
            new_item->align = item->align;
52
            new_item->last_width = item->last_width;
53
            new_item->last_height = item->last_height;
54
+           new_item->output_scale = item->output_scale;
55
+           new_item->scale_filter = item->scale_filter;
56
            new_item->box_transform = item->box_transform;
57
            new_item->draw_transform = item->draw_transform;
58
            new_item->bounds_type = item->bounds_type;
59
obs-studio-0.17.0.tar.xz/libobs/obs-source.c -> obs-studio-17.0.1.tar.xz/libobs/obs-source.c Changed
105
 
1
@@ -2968,19 +2968,19 @@
2
    void *param;
3
 };
4
 
5
-static void enum_source_tree_callback(obs_source_t *parent, obs_source_t *child,
6
-       void *param)
7
+static void enum_source_active_tree_callback(obs_source_t *parent,
8
+       obs_source_t *child, void *param)
9
 {
10
    struct source_enum_data *data = param;
11
    bool is_transition = child->info.type == OBS_SOURCE_TYPE_TRANSITION;
12
 
13
    if (is_transition)
14
        obs_transition_enum_sources(child,
15
-               enum_source_tree_callback, param);
16
+               enum_source_active_tree_callback, param);
17
    if (child->info.enum_active_sources) {
18
        if (child->context.data) {
19
            child->info.enum_active_sources(child->context.data,
20
-                   enum_source_tree_callback, data);
21
+                   enum_source_active_tree_callback, data);
22
        }
23
    }
24
 
25
@@ -3027,11 +3027,67 @@
26
    obs_source_addref(source);
27
 
28
    if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
29
-       obs_transition_enum_sources(source, enum_source_tree_callback,
30
-               &data);
31
+       obs_transition_enum_sources(source,
32
+               enum_source_active_tree_callback, &data);
33
    if (source->info.enum_active_sources)
34
        source->info.enum_active_sources(source->context.data,
35
-               enum_source_tree_callback, &data);
36
+               enum_source_active_tree_callback, &data);
37
+
38
+   obs_source_release(source);
39
+}
40
+
41
+static void enum_source_full_tree_callback(obs_source_t *parent,
42
+       obs_source_t *child, void *param)
43
+{
44
+   struct source_enum_data *data = param;
45
+   bool is_transition = child->info.type == OBS_SOURCE_TYPE_TRANSITION;
46
+
47
+   if (is_transition)
48
+       obs_transition_enum_sources(child,
49
+               enum_source_full_tree_callback, param);
50
+   if (child->info.enum_all_sources) {
51
+       if (child->context.data) {
52
+           child->info.enum_active_sources(child->context.data,
53
+                   enum_source_full_tree_callback, data);
54
+       }
55
+   } else if (child->info.enum_active_sources) {
56
+       if (child->context.data) {
57
+           child->info.enum_active_sources(child->context.data,
58
+                   enum_source_full_tree_callback, data);
59
+       }
60
+   }
61
+
62
+   data->enum_callback(parent, child, data->param);
63
+}
64
+
65
+static void obs_source_enum_full_tree(obs_source_t *source,
66
+       obs_source_enum_proc_t enum_callback,
67
+       void *param)
68
+{
69
+   struct source_enum_data data = {enum_callback, param};
70
+   bool is_transition;
71
+
72
+   if (!data_valid(source, "obs_source_enum_active_tree"))
73
+       return;
74
+
75
+   is_transition = source->info.type == OBS_SOURCE_TYPE_TRANSITION;
76
+   if (!is_transition && !source->info.enum_active_sources)
77
+       return;
78
+
79
+   obs_source_addref(source);
80
+
81
+   if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
82
+       obs_transition_enum_sources(source,
83
+               enum_source_full_tree_callback, &data);
84
+
85
+   if (source->info.enum_all_sources) {
86
+       source->info.enum_all_sources(source->context.data,
87
+               enum_source_full_tree_callback, &data);
88
+
89
+   } else if (source->info.enum_active_sources) {
90
+       source->info.enum_active_sources(source->context.data,
91
+               enum_source_full_tree_callback, &data);
92
+   }
93
 
94
    obs_source_release(source);
95
 }
96
@@ -3063,7 +3119,7 @@
97
        return false;
98
    }
99
 
100
-   obs_source_enum_active_tree(child, check_descendant, &info);
101
+   obs_source_enum_full_tree(child, check_descendant, &info);
102
    if (info.exists)
103
        return false;
104
 
105
obs-studio-0.17.0.tar.xz/libobs/obs-source.h -> obs-studio-17.0.1.tar.xz/libobs/obs-source.h Changed
23
 
1
@@ -400,6 +400,21 @@
2
    bool (*audio_render)(void *data, uint64_t *ts_out,
3
            struct obs_source_audio_mix *audio_output,
4
            uint32_t mixers, size_t channels, size_t sample_rate);
5
+
6
+   /**
7
+    * Called to enumerate all active and inactive sources being used
8
+    * within this source.  If this callback isn't implemented,
9
+    * enum_active_sources will be called instead.
10
+    *
11
+    * This is typically used if a source can have inactive child sources.
12
+    *
13
+    * @param  data           Filter data
14
+    * @param  enum_callback  Enumeration callback
15
+    * @param  param          User data to pass to callback
16
+    */
17
+   void (*enum_all_sources)(void *data,
18
+           obs_source_enum_proc_t enum_callback,
19
+           void *param);
20
 };
21
 
22
 EXPORT void obs_register_source_s(const struct obs_source_info *info,
23
obs-studio-0.17.0.tar.xz/plugins/coreaudio-encoder/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/coreaudio-encoder/data/locale/hu-HU.ini Changed
10
 
1
@@ -1,6 +1,6 @@
2
 CoreAudioAAC="CoreAudio AAC kódoló"
3
-Bitrate="Bitráta"
4
+Bitrate="Bitsebesség"
5
 AllowHEAAC="HE-AAC engedélyezése"
6
 OutputSamplerate="Kimeneti mintavételráta"
7
-UseInputSampleRate="Beviteli (OBS) mintaráta használata (kilistázza a nem támogatott bitrátákat)"
8
+UseInputSampleRate="Beviteli (OBS) mintaráta használata (kilistázza a nem támogatott bitsebességeket)"
9
 
10
obs-studio-0.17.0.tar.xz/plugins/coreaudio-encoder/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/coreaudio-encoder/data/locale/tr-TR.ini Changed
7
 
1
@@ -2,4 +2,5 @@
2
 Bitrate="Bit hızı"
3
 AllowHEAAC="HE-ACC'ye izin ver"
4
 OutputSamplerate="Çıkış örnek hızı"
5
+UseInputSampleRate="Giriş (OBS) Örnekleme Hızını Kullan (desteklenmeyen bit hızları listelenebilir)"
6
 
7
obs-studio-0.17.0.tar.xz/plugins/enc-amf/#Resources/PATCH_NOTES.md -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/#Resources/PATCH_NOTES.md Changed
29
 
1
@@ -1,11 +1,18 @@
2
-# 1.4.3.4 - Crimson ReLive Compatibility Update (Hotfix 1)
3
-Crimson ReLive changed how the Full Range flag is applied, which caused the plugin to break since it expected another property there. This has been fixed and some log messages have been changed to also result in better readability for users and support.
4
+# 1.4.3.8 - Settings Transfer, Automatic VBV Buffer adjustment and Fixes (Hotfix 2)
5
+Another day, another new feature: this time it is transferring settings between versions, so that you will no longer use settings when a change to a setting is made. Since it only just now started tracking the config version, it will only work with settings created between 1.4.3.0 and 1.4.3.5, any other version might end up with broken settings.
6
 
7
-Hotfix 1: The Driver update also broke VBAQ, but it caused less issues than the Full Range flag. This has been fixed.
8
+Another change has been done to the Automatic VBV Buffer Size, which will now behave much more predictable. A value of 0% is completely unrestricted, 50% matches the calculated bitrate and 100% matches the calculated strict bitrate.
9
+
10
+Presets will also now use the proper minimum and maximum QP values and the minimum QP default value has been increased to 11.
11
+
12
+Hotfix 1: Fix enumeration based properties not working correctly due to a programming error.
13
+Hotfix 2: Actually fix the enumeration based properties for real this time.
14
 
15
 ## Changelog
16
-* Hotfix 1: Experimental Property VBAQ would not be properly set.
17
-* Hotfix 1: Runtime and Compiled Against version numbers were switched around.
18
-* Fixed: Experimental Full Range Color mode no longer causes encoding to fail. (Fixes #175)
19
-* Changed: Queue status log messages have been reduced to once per second instead of once per frame.
20
-* Changed: First submission log message now show the time in seconds instead of nanoseconds.
21
+* Added: Version-specific setting transfer code which should reduce the lost settings between updates.
22
+* Changed: VBV Buffer Strictness is now linear with three steps: 100000 (0%), Target Bitrate (50%) and Strict Target Bitrate (100%).
23
+* Changed: Default for Minimum QP is now 11.
24
+* Fixed: Presets not using the proper QP Minimum and Maximum.
25
+* Fixed: Startup log messages not showing proper error codes.
26
+* Hotfix: Fix enumeration based properties not using the correct values.
27
+* Hotfix: Fix the default value for B-Frame Pattern being '-1' due to an oversight in code.
28
\ No newline at end of file
29
obs-studio-0.17.0.tar.xz/plugins/enc-amf/CMakeLists.txt -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/CMakeLists.txt Changed
10
 
1
@@ -37,7 +37,7 @@
2
 SET(enc-amf_VERSION_MAJOR 1)
3
 SET(enc-amf_VERSION_MINOR 4)
4
 SET(enc-amf_VERSION_PATCH 3)
5
-SET(enc-amf_VERSION_BUILD 4)
6
+SET(enc-amf_VERSION_BUILD 8)
7
 configure_file(
8
    "${PROJECT_SOURCE_DIR}/#Resources/package.in.bat"
9
    "${PROJECT_SOURCE_DIR}/#Resources/package.bat"
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/CONTRIBUTING.md -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/CONTRIBUTING.md Changed
20
 
1
@@ -40,13 +40,14 @@
2
 The plugin itself is made up of several sub-modules:
3
 
4
 * AMF: amf.cpp, amf.h, amf-capabilities.cpp, amf-capabilities.h
5
+* Encoder: amf-encoder.cpp, amf-encoder.h
6
 * H264: amf-h264.cpp, amf-h264.h, enc-h264.cpp, enc-h264.h
7
-* H265: amf-h265.cpp, amf-h265.h, enc-h265.cpp, enc-h265.h
8
 * API: api-base.cpp, api-base.h
9
-* API-OGL: api-opengl.cpp, api-opengl.h
10
-* API-D3D9: api-d3d9.cpp, api-d3d9.h
11
-* API-D3D11: api-d3d11.cpp, api-d3d11.h
12
+* API-OpenGL: api-opengl.cpp, api-opengl.h
13
+* API-Direct3D9: api-d3d9.cpp, api-d3d9.h
14
+* API-Direct3D11: api-d3d11.cpp, api-d3d11.h
15
 * API-Host: api-host.cpp, api-host.h
16
+* Plugin: plugin.cpp, plugin.h, CMakeLists.txt
17
 * Utilities: misc-util.cpp
18
 * Locale: Any locale files
19
 * Resources: Any resource files
20
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/amf-capabilities.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/amf-capabilities.h Changed
32
 
1
@@ -85,10 +85,10 @@
2
                Plugin::API::Adapter adapter);
3
            static void ReportAdapterTypeCapabilities(std::shared_ptr<Plugin::API::Base> api,
4
                Plugin::API::Adapter adapter,
5
-               VCEEncoderType type);
6
+               H264EncoderType type);
7
            static void ReportAdapterTypeIOCapabilities(std::shared_ptr<Plugin::API::Base> api,
8
                Plugin::API::Adapter adapter,
9
-               VCEEncoderType type,
10
+               H264EncoderType type,
11
                bool output);
12
 
13
            //////////////////////////////////////////////////////////////////////////
14
@@ -99,13 +99,13 @@
15
            ~VCECapabilities();
16
 
17
            bool Refresh();
18
-           std::vector<std::pair<VCEEncoderType, VCEDeviceCapabilities>>
19
+           std::vector<std::pair<H264EncoderType, VCEDeviceCapabilities>>
20
                GetAllAdapterCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter);
21
            VCEDeviceCapabilities
22
-               GetAdapterCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter, VCEEncoderType type);
23
+               GetAdapterCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter, H264EncoderType type);
24
 
25
            private:
26
-           std::map<std::tuple<std::string, Plugin::API::Adapter, Plugin::AMD::VCEEncoderType>, VCEDeviceCapabilities> capabilityMap;
27
+           std::map<std::tuple<std::string, Plugin::API::Adapter, Plugin::AMD::H264EncoderType>, VCEDeviceCapabilities> capabilityMap;
28
        };
29
    }
30
 }
31
\ No newline at end of file
32
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/amf-h264.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/amf-h264.h Changed
349
 
1
@@ -46,125 +46,120 @@
2
 namespace Plugin {
3
    namespace AMD {
4
        // Internal Properties
5
-       enum VCEEncoderType {
6
-           VCEEncoderType_AVC,     // Advanced Video Coding
7
-           VCEEncoderType_SVC,     // Scalable Video Coding
8
-           VCEEncoderType_HEVC,    // High-Efficiency Video Coding (Discovered in amfrt64.dll)
9
+       enum class H264EncoderType : uint8_t {
10
+           AVC = 0,    // Advanced Video Coding
11
+           SVC,        // Scalable Video Coding
12
+           HEVC,       // High-Efficiency Video Coding (Discovered in amfrt64.dll)
13
        };
14
-       enum VCEMemoryType {
15
-           VCEMemoryType_Host,         // Host-Managed Memory
16
-           VCEMemoryType_DirectX9,     // DirectX9
17
-           VCEMemoryType_DirectX11,    // DirectX11
18
-           VCEMemoryType_OpenGL,       // OpenGL
19
+       enum class H264MemoryType : uint8_t {
20
+           Host = 0,   // Host-Managed Memory
21
+           DirectX9,   // DirectX9
22
+           DirectX11,  // DirectX11
23
+           OpenGL,     // OpenGL
24
        };
25
-       enum VCEColorFormat {
26
+       enum class H264ColorFormat : uint8_t {
27
            // 4:2:0 Formats
28
-           VCEColorFormat_NV12,    // NV12
29
-           VCEColorFormat_I420,    // YUV 4:2:0
30
+           NV12 = 0,   // NV12
31
+           I420,       // YUV 4:2:0
32
            // 4:2:2 Formats
33
-           VCEColorFormat_YUY2,
34
+           YUY2,
35
            // Uncompressed
36
-           VCEColorFormat_BGRA,    // ARGB
37
-           VCEColorFormat_RGBA,    // RGBA
38
+           BGRA,       // ARGB
39
+           RGBA,       // RGBA
40
            // Other
41
-           VCEColorFormat_GRAY,
42
+           GRAY,       // Y 4:0:0
43
        };
44
-       enum VCEColorProfile {
45
-           VCEColorProfile_601,
46
-           VCEColorProfile_709,
47
-           VCEColorProfile_2020, // HDR
48
+       enum class H264ColorProfile : uint8_t {
49
+           Rec601 = 0,
50
+           Rec709,
51
+           Rec2020, // Truer to world color, used for HDR
52
        };
53
 
54
        // Static Properties
55
-       enum VCEUsage {
56
-           VCEUsage_Transcoding,
57
-           VCEUsage_UltraLowLatency,
58
-           VCEUsage_LowLatency,
59
-           VCEUsage_Webcam,            // For SVC
60
+       enum class H264Usage : uint8_t {
61
+           Transcoding = 0,    // Only one capable of streaming to services.
62
+           UltraLowLatency,    // Low Latency Recording or Network Streaming
63
+           LowLatency,         // Low Latency Recording or Network Streaming
64
+           Webcam,             // For SVC Recording and Streaming
65
        };
66
-       enum VCEQualityPreset {
67
-           VCEQualityPreset_Speed,
68
-           VCEQualityPreset_Balanced,
69
-           VCEQualityPreset_Quality,
70
+       enum class H264QualityPreset : uint8_t {
71
+           Speed = 0,
72
+           Balanced,
73
+           Quality,
74
        };
75
-       enum VCEProfile {
76
-           VCEProfile_Baseline = 66,
77
-           VCEProfile_Main = 77,
78
-           VCEProfile_High = 100,
79
-           VCEProfile_ConstrainedBaseline = 256,
80
-           VCEProfile_ConstrainedHigh = 257
81
+       enum class H264Profile : uint16_t {
82
+           Baseline = 66,
83
+           Main = 77,
84
+           High = 100,
85
+           ConstrainedBaseline = 256,
86
+           ConstrainedHigh = 257
87
        };
88
-       enum VCEProfileLevel {
89
-           VCEProfileLevel_Automatic = 0,
90
-           VCEProfileLevel_10 = 10,
91
-           VCEProfileLevel_11,
92
-           VCEProfileLevel_12,
93
-           VCEProfileLevel_13,
94
-           VCEProfileLevel_20 = 20,
95
-           VCEProfileLevel_21,
96
-           VCEProfileLevel_22,
97
-           VCEProfileLevel_30 = 30,
98
-           VCEProfileLevel_31,
99
-           VCEProfileLevel_32,
100
-           VCEProfileLevel_40 = 40,
101
-           VCEProfileLevel_41,
102
-           VCEProfileLevel_42,
103
-           VCEProfileLevel_50 = 50,
104
-           VCEProfileLevel_51,
105
-           VCEProfileLevel_52,
106
-           VCEProfileLevel_60 = 60,
107
-           VCEProfileLevel_61,
108
-           VCEProfileLevel_62,
109
+       enum class H264ProfileLevel : uint8_t {
110
+           Automatic = 0,
111
+           L10 = 10,
112
+           L11,
113
+           L12,
114
+           L13,
115
+           L20 = 20,
116
+           L21,
117
+           L22,
118
+           L30 = 30,
119
+           L31,
120
+           L32,
121
+           L40 = 40,
122
+           L41,
123
+           L42,
124
+           L50 = 50,
125
+           L51,
126
+           L52,
127
        };
128
-       enum VCEScanType {
129
-           VCEScanType_Progressive,
130
-           VCEScanType_Interlaced,
131
+       enum class H264ScanType : uint8_t {
132
+           Progressive = 0,
133
+           Interlaced,
134
        };
135
-       enum VCECodingType {
136
-           VCECodingType_Default = 0,
137
-           VCECodingType_CABAC = 1,
138
-           VCECodingType_CALVC = 2,
139
+       enum class H264CodingType : uint8_t {
140
+           Default = 0,
141
+           CABAC = 1,
142
+           CALVC = 2,
143
        };
144
 
145
        // Dynamic Properties
146
-       enum VCERateControlMethod {
147
-           VCERateControlMethod_ConstantQP,
148
-           VCERateControlMethod_ConstantBitrate,
149
-           VCERateControlMethod_VariableBitrate_PeakConstrained,
150
-           VCERateControlMethod_VariableBitrate_LatencyConstrained,
151
+       enum class H264RateControlMethod : uint8_t {
152
+           ConstantQP = 0,
153
+           ConstantBitrate,
154
+           VariableBitrate_PeakConstrained,
155
+           VariableBitrate_LatencyConstrained = 3,
156
        };
157
-       enum VCEBFramePattern {
158
-           VCEBFramePattern_None,
159
-           VCEBFramePattern_One,
160
-           VCEBFramePattern_Two,
161
-           VCEBFramePattern_Three,
162
+       enum class H264BFramePattern : uint8_t {
163
+           None = 0,
164
+           One,
165
+           Two,
166
+           Three,
167
        };
168
 
169
        // Experimental
170
-       enum VCESliceMode {
171
-           VCESliceMode_Horizontal = 1,
172
-           VCESliceMode_Vertical = 2
173
+       enum class H264SliceMode : uint8_t {
174
+           Horizontal = 1,
175
+           Vertical = 2
176
        };
177
-       enum VCESliceControlMode {
178
-           VCESliceControlMode_Off,
179
-           VCESliceControlMode_Macroblock = 1, // AMF_VIDEO_ENCODER_SLICE_CTRL_MODE_MB
180
-           VCESliceControlMode_Invalid,
181
-           VCESliceControlMode_Macroblock_Row = 3 // AMF_VIDEO_ENCODER_SLICE_CTRL_MODE_MB_ROW
182
+       enum class H264SliceControlMode : uint8_t {
183
+           Off = 0,
184
+           Macroblock = 1, // AMF_VIDEO_ENCODER_SLICE_CTRL_MODE_MB
185
+           Invalid,
186
+           Macroblock_Row = 3 // AMF_VIDEO_ENCODER_SLICE_CTRL_MODE_MB_ROW
187
        };
188
-
189
-
190
-
191
-       class VCEEncoder {
192
+       
193
+       class H264Encoder {
194
            #pragma region Initializer & Finalizer
195
            public:
196
-           VCEEncoder(
197
-               VCEEncoderType p_Type,
198
+           H264Encoder(
199
+               H264EncoderType p_Type,
200
                std::string p_VideoAPI,
201
                uint64_t p_VideoAdapterId,
202
                bool p_OpenCL,
203
-               VCEColorFormat p_SurfaceFormat = VCEColorFormat_NV12
204
+               H264ColorFormat p_SurfaceFormat = H264ColorFormat::NV12
205
            );
206
-           ~VCEEncoder();
207
+           ~H264Encoder();
208
            #pragma endregion Initializer & Finalizer
209
 
210
            public:
211
@@ -187,27 +182,27 @@
212
            #pragma region Startup Properties
213
            // Set which Usage preset to use.
214
            // Changing this will also change a lot of other properties.
215
-           void SetUsage(VCEUsage usage);
216
-           VCEUsage GetUsage();
217
+           void SetUsage(H264Usage usage);
218
+           H264Usage GetUsage();
219
 
220
            // Set which Quality Preset AMF should use.
221
            // Affects the quality of the output.
222
-           void SetQualityPreset(VCEQualityPreset preset);
223
-           VCEQualityPreset GetQualityPreset();
224
+           void SetQualityPreset(H264QualityPreset preset);
225
+           H264QualityPreset GetQualityPreset();
226
 
227
            // Set the Profile the output should have.
228
-           void SetProfile(VCEProfile profile);
229
-           VCEProfile GetProfile();
230
+           void SetProfile(H264Profile profile);
231
+           H264Profile GetProfile();
232
 
233
            // Set the Profile Level the output should have.
234
-           void SetProfileLevel(VCEProfileLevel level);
235
-           VCEProfileLevel GetProfileLevel();
236
+           void SetProfileLevel(H264ProfileLevel level);
237
+           H264ProfileLevel GetProfileLevel();
238
            #pragma endregion Startup Properties
239
 
240
            #pragma region Frame Properties
241
            // Set which Color Profile the input frame is.
242
-           void SetColorProfile(VCEColorProfile profile);
243
-           VCEColorProfile GetColorProfile();
244
+           void SetColorProfile(H264ColorProfile profile);
245
+           H264ColorProfile GetColorProfile();
246
 
247
            // Set if the input frame is in full color range.
248
            void SetFullRangeColorEnabled(bool enabled);
249
@@ -222,8 +217,8 @@
250
            std::pair<uint32_t, uint32_t> GetFrameRate();
251
 
252
            // Scanning method for input (and output?).
253
-           void SetScanType(VCEScanType scanType);
254
-           VCEScanType GetScanType();
255
+           void SetScanType(H264ScanType scanType);
256
+           H264ScanType GetScanType();
257
            #pragma endregion Frame Properties
258
 
259
            // Dynamic
260
@@ -239,8 +234,8 @@
261
             *  - When SVC encoding is enabled, all Rate-control parameters (with some restrictions) can be configured differently for a particular SVC-layer. An SVC-layer is denoted by an index pair [SVC-Temporal Layer index][SVC-Quality Layer index]. E.g. The bitrate may be configured differently for SVC-layers [0][0] and [1][0].
262
             *  - We restrict all SVC layers to have the same Rate Control method. Some RC parameters are not enabled with SVC encoding (e.g. all parameters related to B-Frames).
263
            **/
264
-           void SetRateControlMethod(VCERateControlMethod method);
265
-           VCERateControlMethod GetRateControlMethod();
266
+           void SetRateControlMethod(H264RateControlMethod method);
267
+           H264RateControlMethod GetRateControlMethod();
268
 
269
            /*  Sets the target bitrate */
270
            void SetTargetBitrate(uint32_t bitrate);
271
@@ -300,8 +295,8 @@
272
 
273
            #pragma region B-Frames
274
            /*  Sets the number of consecutive B-Frames. BFramesPattern = 0 indicates that B-Frames are not used */
275
-           void SetBFramePattern(VCEBFramePattern pattern);
276
-           VCEBFramePattern GetBFramePattern();
277
+           void SetBFramePattern(H264BFramePattern pattern);
278
+           H264BFramePattern GetBFramePattern();
279
 
280
            /* Selects the delta QP of non-reference B-Frames with respect to the last non-B-Frame */
281
            void SetBFrameDeltaQP(int8_t qp);
282
@@ -338,8 +333,8 @@
283
            uint32_t GetMaxMBPerSec();
284
 
285
            /* Coding Type */
286
-           void SetCodingType(VCECodingType type);
287
-           VCECodingType GetCodingType();
288
+           void SetCodingType(H264CodingType type);
289
+           H264CodingType GetCodingType();
290
 
291
            void SetWaitForTaskEnabled(bool enabled);
292
            bool IsWaitForTaskEnabled();
293
@@ -404,16 +399,16 @@
294
            uint32_t GetSlicesPerFrame();
295
 
296
            // - SliceMode (1 - 2, Default is 1)
297
-           void SetSliceMode(VCESliceMode mode);
298
-           VCESliceMode GetSliceMode();
299
+           void SetSliceMode(H264SliceMode mode);
300
+           H264SliceMode GetSliceMode();
301
 
302
            // - MaxSliceSize (1 - INT_MAX)
303
            void SetMaximumSliceSize(uint32_t size);
304
            uint32_t GetMaximumSliceSize();
305
 
306
            // - SliceControlMode (0 - 3)
307
-           void SetSliceControlMode(VCESliceControlMode mode);
308
-           VCESliceControlMode GetSliceControlMode();
309
+           void SetSliceControlMode(H264SliceControlMode mode);
310
+           H264SliceControlMode GetSliceControlMode();
311
 
312
            // - SliceControlSize (0 - INT_MAX)
313
            void SetSliceControlSize(uint32_t size);
314
@@ -437,9 +432,9 @@
315
 
316
            // Threading
317
            private:
318
-           static void InputThreadMain(Plugin::AMD::VCEEncoder* p_this);
319
+           static void InputThreadMain(Plugin::AMD::H264Encoder* p_this);
320
            void InputThreadLogic();
321
-           static void OutputThreadMain(Plugin::AMD::VCEEncoder* p_this);
322
+           static void OutputThreadMain(Plugin::AMD::H264Encoder* p_this);
323
            void OutputThreadLogic();
324
            inline amf::AMFSurfacePtr CreateSurfaceFromFrame(struct encoder_frame*& frame);
325
 
326
@@ -483,10 +478,10 @@
327
            } m_Output;
328
 
329
            // Internal Properties
330
-           VCEEncoderType m_EncoderType;
331
-           VCEMemoryType m_MemoryType;
332
+           H264EncoderType m_EncoderType;
333
+           H264MemoryType m_MemoryType;
334
            bool m_OpenCL;
335
-           VCEColorFormat m_ColorFormat;
336
+           H264ColorFormat m_ColorFormat;
337
            bool m_Flag_IsStarted,
338
                m_Flag_FirstFrameSubmitted,
339
                m_Flag_FirstFrameReceived;
340
@@ -497,7 +492,7 @@
341
            size_t m_InputQueueLimit,
342
                m_InputQueueLastSize;
343
            uint32_t m_TimerPeriod;
344
-           VCEColorProfile m_ColorProfile;
345
+           H264ColorProfile m_ColorProfile;
346
            std::chrono::time_point<std::chrono::high_resolution_clock> m_LastQueueWarnMessageTime;
347
 
348
            #pragma endregion Members
349
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/amf.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/amf.h Changed
10
 
1
@@ -79,6 +79,7 @@
2
            amf::AMFFactory* m_AMFFactory;
3
            amf::AMFTrace* m_AMFTrace;
4
            amf::AMFDebug* m_AMFDebug;
5
+           amf::AMFTraceWriter* m_TraceWriter;
6
        };
7
    }
8
 }
9
\ No newline at end of file
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/api-base.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/api-base.h Changed
27
 
1
@@ -36,11 +36,11 @@
2
 //////////////////////////////////////////////////////////////////////////
3
 namespace Plugin {
4
    namespace API {
5
-       enum APIType {
6
-           APIType_Host,
7
-           APIType_Direct3D9,
8
-           APIType_Direct3D11,
9
-           APIType_OpenGL,
10
+       enum class Type {
11
+           Host,
12
+           Direct3D9,
13
+           Direct3D11,
14
+           OpenGL,
15
        };
16
 
17
        struct Adapter {
18
@@ -78,7 +78,7 @@
19
            //////////////////////////////////////////////////////////////////////////
20
            public:
21
            virtual std::string GetName() = 0;
22
-           virtual APIType GetType() = 0;
23
+           virtual Type GetType() = 0;
24
 
25
            virtual std::vector<Adapter> EnumerateAdapters() = 0;
26
            virtual Adapter GetAdapterById(uint32_t idLow, uint32_t idHigh) = 0;
27
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/api-d3d11.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/api-d3d11.h Changed
10
 
1
@@ -37,7 +37,7 @@
2
    namespace API {
3
        class Direct3D11 : public Base {
4
            virtual std::string GetName() override;
5
-           virtual APIType GetType() override;
6
+           virtual Type GetType() override;
7
 
8
            virtual std::vector<Adapter> EnumerateAdapters() override;
9
            virtual Adapter GetAdapterById(uint32_t idLow, uint32_t idHigh) override;
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/api-d3d9.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/api-d3d9.h Changed
10
 
1
@@ -37,7 +37,7 @@
2
    namespace API {
3
        class Direct3D9 : public Base {
4
            virtual std::string GetName() override;
5
-           virtual APIType GetType() override;
6
+           virtual Type GetType() override;
7
 
8
            virtual std::vector<Adapter> EnumerateAdapters() override;
9
            virtual Adapter GetAdapterById(uint32_t idLow, uint32_t idHigh);
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/api-host.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/api-host.h Changed
10
 
1
@@ -37,7 +37,7 @@
2
    namespace API {
3
        class Host : public Base {
4
            virtual std::string GetName() override;
5
-           virtual APIType GetType() override;
6
+           virtual Type GetType() override;
7
 
8
            virtual std::vector<Adapter> EnumerateAdapters() override;
9
            virtual Adapter GetAdapterById(uint32_t idLow, uint32_t idHigh);
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/api-opengl.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/api-opengl.h Changed
10
 
1
@@ -37,7 +37,7 @@
2
    namespace API {
3
        class OpenGL : public Base {
4
            virtual std::string GetName() override;
5
-           virtual APIType GetType() override;
6
+           virtual Type GetType() override;
7
 
8
            virtual std::vector<Adapter> EnumerateAdapters() override;
9
            virtual Adapter GetAdapterById(uint32_t idLow, uint32_t idHigh);
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/enc-h264.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/enc-h264.h Changed
19
 
1
@@ -177,6 +177,7 @@
2
 #define AMF_H264_VIEW_MASTER                               TEXT_AMF_H264("View.Master")
3
 #define AMF_H264_DEBUG                                     TEXT_AMF_H264("Debug")
4
 #define AMF_H264_DEBUG_DESCRIPTION                         TEXT_AMF_H264("Debug.Description")
5
+#define AMF_H264_VERSION                                   TEXT_AMF_H264("Version")
6
 
7
 //////////////////////////////////////////////////////////////////////////
8
 // Code
9
@@ -216,7 +217,7 @@
10
            // Storage
11
            //////////////////////////////////////////////////////////////////////////
12
            private:
13
-           Plugin::AMD::VCEEncoder* m_VideoEncoder;
14
+           Plugin::AMD::H264Encoder* m_VideoEncoder;
15
        };
16
    }
17
 }
18
\ No newline at end of file
19
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Include/plugin.h -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Include/plugin.h Changed
18
 
1
@@ -26,7 +26,15 @@
2
 //////////////////////////////////////////////////////////////////////////
3
 // Includes
4
 //////////////////////////////////////////////////////////////////////////
5
-#include <stdint.h>
6
+
7
+// Microsoft as always does not follow the standard and declares safe functions unsafe.
8
+// Or even straight up marks them as deprecated, what the fuck Microsoft?
9
+#ifdef _MSC_VER
10
+#define _CRT_SECURE_NO_WARNINGS
11
+#pragma warning(disable : 4996)
12
+#endif
13
+
14
+#include <cstdint>
15
 #include <inttypes.h>
16
 #include <exception>
17
 #include <stdexcept>
18
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/ca-ES.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/ca-ES.ini Changed
122
 
1
@@ -4,6 +4,7 @@
2
 AMF.Util.Toggle.Disabled="Desactivat"
3
 AMF.Util.Toggle.Enabled="Activat"
4
 AMF.H264.Preset="Configuració preestablerta"
5
+AMF.H264.Preset.ResetToDefaults="Restableix als valors per defecte"
6
 AMF.H264.Preset.Recording="S'està enregistrant"
7
 AMF.H264.Preset.HighQuality="Alta qualitat"
8
 AMF.H264.Preset.Indistinguishable="Indistinguible"
9
@@ -16,34 +17,112 @@
10
 AMF.H264.Usage.UltraLowLatency="Latència ultra baixa"
11
 AMF.H264.Usage.LowLatency="Latència baixa"
12
 AMF.H264.QualityPreset="Qualitat del perfil"
13
+AMF.H264.QualityPreset.Description="Quina qualitat del perfil d'AMD s'ha d'intentar aconseguir:\n- 'Velocitat' és la més ràpida però la que pitjor qualitat obté,\n- 'Equilibrat' està entre 'Velocitat' i 'Qualitat' oferint un balanç entre els dos,\n- 'Qualitat' ofereix la millor qualitat possible per una determinada tassa de marcs."
14
 AMF.H264.QualityPreset.Speed="Velocitat"
15
 AMF.H264.QualityPreset.Balanced="Equilibrat"
16
 AMF.H264.QualityPreset.Quality="Qualitat"
17
 AMF.H264.Profile="Perfil"
18
+AMF.H264.Profile.Description="Quin perfil H.264 s'ha d'utilitzar per la codificació, ordenats de major qualitat al més suportat."
19
 AMF.H264.ProfileLevel="Nivell de perfil"
20
+AMF.H264.ProfileLevel.Description="Nivell de perfil H.264 a utilitzar per la codificació:\n- 'Automàtic' calcula el millor nivell de perfil per certa velocitat i mida de marcs,\n- '4.1' suporta 1920x1080 30FPS, 1280x720 60FPS, 960x540 90FPS\n- '4.2' suporta 1920x1080 60FPS, 1280x720 120FPS, 960x540 172FPS\n- '5.0' suporta 1920x1080 60FPS, 1280x720 144FPS, 960x540 172FPS\n- '5.1' suporta 3840x2160 30FPS, 1920x1080 120FPS, 1280x720 172FPS, 960x540 172FPS\n- '5.2' suporta 3840x2160 60FPS, 1920x1080 172FPS, 1280x720 172FPS, 960x540 172FPS"
21
 AMF.H264.RateControlMethod="Mètode de control del flux"
22
+AMF.H264.RateControlMethod.Description="Quin mètode de control de flux s'ha d'utilitzar:\n- '\@AMF.H264.RateControlMethod.CQP\@' assigna valors fixos de QP a I-/P-/B-Frames (Paràmetre de quantització),\n- '\@AMF.H264.RateControlMethod.CBR\@' es manté en la tassa de marcs objectiu (utilitzant dades de farciment) (recomanat per transmissions en directe),\n- '\@AMF.H264.RateControlMethod.VBR\@' es manté per sota d'un pic de tassa de marcs,\n- '\@AMF.H264.RateControlMethod.VBR_LAT\@' es manté prop de la tassa de marcs desitjada si la latència i carrega de la GPU ho permet, si no s'augmentarà la taxa de marcs (recomanat per a enregistraments)."
23
 AMF.H264.RateControlMethod.CQP="QP constant (CQP)"
24
 AMF.H264.RateControlMethod.CBR="Flux constant (CBR)"
25
 AMF.H264.RateControlMethod.VBR.Peak="Flux variable (pic restringit)(VBR)"
26
 AMF.H264.RateControlMethod.VBR.Latency="Flux variable (latència restringida) (VBR_LAT)"
27
 AMF.H264.Bitrate.Target="Tassa de bits desitjada"
28
+AMF.H264.Bitrate.Target.Description="Tassa de marcs a intentar arribar a la seqüència general."
29
 AMF.H264.Bitrate.Peak="Pic de tassa de bits"
30
+AMF.H264.Bitrate.Peak.Description="Tassa de marcs a intentar aconseguir com pic màxim en la seqüència general."
31
 AMF.H264.QP.Minimum="QP mínim"
32
+AMF.H264.QP.Minimum.Description="Valor mínim de QP (paràmetre de quantització) a utilitzar en un fotograma."
33
 AMF.H264.QP.Maximum="QP màxim"
34
+AMF.H264.QP.Maximum.Description="Valor màxim de QP (paràmetre de quantització) a utilitzar en un fotograma."
35
 AMF.H264.QP.IFrame="I-Frame QP"
36
+AMF.H264.QP.IFrame.Description="Valor fix de QP per I-Frames."
37
 AMF.H264.QP.PFrame="P-Frame QP"
38
+AMF.H264.QP.PFrame.Description="Valor fix de QP per P-Frames."
39
 AMF.H264.QP.BFrame="B-Frame QP"
40
+AMF.H264.QP.BFrame.Description="Valor de QP fix (paràmetre de quantització) a utilitzar per B-Frames."
41
+AMF.H264.VBVBuffer="Memòria intermèdia VBV"
42
+AMF.H264.VBVBuffer.Description="Quin mètode s'ha d'utilitzar per determinar la mida de la memòria intermèdia VBV:\n- 'Automàtic' calcula la mida utilitzant una restricció estricta,\n- 'Manual' permet a l'usuari controlar la mida.\nLa memòria intermèdia VBV (Verificador de la memòria intermèdia del vídeo) és usat per certs mètodes de control del flux per mantenir la taxa de bits dins dels paràmetres establerts."
43
+AMF.H264.VBVBuffer.Strictness="Rigorositat de la memòria intermèdia VBV"
44
+AMF.H264.VBVBuffer.Strictness.Description="Determina la rigidesa de la memòria intermèdia VBV, con 100% essent tant estricte com sigui possible i 0% sense restricció."
45
+AMF.H264.VBVBuffer.Size="Mida de la memòria intermèdia VBV"
46
+AMF.H264.VBVBuffer.Size.Description="La mida de la memòria intermèdia VBV que s'utilitza per al control de la tassa de marcs en una seqüencia."
47
+AMF.H264.VBVBuffer.Fullness="Amplitud de la memòria intermèdia VBV"
48
+AMF.H264.VBVBuffer.Fullness.Description="Com de ple és la memòria intermèdia VMV inicialment, només afectarà la seqüència inicial de la codificació."
49
 AMF.H264.FillerData="Dades a omplir"
50
+AMF.H264.FillerData.Description="En activar les dades de farciment es permet al codificador mantenir almenys la tassa de marcs desitjada omplint l'espai que falta amb informació sense valor."
51
 AMF.H264.FrameSkipping="Omissió de fotogrames"
52
+AMF.H264.FrameSkipping.Description="L'omissió de fotogrames permet al codificador saltar fotogrames per complir amb el requeriment de la tassa de marcs objectiu.\nQuan el codificador salta un fotograma inserirà una NAL que repetirà el darrer fotograma codificat a la transmissió.\nPot ajudar amb tassa de bits objectiu molt baixes."
53
 AMF.H264.EnforceHRDCompatibility="Força la compatibilitat amb HRD"
54
+AMF.H264.EnforceHRDCompatibility.Description="Força les restriccions del descodificador hipotètic de referència que limiten el canvi de valor màxim de QP dins d'un fotograma."
55
+AMF.H264.KeyframeInterval="Interval de fotogrames clau"
56
+AMF.H264.KeyframeInterval.Description="Quants segons han d'haver entre fotogrames que no es poden descartar.\nTambé controla la mida de la seqüència (GOP)."
57
+AMF.H264.IDRPeriod="Període IDR"
58
+AMF.H264.IDRPeriod.Description="Defineix la distància entre Instantaneous Decoding Refreshes (IDR) en fotogrames. També controla la mida de la seqüència del GOP."
59
+AMF.H264.BFrame.Pattern="B-Frames"
60
+AMF.H264.BFrame.Pattern.Description="La quantitat de B-Frames a utilitzar mestre es codifica.\nCompatible amb targetes de 2ª i 3ª generació VCE. Impacte negatiu en el rendiment de codificació."
61
+AMF.H264.BFrame.DeltaQP="Delta QP per B-Frames"
62
+AMF.H264.BFrame.DeltaQP.Description="Valor Delta QP per al darrer I- o P-Frame per B-Frames no referenciables."
63
+AMF.H264.BFrame.Reference="B-Frames referenciables"
64
+AMF.H264.BFrame.Reference.Description="Permet a un B-Frames utilitzar també B-Frames com referència, enlloc de P- i I-Frames."
65
+AMF.H264.BFrame.ReferenceDeltaQP="Delta QP per als fotogrames referenciables"
66
+AMF.H264.BFrame.ReferenceDeltaQP.Description="Valor Delta QP per al darrer I- o P-Frame per B-Frames referenciables."
67
 AMF.H264.DeblockingFilter="Filtre d'eliminació de blocs"
68
+AMF.H264.DeblockingFilter.Description="Estableix l'indicador que el descodificador està permès a utilitzar el Filtre d'eliminació de blocs per a la transmissió codificada."
69
 AMF.H264.ScanType="Tipus d'exploració"
70
+AMF.H264.ScanType.Description="Quin mètode de escaneig utilitzar, deixeu-lo sempre a '\@AMF.H264.ScanType.Progressive\@'."
71
 AMF.H264.ScanType.Progressive="Progressiu"
72
 AMF.H264.ScanType.Interlaced="Entrellaçat"
73
+AMF.H264.MotionEstimation="Estimació del moviment"
74
+AMF.H264.MotionEstimation.Description="L'estimació del moviment permet al codificador reduir el flux de dades necessari calculant d'on vénen els píxels."
75
 AMF.H264.MotionEstimation.None="Cap"
76
 AMF.H264.MotionEstimation.Half="Meitat de píxel"
77
 AMF.H264.MotionEstimation.Quarter="Quart de Píxel"
78
+AMF.H264.MotionEstimation.Both="Meitat i quart de píxel"
79
+AMF.H264.CodingType="Tipus de codificació"
80
+AMF.H264.CodingType.Description="Quin tipus de codificació utilitzar:\n* \@AMF.Util.Default\@ deixeu que AMF ho decideixi (recomanat).\n* CALVC (Context-Adaptive Variable-Length Coding) és més ràpid, però mes gran.\n* CABAC (Context-Adaptive Binary Arithmetic Coding) es més lent, però més petit."
81
 AMF.H264.MaximumLTRFrames="Fotogrames màxims LTR"
82
+AMF.H264.MaximumLTRFrames.Description="Fotogrames de referència a llarg plaç (LTR) és una característica que permet al codificador marcar certs marcs en una seqüencia com referents per un llarg temps.\nEls fotogrames LTR no poden ser utilitzats amb B-Pictures i el codificador desactivarà B-Pictures si s'utilitza."
83
+AMF.H264.MaximumAccessUnitSize="Mida màxima de la unitat d'accés"
84
+AMF.H264.MaximumAccessUnitSize.Description="Mida d'una unitat d'accés per a una NAL."
85
+AMF.H264.HeaderInsertionSpacing="Espaiat d'inserció de capçaleres"
86
+AMF.H264.HeaderInsertionSpacing.Description="Quants fotogrames han d'haver entre capçaleres NAL."
87
+AMF.H264.WaitForTask="Espera per la tasca"
88
+AMF.H264.WaitForTask.Description="Desconegut, Experimental"
89
+AMF.H264.PreAnalysisPass="Passada d'anàlisi previ"
90
+AMF.H264.PreAnalysisPass.Description="Desconegut, Experimental"
91
+AMF.H264.VBAQ="VBAQ"
92
+AMF.H264.VBAQ.Description="Desconegut, Experimental"
93
+AMF.H264.GOPSize="Mida del GOP"
94
+AMF.H264.GOPSize.Description="Desconegut, Experimental"
95
+AMF.H264.GOPAlignment="Alineació del GOP"
96
+AMF.H264.GOPAlignment.Description="Desconegut, Experimental"
97
+AMF.H264.MaximumReferenceFrames="Fotogrames de referència màxims"
98
+AMF.H264.MaximumReferenceFrames.Description="Desconegut, Experimental"
99
+AMF.H264.SlicesPerFrame="Porcions per fotograma"
100
+AMF.H264.SlicesPerFrame.Description="Quantes porcions I-Frame han de ser emmagatzemats en cada fotograma?\nUn valor de 0 permet al codificador decidir sobre la marxa.\nLa codificació Intra-Refresh és usada per a una reproducció i exploració més fluïda."
101
+AMF.H264.SliceMode="Mode de porcions"
102
+AMF.H264.SliceMode.Description="Desconegut, Experimental"
103
+AMF.H264.MaximumSliceSize="Mida màxima de la porció"
104
+AMF.H264.MaximumSliceSize.Description="Desconegut, Experimental"
105
+AMF.H264.SliceControlMode="Mode de control de la porció"
106
+AMF.H264.SliceControlMode.Description="Desconegut, Experimental"
107
+AMF.H264.SliceControlSize="Control de mida de la porció"
108
+AMF.H264.SliceControlSize.Description="Desconegut, Experimental"
109
+AMF.H264.IntraRefresh.NumberOfStripes="Numero de línies Intra-Refresh"
110
+AMF.H264.IntraRefresh.NumberOfStripes.Description="Desconegut, Experimental"
111
+AMF.H264.IntraRefresh.MacroblocksPerSlot="Macroblocs intra-refresh per Slot"
112
+AMF.H264.IntraRefresh.MacroblocksPerSlot.Description="Quants macroblocs han de ser emmagatzemats en cada slot?\nUn valor de 0 desactiva aquesta funció.\nLa codificació Intra-Refresh és usada per a una reproducció i exploració més fluïda."
113
+AMF.H264.VideoAPI="API de vídeo"
114
+AMF.H264.VideoAPI.Description="Quina API utilitzar per la codificació."
115
+AMF.H264.VideoAdapter="Adaptador de vídeo"
116
+AMF.H264.VideoAdapter.Description="Quin adaptador utilitzar per la codificació."
117
+AMF.H264.OpenCL="OpenCL"
118
+AMF.H264.OpenCL.Description="El codificador hauria d'utilitzar OpenCL per presentar els fotogrames individuals?"
119
 AMF.H264.View="Mode de visualització"
120
 AMF.H264.View.Description="Quines propietats han de ser visibles. No rebreu suport si feu servir el mode de vista 'Expert' o 'Màster'."
121
 AMF.H264.View.Basic="Bàsic"
122
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/da-DK.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/da-DK.ini Changed
31
 
1
@@ -1,15 +1,29 @@
2
 AMF.Util.Default="Standard"
3
+AMF.Util.Automatic="Automatisk"
4
+AMF.Util.Manual="Manuelt"
5
 AMF.Util.Toggle.Disabled="Deaktiveret"
6
 AMF.Util.Toggle.Enabled="Aktiveret"
7
+AMF.H264.Preset="Forudindstillinger"
8
+AMF.H264.Preset.ResetToDefaults="Nulstil til standarder"
9
+AMF.H264.Preset.Recording="Optagelse"
10
+AMF.H264.Preset.HighQuality="Højkvalitet"
11
+AMF.H264.Preset.Indistinguishable="Indistingverbar"
12
+AMF.H264.Preset.Lossless="Tabsfri"
13
+AMF.H264.Preset.YouTube="YouTube"
14
+AMF.H264.Usage="Anvendelse"
15
+AMF.H264.Usage.Description="Hvilken anvendelse AMF bør indstilles til:\n- '\@AMF.H264.Usage.Transcoding\@' er omkodning til generelle formål (anbefalet),\n - '\@AMF.H264.Usage.UltraLowLatency\@' er til virkelig lav-forsinkelseskodning,\n- '\@AMF.H264.Usage.LowLatency\@' er tilsvarende ovennævnte med en lidt større forsinkelse.\nStreaming understøtter kun '\@AMF.H264.Usage.Transcoding\@', alle andre værdier kan benyttes til optagelse."
16
 AMF.H264.Usage.Transcoding="Transcoding"
17
 AMF.H264.Usage.UltraLowLatency="Ekstrem Lav Ventetid"
18
 AMF.H264.Usage.LowLatency="Lav Ventetid"
19
 AMF.H264.QualityPreset="Kvalitets profiler"
20
+AMF.H264.QualityPreset.Description="Hvilken Kvalitetsforudindstilling AMF bør forsøges målrettet imod:\n- '\@AMF. H264. QualityPreset.Speed\@' er den hurtigste, men har den ringeste kvalitet,\n- '\@AMF. H264. QualityPreset.Balanced\@' er en balanceret blanding af begge,\n- '\@AMF. H264. QualityPreset.Quality\@' giver den bedste kvalitet for en given bithastighed."
21
 AMF.H264.QualityPreset.Speed="Hastighed (Dårligste kvalitet)"
22
 AMF.H264.QualityPreset.Balanced="Balanceret (Mellem Kvalitet)"
23
 AMF.H264.QualityPreset.Quality="Kvalitet (Bedste Kvalitet)"
24
 AMF.H264.Profile="Profil"
25
+AMF.H264.Profile.Description="Hvilken H.264-profil at benytte til kodning, sorteret fra højeste kvalitet til mest udbredte understøttelse."
26
 AMF.H264.ProfileLevel="Profil Niveau"
27
+AMF.H264.ProfileLevel.Description="Hvilket H.264-profilniveau at benytte til kodning:\n- ' \@AMF. Util.Automatic\@' beregner det best profilniveau for en given billedhastighed og -størrelse,\n- '4.1' understøtter 1920x1080 30FPS, 1280x720 60FPS, 960x540 90FPS\n- '4.2' understøtter 1920x1080 60FPS, 1280x720 120FPS, 960x540 172FPS\n- '5.0' understøtter 1920x1080 60FPS, 1280x720 144FPS, 960x540 172FPS\n- '5.1' understøtter 3840x2160 30FPS, 1920x1080 120FPS, 1280x720 172FPS, 960x540 172FPS\n- '5.2' understøtter 3840x2160 60FPS, 1920x1080 172FPS, 1280x720 172FPS, 960 x 540 172 FPS"
28
 AMF.H264.RateControlMethod="Rate Control Method"
29
 AMF.H264.RateControlMethod.CQP="Constant QP (CQP)"
30
 AMF.H264.RateControlMethod.CBR="Constant Bitrate (CBR)"
31
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/eu-ES.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/eu-ES.ini Changed
14
 
1
@@ -70,7 +70,12 @@
2
 AMF.H264.SliceControlMode.Description="Ezezaguna, esperimentala"
3
 AMF.H264.SliceControlSize.Description="Ezezaguna, esperimentala"
4
 AMF.H264.IntraRefresh.NumberOfStripes.Description="Ezezaguna, esperimentala"
5
+AMF.H264.VideoAPI="Bideo APIa"
6
+AMF.H264.VideoAPI.Description="Zein API erabili kodeketarako."
7
+AMF.H264.VideoAdapter="Bideo egokigailua"
8
+AMF.H264.VideoAdapter.Description="Zein egokigailu erabili kodeketarako."
9
 AMF.H264.OpenCL="OpenCL"
10
+AMF.H264.OpenCL.Description="Kodetzaileak OpenCL erabili behar du banakako fotogramak bidaltzeko?"
11
 AMF.H264.View="Ikuspegia"
12
 AMF.H264.View.Description="Zein propietate ikusi behar dira. Ez duzu laguntzarik jasoko 'Aditu' edo 'Maisu' ikuspegian."
13
 AMF.H264.View.Basic="Oinarrizkoa"
14
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/hu-HU.ini Changed
79
 
1
@@ -24,13 +24,13 @@
2
 AMF.H264.ProfileLevel="Profil szint"
3
 AMF.H264.RateControlMethod="Bitráta vezérlés"
4
 AMF.H264.RateControlMethod.CQP="Erőltetett QP (CQP)"
5
-AMF.H264.RateControlMethod.CBR="Konstans bitráta (CBR)"
6
-AMF.H264.RateControlMethod.VBR.Peak="Változó bitráta (Csúcsértéket betartva) (VBR)"
7
-AMF.H264.RateControlMethod.VBR.Latency="Változó bitráta (Késleltetés kényszerítése) (VBR_LAT)"
8
-AMF.H264.Bitrate.Target="Bitráta (Bitben)"
9
+AMF.H264.RateControlMethod.CBR="Konstans bitsebesség (CBR)"
10
+AMF.H264.RateControlMethod.VBR.Peak="Változó bitsebesség (Csúcsértéket betartva) (VBR)"
11
+AMF.H264.RateControlMethod.VBR.Latency="Változó bitsebesség (Késleltetés kényszerítése) (VBR_LAT)"
12
+AMF.H264.Bitrate.Target="Célbitsebesség"
13
 AMF.H264.Bitrate.Target.Description="Bitráta amelyet szeretne elérni a konvertálás során."
14
-AMF.H264.Bitrate.Peak="Csúcs bitráta (Bitben)"
15
-AMF.H264.Bitrate.Peak.Description="Bitráta amelyet maximálisan elérhet a konvertálás során."
16
+AMF.H264.Bitrate.Peak="Csúcs bitsebesség"
17
+AMF.H264.Bitrate.Peak.Description="Bitsebesség amelyet maximálisan elérhet a konvertálás során."
18
 AMF.H264.QP.Minimum="Minimum QP"
19
 AMF.H264.QP.Minimum.Description="Legalacsonyabb QP (Quantization Parameter) képkockában használható érték."
20
 AMF.H264.QP.Maximum="Maximum QP"
21
@@ -52,7 +52,9 @@
22
 AMF.H264.KeyframeInterval="Kulcsképkocka időköze"
23
 AMF.H264.IDRPeriod="IDR időköz"
24
 AMF.H264.BFrame.Pattern="B képkocka"
25
+AMF.H264.BFrame.Pattern.Description="A B képkockák száma kódolás közben.\nA második és harmadik generációjú VCE kártyák támogatják. Hátráltató hatása van a kódolás teljesítményére."
26
 AMF.H264.BFrame.DeltaQP="B képkocka Delta QP"
27
+AMF.H264.BFrame.DeltaQP.Description="Delta QP érték az utolsó I vagy P képkocka nem referenciálható B képkockáihoz."
28
 AMF.H264.BFrame.Reference="Referenciálható B képkockák"
29
 AMF.H264.BFrame.Reference.Description="Lehetővé teszi a B képkockák számára, hogy B képkockát referenciaként használjon, P és I képkockák helyett."
30
 AMF.H264.BFrame.ReferenceDeltaQP="Delta QP a referenciálható B kockákhoz"
31
@@ -62,6 +64,7 @@
32
 AMF.H264.ScanType.Progressive="Progresszív"
33
 AMF.H264.ScanType.Interlaced="Váltottsoros (Kísérleti)"
34
 AMF.H264.MotionEstimation="Mozgásbecslés"
35
+AMF.H264.MotionEstimation.Description="Mozdulat becslés lehetővé teszi a kódolónak, hogy csökkentse a bitsebesség követelményt a pixel elmozdulásának a felbecsülésével."
36
 AMF.H264.MotionEstimation.None="Semmi"
37
 AMF.H264.MotionEstimation.Half="Fél-pixel"
38
 AMF.H264.MotionEstimation.Quarter="Negyed-pixel"
39
@@ -69,20 +72,39 @@
40
 AMF.H264.CodingType="Kódolás típusa"
41
 AMF.H264.MaximumLTRFrames="Maximális LTR képkocka"
42
 AMF.H264.MaximumAccessUnitSize="Hozzáférési egység maximális mérete"
43
+AMF.H264.MaximumAccessUnitSize.Description="NAL számára a legnagyobb elérési egység."
44
+AMF.H264.HeaderInsertionSpacing.Description="NAL fejlécek közötti képkockák száma."
45
+AMF.H264.WaitForTask="Feladatra várakozás"
46
+AMF.H264.WaitForTask.Description="Ismeretlen, kísérleti"
47
 AMF.H264.PreAnalysisPass="Elemzés előtti fázis"
48
+AMF.H264.PreAnalysisPass.Description="Ismeretlen, kísérleti"
49
 AMF.H264.VBAQ="VBAQ"
50
+AMF.H264.VBAQ.Description="Ismeretlen, kísérleti"
51
 AMF.H264.GOPSize="GOP méret"
52
+AMF.H264.GOPSize.Description="Ismeretlen, kísérleti"
53
 AMF.H264.GOPAlignment="GOP igazítás"
54
+AMF.H264.GOPAlignment.Description="Ismeretlen, kísérleti"
55
 AMF.H264.MaximumReferenceFrames="Maximális referencia képkockák"
56
+AMF.H264.MaximumReferenceFrames.Description="Ismeretlen, kísérleti"
57
 AMF.H264.SlicesPerFrame="Szeletelés képkockánként"
58
 AMF.H264.SliceMode="Szelet mód"
59
+AMF.H264.SliceMode.Description="Ismeretlen, kísérleti"
60
 AMF.H264.MaximumSliceSize="Maximális szeletméret"
61
+AMF.H264.MaximumSliceSize.Description="Ismeretlen, kísérleti"
62
+AMF.H264.SliceControlMode="Szelet ellenőrzési mód"
63
+AMF.H264.SliceControlMode.Description="Ismeretlen, kísérleti"
64
+AMF.H264.SliceControlSize="Szeletméret ellenőrzés"
65
+AMF.H264.SliceControlSize.Description="Ismeretlen, kísérleti"
66
+AMF.H264.IntraRefresh.NumberOfStripes.Description="Ismeretlen, kísérleti"
67
+AMF.H264.IntraRefresh.MacroblocksPerSlot.Description="Hány makroblokkot tároljon céllánként?\nA 0 érték kikapcsolja a funkciót.\nIntra-Refresh kódolás a gyorsabb lejátszáshoz és kereséshez használható."
68
 AMF.H264.VideoAPI="Videó API"
69
 AMF.H264.VideoAPI.Description="Melyik API használható kódoláshoz."
70
 AMF.H264.VideoAdapter="Videó adapter"
71
 AMF.H264.VideoAdapter.Description="Melyik adapter használható kódoláshoz."
72
 AMF.H264.OpenCL="OpenCL"
73
+AMF.H264.OpenCL.Description="A kódolós használhat OpenCL-t az egyes képkockák elkészítéséhez?"
74
 AMF.H264.View="Nézet mód"
75
+AMF.H264.View.Description="Milyen tulajdonságok jelenjenek meg?\nA '\@AMF.H264.View.Master\@' használata kizárja a támogatásban való részesülésből."
76
 AMF.H264.View.Basic="Alap"
77
 AMF.H264.View.Advanced="Haladó"
78
 AMF.H264.View.Expert="Szakértő"
79
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/it-IT.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/it-IT.ini Changed
25
 
1
@@ -59,7 +59,23 @@
2
 AMF.H264.MaximumAccessUnitSize="Massima dimensione di unità d'accesso"
3
 AMF.H264.HeaderInsertionSpacing="Spaziatura di inserimento di intestazione"
4
 AMF.H264.WaitForTask="Attendere per attività"
5
+AMF.H264.WaitForTask.Description="Sconosciuto, sperimentale"
6
+AMF.H264.PreAnalysisPass="Analisi pre-pass"
7
+AMF.H264.PreAnalysisPass.Description="Sconosciuto, sperimentale"
8
+AMF.H264.VBAQ="VBAQ"
9
+AMF.H264.VBAQ.Description="Sconosciuto, sperimentale"
10
+AMF.H264.GOPSize="Dimensione del GOP"
11
+AMF.H264.GOPSize.Description="Sconosciuto, sperimentale"
12
+AMF.H264.GOPAlignment="Allineamento del GOP"
13
+AMF.H264.GOPAlignment.Description="Sconosciuto, sperimentale"
14
+AMF.H264.MaximumReferenceFrames="Numero massimo di frames di riferimento"
15
+AMF.H264.MaximumReferenceFrames.Description="Sconosciuto, sperimentale"
16
 AMF.H264.SlicesPerFrame="Slices Per Frame"
17
+AMF.H264.SliceMode="Modalità Slice"
18
+AMF.H264.SliceMode.Description="Sconosciuto, sperimentale"
19
+AMF.H264.MaximumSliceSize="Dimensione massima frame"
20
+AMF.H264.MaximumSliceSize.Description="Sconosciuto, sperimentale"
21
+AMF.H264.SliceControlMode="Modalità di controllo Slice"
22
 AMF.H264.View="Modalità di visualizzazione"
23
 AMF.H264.View.Basic="Basico"
24
 AMF.H264.View.Advanced="Avanzate"
25
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/ko-KR.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/ko-KR.ini Changed
18
 
1
@@ -63,6 +63,7 @@
2
 AMF.H264.KeyframeInterval.Description="손실이 불가능한 프레임 사이에 얼마나 많은 시간(초)이 필요한지 설정합니다.\n또한 영상(GOP) 크기도 제어합니다."
3
 AMF.H264.IDRPeriod="IDR 주기"
4
 AMF.H264.IDRPeriod.Description="프레임 내에서 순간 복호 갱신(nstantaneous Decoding Refreshes) 사이의 거리를 설정합니다. 또한, GOP-장면 크기를 제어합니다."
5
+AMF.H264.BFrame.Pattern="B-화면"
6
 AMF.H264.BFrame.Pattern.Description="인코딩에 얼마나 많은 B-화면을 사용할지 설정합니다.\n2, 3세대 VCE카드에서 지원합니다. 인코딩 성능에 부정적인 영향을 줍니다."
7
 AMF.H264.BFrame.DeltaQP="B-화면 델타 QP"
8
 AMF.H264.BFrame.DeltaQP.Description="비참조 B-화면에 쓰이는 마지막 I- 혹은P-화면의 델타 QP 값"
9
@@ -92,6 +93,8 @@
10
 AMF.H264.HeaderInsertionSpacing.Description="NAL 헤더 사이에 얼마나 많은 프레임이 필요한지 설정합니다. 0(자동)에서 바꾸는 것은 추천하지 않습니다."
11
 AMF.H264.WaitForTask="작업을 대기"
12
 AMF.H264.WaitForTask.Description="알수 없음, 실험적인 기능"
13
+AMF.H264.PreAnalysisPass="사전분석 처리"
14
+AMF.H264.PreAnalysisPass.Description="알수 없음, 실험적인 기능"
15
 AMF.H264.VBAQ="VBAQ"
16
 AMF.H264.VBAQ.Description="알수 없음, 실험적인 기능"
17
 AMF.H264.GOPSize="GOP 크기"
18
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/nl-NL.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/nl-NL.ini Changed
131
 
1
@@ -1,8 +1,10 @@
2
 AMF.Util.Default="Standaard"
3
 AMF.Util.Automatic="Automatisch"
4
+AMF.Util.Manual="Handmatig"
5
 AMF.Util.Toggle.Disabled="Uitgeschakeld"
6
 AMF.Util.Toggle.Enabled="Ingeschakeld"
7
 AMF.H264.Preset="Voorkeursinstelling"
8
+AMF.H264.Preset.ResetToDefaults="Standaardinstellingen herstellen"
9
 AMF.H264.Preset.Recording="Opname"
10
 AMF.H264.Preset.HighQuality="Hoge kwaliteit"
11
 AMF.H264.Preset.Indistinguishable="Ononderscheidbaar"
12
@@ -15,31 +17,118 @@
13
 AMF.H264.Usage.UltraLowLatency="Ultra Low Latency"
14
 AMF.H264.Usage.LowLatency="Low Latency"
15
 AMF.H264.QualityPreset="Kwaliteitsinstelling"
16
+AMF.H264.QualityPreset.Description="Welke kwaliteitsinstelling AMF moet proberen te halen:\n- '\@AMF.H264.QualityPreset.Speed\@' is de snelste maar heeft de slechtste kwaliteit,\n- '\@AMF.H264.QualityPreset.Balanced\@' is een gebalanceerde mix van beide,\n- '\@AMF.H264.QualityPreset.Quality\@' geeft de beste kwaliteit voor een gekozen bitrate."
17
 AMF.H264.QualityPreset.Speed="Snelheid"
18
 AMF.H264.QualityPreset.Balanced="Gebalanceerd"
19
 AMF.H264.QualityPreset.Quality="Kwaliteit"
20
 AMF.H264.Profile="Profiel"
21
+AMF.H264.Profile.Description="Welk h.264 profiel gebruikt moet worden, gesorteerd van beste kwaliteit tot breedste ondersteuning."
22
 AMF.H264.ProfileLevel="Profielniveau"
23
 AMF.H264.ProfileLevel.Description="Welk H.264 profielniveau moet worden gebruikt voor encoden:\n- 'Automatisch' berekent het beste profielniveau voor de gebruikte framerate en framegrootte.\n- '4.1' ondersteunt 1920x1080 30FPS, 1280x720 60FPS, 960x540 90FPS\n- '4.2' ondersteunt 1920x1080 60FPS, 1280x720 120FPS, 960x540 172FPS\n- '5.0' ondersteunt1920x1080 60FPS, 1280x720 144FPS, 960x540 172FPS\n- '5.1' ondersteunt3840x2160 30FPS, 1920x1080 120FPS, 1280x720 172FPS, 960x540 172FPS\n- '5.2' ondersteunt 3840x2160 60FPS, 1920x1080 172FPS, 1280x720 172FPS, 960x540 172FPS"
24
 AMF.H264.RateControlMethod="Rate control methode"
25
+AMF.H264.RateControlMethod.Description="Welke rate control methode gebruikt moet worden:\n- '\@AMF.H264.RateControlMethod.CQP\@' kent vaste I-/P-/B-Frame QP waardes toe,\n- '\@AMF.H264.RateControlMethod.CBR\@' blijft op de insgestelde doelbitrate (met opvuldata) (aanbevolen voor streamen),\n- '\@AMF.H264.RateControlMethod.VBR\@' blijft onder de ingestelde piek bitrate,\n- '\@AMF.H264.RateControlMethod.VBR_LAT\@' blijft in de buurt van de doelbitrate als de GPU latency en belasting het toestaan, anders zal er een hogere bitrate worden gebruikt (aanbevolen voor opnames)."
26
 AMF.H264.RateControlMethod.CQP="Constant QP (CQP)"
27
 AMF.H264.RateControlMethod.CBR="Constant Bitrate (CBR)"
28
 AMF.H264.RateControlMethod.VBR.Peak="Variable Bitrate (Peak Constrained) (VBR)"
29
 AMF.H264.RateControlMethod.VBR.Latency="Variable Bitrate (Latency Constrained) (VBR_LAT)"
30
 AMF.H264.Bitrate.Target="Doelbitrate"
31
+AMF.H264.Bitrate.Target.Description="Bitrate om te proberen aan te houden in de gehele reeks."
32
 AMF.H264.Bitrate.Peak="Maximale bitrate"
33
+AMF.H264.Bitrate.Peak.Description="Bitrate om in de gehele reeks maximaal naartoe te pieken."
34
 AMF.H264.QP.Minimum="Minimale QP"
35
+AMF.H264.QP.Minimum.Description="Laagste QP waarde om te gebruiken in een frame."
36
 AMF.H264.QP.Maximum="Maximale QP"
37
+AMF.H264.QP.Maximum.Description="Hoogste QP waarde om te gebruiken in een frame."
38
 AMF.H264.QP.IFrame="I-Frame QP"
39
+AMF.H264.QP.IFrame.Description="Vaste QP waarde om te gebruiken voor I-frames."
40
 AMF.H264.QP.PFrame="P-Frame QP"
41
+AMF.H264.QP.PFrame.Description="Vaste QP waarde om te gebruiken voor P-frames."
42
 AMF.H264.QP.BFrame="B-Frame QP"
43
+AMF.H264.QP.BFrame.Description="Vaste QP waarde om te gebruiken voor B-frames."
44
 AMF.H264.VBVBuffer="VBV Buffer"
45
+AMF.H264.VBVBuffer.Description="Welke methode moet worden gebruikt om de VBV buffergrootte te bepalen:\n- '\@AMF.Util.Automatic\@' berekent de grootte met een strengheid-instelling.\n- '\@AMF.Util.Manual\@' laat de gebruiker de grootte bepalen.\nVBV (Video Buffering Verifier) buffer wordt gebruikt door bepaalde Rate Control methodes om de algehele bitrate binnen de aangegeven perken te houden."
46
+AMF.H264.VBVBuffer.Strictness="VBV Buffer-strengheid"
47
+AMF.H264.VBVBuffer.Strictness.Description="Bepaalt de strengheid van de VBV buffer, waar 100% zo streng mogelijk is, en 0% geen restricties oplegt."
48
+AMF.H264.VBVBuffer.Size="VBV Buffergrootte"
49
+AMF.H264.VBVBuffer.Size.Description="De grootte van de VBV Buffer welke wordt gebruikt voor bitrate controle in een reeks."
50
+AMF.H264.VBVBuffer.Fullness="VBV Buffervulling"
51
+AMF.H264.VBVBuffer.Fullness.Description="Hoe vol de VBV Buffer initieel is, beïnvloedt alleen de initiële reeks van encoden."
52
 AMF.H264.FillerData="Opvuldata"
53
+AMF.H264.FillerData.Description="Inschakelen van opvuldata laat de encoder tenminste de doelbitrate aanhouden door de overtollige ruimte in een reeks te vullen met lege informatie."
54
 AMF.H264.FrameSkipping="Frames overslaan"
55
+AMF.H264.FrameSkipping.Description="Frame Skipping laat een encoder frames droppen om de doelbitrate te halen.\nAls de encoder een frame dropt vult het een herhaal-laatste-frame NAL in de stream.\nKan helpen bij erg lage doelbitrates."
56
 AMF.H264.EnforceHRDCompatibility="Forceer HDR compatibiliteit"
57
+AMF.H264.EnforceHRDCompatibility.Description="Forceer hypothetische referentiedecoder-restricties welke de maximale QP waarde veranderen binnen een frame."
58
+AMF.H264.KeyframeInterval="Keyframe-Interval"
59
+AMF.H264.KeyframeInterval.Description="Bepaalt de afstand tussen keyframes in seconden. Bepaalt ook de GOP-sequence size."
60
+AMF.H264.IDRPeriod="IDR Periode"
61
+AMF.H264.IDRPeriod.Description="Bepaalt de afstand tussen Instantaneous Decoding Refreshes (IDR) in frames. Bepaalt ook de GOP-sequence size."
62
+AMF.H264.BFrame.Pattern="B-frames"
63
+AMF.H264.BFrame.Pattern.Description="Het aantal B-frames om te gebruiken tijdens het encoden.\nOndersteund door 2e en 3e generatie VCE-kaarten. Negatieve invloed op encodingprestaties."
64
+AMF.H264.BFrame.DeltaQP="Delta QP voor B-frames"
65
+AMF.H264.BFrame.DeltaQP.Description="Delta QP waarde tot de laatste I- of P-frame voor niet-refereerbare B-frames."
66
+AMF.H264.BFrame.Reference="Refereerbare B-frames"
67
+AMF.H264.BFrame.Reference.Description="Laat een B-frame ook B-frames gebruiken als referentie, in plaats van enkel P- en I-frames."
68
+AMF.H264.BFrame.ReferenceDeltaQP="Delta QP voor refereerbare B-frames"
69
+AMF.H264.BFrame.ReferenceDeltaQP.Description="Delta QP waarde tot de laatste I- of P-frame voor refereerbare B-frames."
70
 AMF.H264.DeblockingFilter="Deblocking Filter"
71
+AMF.H264.DeblockingFilter.Description="Staat de encoder toe om een Deblocking Filter te gebruiken voor de gecodeerde stream."
72
 AMF.H264.ScanType="Scantype"
73
+AMF.H264.ScanType.Description="Welke scanmethode gebruikt moet worden, laat dit altijd op '\@AMF.H264.ScanType.Progressive\@'."
74
 AMF.H264.ScanType.Progressive="Progressive"
75
 AMF.H264.ScanType.Interlaced="Interlaced"
76
+AMF.H264.MotionEstimation="Bewegingsschatting"
77
+AMF.H264.MotionEstimation.Description="Bewigingsschatting laat de encoder de benodigde bitrate verlagen door te schatten waar een pixel heen ging."
78
+AMF.H264.MotionEstimation.None="Geen"
79
+AMF.H264.MotionEstimation.Half="Halve pixel"
80
+AMF.H264.MotionEstimation.Quarter="Kwartpixel"
81
+AMF.H264.MotionEstimation.Both="Halve en kwartpixel"
82
+AMF.H264.CodingType="Codeertype"
83
+AMF.H264.CodingType.Description="Welk codeertype gebruikt moet worden:\n* \@AMF.Util.Default\@ laat AMF bepalen (aanbevolen).\n* CALVC (Context-Adaptive Variable-Length Coding) is sneller, maar groter.\n* CABAC (Context-Adaptive Binary Arithmetic Coding) is langzamer, maar kleiner."
84
 AMF.H264.MaximumLTRFrames="Maximale LTR Frames"
85
+AMF.H264.MaximumLTRFrames.Description="Long Term Reference (LTR) frames zijn een functie waarmee de encoder bepaalde frames in een reeks kan aanmerken als refereerbaar gedurende een lange tijd.\nLTR frames kunnen niet met B-frames gebruikt worden, en de encoder zal B-frames ook uitzetten als deze gebruikt worden."
86
+AMF.H264.MaximumAccessUnitSize="Maximale Access Unit grootte"
87
+AMF.H264.MaximumAccessUnitSize.Description="De maximale grootte voor een Access Unit voor een NAL."
88
+AMF.H264.HeaderInsertionSpacing="Header Insertion Spacing"
89
+AMF.H264.HeaderInsertionSpacing.Description="Hoeveel frames er tussen NAL headers moeten zitten."
90
+AMF.H264.WaitForTask="Wacht op taak"
91
+AMF.H264.WaitForTask.Description="Onbekend, experimenteel"
92
+AMF.H264.PreAnalysisPass="Pre-analyse pass"
93
+AMF.H264.PreAnalysisPass.Description="Onbekend, experimenteel"
94
+AMF.H264.VBAQ="VBAQ"
95
+AMF.H264.VBAQ.Description="Onbekend, experimenteel"
96
+AMF.H264.GOPSize="GOP-grootte"
97
+AMF.H264.GOPSize.Description="Onbekend, experimenteel"
98
+AMF.H264.GOPAlignment="GOP-uitlijning"
99
+AMF.H264.GOPAlignment.Description="Onbekend, experimenteel"
100
+AMF.H264.MaximumReferenceFrames="Maximale referentieframes"
101
+AMF.H264.MaximumReferenceFrames.Description="Onbekend, experimenteel"
102
+AMF.H264.SlicesPerFrame="Segmenten per frame"
103
+AMF.H264.SlicesPerFrame.Description="Hoeveel I-frame segmenten moeten er worden opgeslagen bij elke frame?\nEen waarde van nul laat de encoder bepalen.\nIntra-refresh encoding wordt gebruikt voor snellere weergave van en zoeken door video."
104
+AMF.H264.SliceMode="Slice-modus"
105
+AMF.H264.SliceMode.Description="Onbekend, experimenteel"
106
+AMF.H264.MaximumSliceSize="Maximale Segmentgrootte"
107
+AMF.H264.MaximumSliceSize.Description="Onbekend, experimenteel"
108
+AMF.H264.SliceControlMode="Slice Control Mode"
109
+AMF.H264.SliceControlMode.Description="Onbekend, experimenteel"
110
+AMF.H264.SliceControlSize="Slice Control Size"
111
+AMF.H264.SliceControlSize.Description="Onbekend, experimenteel"
112
+AMF.H264.IntraRefresh.NumberOfStripes="Intra-Refresh Number of Stripes"
113
+AMF.H264.IntraRefresh.NumberOfStripes.Description="Onbekend, experimenteel"
114
+AMF.H264.IntraRefresh.MacroblocksPerSlot="Intra-Refresh Macroblocks per Slot"
115
+AMF.H264.IntraRefresh.MacroblocksPerSlot.Description="Hoeveel Macroblocks moeten er in elk slot worden opgeslagen?\nEen waarde van 0 schakelt deze functie uit.\nIntra-Refresh encoding wordt gebruikt voor snellere weergave van en zoeken door video."
116
+AMF.H264.VideoAPI="Video API"
117
+AMF.H264.VideoAPI.Description="Welke API gebruikt moet worden voor encoden."
118
+AMF.H264.VideoAdapter="Videoadapter"
119
+AMF.H264.VideoAdapter.Description="Welke apter gebruikt moet worden voor encoding."
120
+AMF.H264.OpenCL="OpenCL"
121
+AMF.H264.OpenCL.Description="Moet de encoder OpenCL gebruiken om de individuele frames te leveren?"
122
+AMF.H264.View="Weergavemodus"
123
+AMF.H264.View.Description="Welke eigenschappen moeten getoond worden?\nHet gebruiken van '\@AMF.H264.View.Master\@' diskwalificeert je voor het ontvangen van ondersteuning."
124
+AMF.H264.View.Basic="Simpel"
125
+AMF.H264.View.Advanced="Geavanceerd"
126
+AMF.H264.View.Expert="Expert"
127
+AMF.H264.View.Master="Meester"
128
+AMF.H264.Debug="Debug"
129
+AMF.H264.Debug.Description="Schakel extra debug-logging in, dit moet actief zijn als je ondersteuning nodig hebt met deze encoder."
130
 
131
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/pl-PL.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/pl-PL.ini Changed
13
 
1
@@ -59,6 +59,11 @@
2
 AMF.H264.ScanType="Metoda skanowania"
3
 AMF.H264.ScanType.Progressive="Progresywne"
4
 AMF.H264.ScanType.Interlaced="Z przeplotem"
5
+AMF.H264.MotionEstimation="Szacowania ruchu"
6
+AMF.H264.MotionEstimation.None="Żaden"
7
+AMF.H264.MotionEstimation.Half="Pół piksela"
8
+AMF.H264.MotionEstimation.Quarter="Kwartał piksela"
9
+AMF.H264.MotionEstimation.Both="Pół i kwartał piksela"
10
 AMF.H264.CodingType="Typ kodowania"
11
 AMF.H264.MaximumAccessUnitSize="Maksymalny rozmiar Access Unit"
12
 AMF.H264.MaximumAccessUnitSize.Description="Maksymalny rozmiar Access Unit. Wartość 0 umożliwia enkoderowi wybranie najlepszej wartości."
13
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/ru-RU.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/ru-RU.ini Changed
98
 
1
@@ -22,9 +22,11 @@
2
 AMF.H264.QualityPreset.Balanced="Баланс"
3
 AMF.H264.QualityPreset.Quality="Качество"
4
 AMF.H264.Profile="Профиль кодирования"
5
+AMF.H264.Profile.Description="Какой профиль формата H.264, использовать для кодирования, отсортированный от высочайшего качества для самой широкой поддержки."
6
 AMF.H264.ProfileLevel="Уровень профиля"
7
 AMF.H264.ProfileLevel.Description="Какой уровень профиля H.264 использовать для кодирования:\n- 'Автоматически' выбирает наиболее подходящий уровень под выбранную частоту и размер кадра,\n- '4.1' поддерживает 1920x1080 30FPS, 1280x720 60FPS, 960x540 90FPS\n- '4.2' поддерживает 1920x1080 60FPS, 1280x720 120FPS, 960x540 172FPS\n- '5.0' поддерживает 1920x1080 60FPS, 1280x720 144FPS, 960x540 172FPS\n- '5.1' поддерживает 3840x2160 30FPS, 1920x1080 120FPS, 1280x720 172FPS, 960x540 172FPS\n- '5.2' поддерживает 3840x2160 60FPS, 1920x1080 172FPS, 1280x720 172FPS, 960x540 172FPS"
8
 AMF.H264.RateControlMethod="Метод кодирования"
9
+AMF.H264.RateControlMethod.Description="Как оценить способ контроля должны быть использованы:\n- '\@AMF.H264.RateControlMethod.CQP\@' назначает фиксированные I-/P-/B-Значения кадра QP,\n- '\@AMF.H264.RateControlMethod.CBR\@' остается в данном целевом Битрейте (используя данные заполнителя) (рекомендуется для стрима),\n-'\@AMF.H264.RateControlMethod.VBR\@' остается ниже пика Битрейта,\n-'\@AMF.H264.RateControlMethod.VBR_LAT\@' остается близко к целевому Битрейту, если задержка GPU и нагрузки позволяют, в противном случае будут использовать более высокий Битрейт (рекомендуется для стрима)."
10
 AMF.H264.RateControlMethod.CQP="CQP: постоянное качество"
11
 AMF.H264.RateControlMethod.CBR="CBR: постоянный битрейт"
12
 AMF.H264.RateControlMethod.VBR.Peak="VBR: переменный битрейт (Ограничение пиков)"
13
@@ -38,22 +40,37 @@
14
 AMF.H264.QP.Maximum="Максимальное QP"
15
 AMF.H264.QP.Maximum.Description="Наибольшее значение QP (Параметр квантования) для использования в кадре."
16
 AMF.H264.QP.IFrame="I-кадр QP"
17
+AMF.H264.QP.IFrame.Description="Фиксированное значение QP используемое для I-Кадров."
18
 AMF.H264.QP.PFrame="P-кадр QP"
19
+AMF.H264.QP.PFrame.Description="Фиксированное значение QP используемое для P-Кадров."
20
 AMF.H264.QP.BFrame="B-кадр QP"
21
 AMF.H264.QP.BFrame.Description="Фиксированное значение QP (Параметр квантования) для использования в B-Кадрах."
22
 AMF.H264.VBVBuffer="Буфер VBV"
23
 AMF.H264.VBVBuffer.Description="Какой метод следует использовать для определения Размера буфера VBV:\n- '\@AMF.Util.Automatic\@' рассчитывает размер ограничивающийся строгостью,\n- '\@AMF.Util.Manual\@' позволяет пользователю контролировать размер буфера.\nVBV (Верификатор буферизации видео) буфер используется некоторыми Методами управления скоростью, чтобы сохранить общий битрейт в пределах заданных ограничений."
24
 AMF.H264.VBVBuffer.Strictness="Строгость буфера VBV"
25
+AMF.H264.VBVBuffer.Strictness.Description="Определяет жесткость буфера vbv, при 100% будет максимально жестким и 0% будет неограниченным."
26
 AMF.H264.VBVBuffer.Size="Размер буфера VBV"
27
+AMF.H264.VBVBuffer.Size.Description="Размер буфера vbv, которая используется для управления скорости передачи данных в последовательности."
28
 AMF.H264.VBVBuffer.Fullness="Заполнение буфера VBV"
29
 AMF.H264.VBVBuffer.Fullness.Description="Изначальная степень заполнения VBV буфера, будет влиять только на первоначальную последовательность кодирования."
30
 AMF.H264.FillerData="Данные наполнителя"
31
+AMF.H264.FillerData.Description="Включение данных наполнителей позволяет кодировщику сохранять, по крайней мере, целевой Битрейт, заполняя оставшееся пространство в последовательности с пустой информации."
32
 AMF.H264.FrameSkipping="Пропуск кадров"
33
+AMF.H264.FrameSkipping.Description="Пропуск кадров позволяет кодировщику падение кадров в целях соответствия требованиям целевого битрейта.\nКогда в энкодере пропадает рамка вместо этого вставьте повторять-последний кадр NAL в стрим.\nМожет помочь с очень низким битрейтом."
34
 AMF.H264.EnforceHRDCompatibility="Принудительная HRD совместимость"
35
+AMF.H264.EnforceHRDCompatibility.Description="Соблюдение гипотетическому эталону Декодера ограничения, которые ограничивают максимальное значение QP изменения в кадре."
36
 AMF.H264.KeyframeInterval="Интервал ключевых кадров"
37
 AMF.H264.KeyframeInterval.Description="Сколько секунд должен быть просадок кадров.\nТакже контролирует GOP Size."
38
 AMF.H264.IDRPeriod="Период IDR"
39
 AMF.H264.IDRPeriod.Description="Определяет расстояние между Мгновенными обновлениями декодирования (IDR) в кадрах. Так же контролирует размер последовательности GOP."
40
+AMF.H264.BFrame.Pattern="B-Кадры"
41
+AMF.H264.BFrame.Pattern.Description="Количество B-кадров использованное при кодировании.\nПоддерживается 2-й и 3-й VCE карт поколения. Негативно влияет на производительность кодирования."
42
+AMF.H264.BFrame.DeltaQP="QP дельта для B-Кадров"
43
+AMF.H264.BFrame.DeltaQP.Description="Значение дельты QP в последних I- или P-Кадров для нессылаемых B-Кадров."
44
+AMF.H264.BFrame.Reference="Ссылаемые B-Кадры"
45
+AMF.H264.BFrame.Reference.Description="Разрешить B-Кадру так же использовать B-Кадры как ссылки, вместо просто P- и I-Кадров."
46
+AMF.H264.BFrame.ReferenceDeltaQP="Дельта QP для ссылаемых B-кадров"
47
+AMF.H264.BFrame.ReferenceDeltaQP.Description="Значение дельты QP в последних I- или P-Кадров для ссылаемых B-Кадров."
48
 AMF.H264.DeblockingFilter="Фильтр деблокинга"
49
 AMF.H264.DeblockingFilter.Description="Устанавливает флаг, что декодер может использовать фильтр удаления блочности для прямой трансляции."
50
 AMF.H264.ScanType="Развертка"
51
@@ -66,13 +83,46 @@
52
 AMF.H264.MotionEstimation.Half="Пол-пиксельная"
53
 AMF.H264.MotionEstimation.Quarter="Четверть-пиксельная"
54
 AMF.H264.MotionEstimation.Both="Пол- & Четверть-пиксельная"
55
+AMF.H264.CodingType="Тип кодирования"
56
+AMF.H264.CodingType.Description="Какой тип кодирования использовать:\n* \@AMF.Util.Default\@ позволяет решать AMF (рекомендуется).\n* CALVC (контекстно-Адаптивное с переменной длинной кодирования) - это быстрее, но больше.\n* CABAC (контекстно-Адаптивное Двоичное арифметическое кодирование) - это медленнее, но меньше."
57
 AMF.H264.MaximumLTRFrames="Максимум LTR-кадров"
58
+AMF.H264.MaximumLTRFrames.Description="Long Term Reference (LTR) Frames - функция позволяющая кодировщику помечать определенные кадры в последовательности как ссылаемые.\nLTR Frames не может использоваться B-кадры и энкодер будет отключать B-кадры, если они используются."
59
 AMF.H264.MaximumAccessUnitSize="Максимальный Размер Блока Доступа"
60
 AMF.H264.MaximumAccessUnitSize.Description="Большой размер блока доступа для NAL. Значение 0 позволяет регулировать, чтобы выбрать лучший."
61
 AMF.H264.HeaderInsertionSpacing="Расстояние вставки заголовка"
62
 AMF.H264.HeaderInsertionSpacing.Description="Сколько кадров должно быть между заголовками NAL. Не рекомендуется менять значение с 0 (автоматически)."
63
+AMF.H264.WaitForTask="Дождитесь Задач"
64
+AMF.H264.WaitForTask.Description="Неизвестно, Экспериментально"
65
+AMF.H264.PreAnalysisPass="Проход пред-анализа"
66
+AMF.H264.PreAnalysisPass.Description="Неизвестно, Экспериментально"
67
+AMF.H264.VBAQ="VBAQ"
68
+AMF.H264.VBAQ.Description="Неизвестно, Экспериментально"
69
+AMF.H264.GOPSize="Размер GOP"
70
+AMF.H264.GOPSize.Description="Неизвестно, Экспериментально"
71
+AMF.H264.GOPAlignment="Выравнивание GOP"
72
+AMF.H264.GOPAlignment.Description="Неизвестно, Экспериментально"
73
+AMF.H264.MaximumReferenceFrames="Максимум кадров-ссылок"
74
+AMF.H264.MaximumReferenceFrames.Description="Неизвестно, Экспериментально"
75
 AMF.H264.SlicesPerFrame="Количество частей на кадр"
76
 AMF.H264.SlicesPerFrame.Description="Сколько кусков I-Кадров должно быть сохранено в каждом кадре?\nЗначение 0 позволяет кодировщику выбирать \"на лету\".\nКодирование Intra-Refresh используется для быстрого воспроизведения и поиска при перемотке."
77
+AMF.H264.SliceMode="Режим Slice"
78
+AMF.H264.SliceMode.Description="Неизвестно, Экспериментально"
79
+AMF.H264.MaximumSliceSize="Максимальный размер Slice"
80
+AMF.H264.MaximumSliceSize.Description="Неизвестно, Экспериментально"
81
+AMF.H264.SliceControlMode="Режим управления Slice"
82
+AMF.H264.SliceControlMode.Description="Неизвестно, Экспериментально"
83
+AMF.H264.SliceControlSize="Размер элемента управления Slice"
84
+AMF.H264.SliceControlSize.Description="Неизвестно, Экспериментально"
85
+AMF.H264.IntraRefresh.NumberOfStripes="Число полос Intra-Refresh"
86
+AMF.H264.IntraRefresh.NumberOfStripes.Description="Неизвестно, Экспериментально"
87
+AMF.H264.IntraRefresh.MacroblocksPerSlot="Количество Intra-Refresh Макроблоков на слот"
88
+AMF.H264.IntraRefresh.MacroblocksPerSlot.Description="Сколько Макроблоков должно быть сохранено в каждом слоте?\nЗначение 0 отключает эту функцию.\nКодирование Intra-Refresh используется для быстрого воспроизведения и поиска при перемотке."
89
+AMF.H264.VideoAPI="Video API"
90
+AMF.H264.VideoAPI.Description="Какой API использовать для кодирования."
91
+AMF.H264.VideoAdapter="Видеоадаптер"
92
+AMF.H264.VideoAdapter.Description="Какой видеоадаптер использовать для кодирования."
93
+AMF.H264.OpenCL="OpenCL"
94
+AMF.H264.OpenCL.Description="Должен ли кодировщик использовать OpenCL для подтверждения индивидуальных кадров?"
95
 AMF.H264.View="Режим просмотра"
96
 AMF.H264.View.Description="Какие параметры должны быть видны. Вы не будете получать поддержку при использовании режимов 'Эксперт' и 'Мастер'."
97
 AMF.H264.View.Basic="Обычный"
98
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/sv-SE.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/sv-SE.ini Changed
60
 
1
@@ -31,15 +31,29 @@
2
 AMF.H264.Bitrate.Target.Description="Bithastighet att försöka uppnå i den övergripande sekvensen."
3
 AMF.H264.Bitrate.Peak="Maximal bithastighet"
4
 AMF.H264.QP.Minimum="Minimal QP"
5
+AMF.H264.QP.Minimum.Description="Lägsta QP-värde att använda i en bildruta."
6
 AMF.H264.QP.Maximum="Maximal QP"
7
+AMF.H264.QP.Maximum.Description="Högsta QP-värde att använda i en bildruta."
8
+AMF.H264.QP.IFrame="QP för I-bildrutor"
9
+AMF.H264.QP.IFrame.Description="Konstant QP-värde att använda för I-bildrutor."
10
+AMF.H264.QP.PFrame="QP för P-bildrutor"
11
+AMF.H264.QP.PFrame.Description="Konstant QP-värde att använda för P-bildrutor."
12
+AMF.H264.QP.BFrame="QP för B-bildrutor"
13
+AMF.H264.QP.BFrame.Description="Konstant QP-värde att använda för B-bildrutor."
14
 AMF.H264.VBVBuffer="VBV-buffert"
15
 AMF.H264.VBVBuffer.Description="Vilken metod som ska användas för att bestämma VBV-buffertens storlek:\n- '\@AMF.Util.Automatic\@' beräknar storleken med hjälp av en strikt begränsning,\n- '\@AMF.Util.Manual\@' låter användaren kontrollera storleken.\nVBV-buffertern (Video Buffering Verifier) används av vissa Rate Control Methods för att hålla den övergripande bithastigheten inom de angivna begränsningarna."
16
 AMF.H264.VBVBuffer.Strictness="Strikthet för VBV-buffert"
17
+AMF.H264.VBVBuffer.Strictness.Description="Bestämmer noggrannheten för VBV-bufferten, där 100% är så noggrann som möjligt och 0% är gränslös."
18
 AMF.H264.VBVBuffer.Size="VBV-buffertstorlek"
19
+AMF.H264.FillerData="Fyllningsdata"
20
+AMF.H264.FillerData.Description="Fyllningsdata låter kodaren behålla önskad bithastighet genom att fylla upp det återstående utrymmet i en sekvens med tom information."
21
 AMF.H264.FrameSkipping="Hoppa över bildrutor"
22
 AMF.H264.EnforceHRDCompatibility="Tvinga HRD-kompatibilitet"
23
+AMF.H264.KeyframeInterval="Intervall för keyframes"
24
+AMF.H264.KeyframeInterval.Description="Definierar avståndet mellan keyframes i sekunder. Kontrollerar även GOP-sekvensens storlek."
25
 AMF.H264.IDRPeriod="IDR-period"
26
 AMF.H264.IDRPeriod.Description="Definierar avståndet mellan Instantaneous Decoding Refreshes (IDR) i bildrutor. Kontrollerar även GOP-sekvensens storlek."
27
+AMF.H264.BFrame.Pattern="B-bildrutor"
28
 AMF.H264.DeblockingFilter="Avblockningsfilter"
29
 AMF.H264.ScanType="Typ av skanning"
30
 AMF.H264.ScanType.Description="Vilken skanningsmetod att använda, lämna alltid detta på '\@AMF.H264.ScanType.Progressive\@'."
31
@@ -54,6 +68,28 @@
32
 AMF.H264.CodingType="Kodningstyp"
33
 AMF.H264.CodingType.Description="Vilken typ av kodning som ska användas:\n* \@AMF.Util.Default\@ låter AMF bestämma (rekommenderas).\n* CALVC (Context-Adaptive Variable-Length Coding) är snabbare, men större.\n* CABAC (Context-Adaptive Binary Arithmetic Coding) är långsammare, men mindre."
34
 AMF.H264.MaximumLTRFrames="Maximalt antal LTR-bildrutor"
35
+AMF.H264.HeaderInsertionSpacing.Description="Hur många bildrutor som borde vara mellan NAL-headers."
36
+AMF.H264.WaitForTask="Väntar på arbetsuppgifter"
37
+AMF.H264.WaitForTask.Description="Okänd, experimentell"
38
+AMF.H264.PreAnalysisPass.Description="Okänd, experimentell"
39
+AMF.H264.VBAQ="VBAQ"
40
+AMF.H264.VBAQ.Description="Okänd, experimentell"
41
+AMF.H264.GOPSize="GOP-storlek"
42
+AMF.H264.GOPSize.Description="Okänd, experimentell"
43
+AMF.H264.GOPAlignment="GOP-justering"
44
+AMF.H264.GOPAlignment.Description="Okänd, experimentell"
45
+AMF.H264.MaximumReferenceFrames.Description="Okänd, experimentell"
46
+AMF.H264.SliceMode.Description="Okänd, experimentell"
47
+AMF.H264.MaximumSliceSize.Description="Okänd, experimentell"
48
+AMF.H264.SliceControlMode.Description="Okänd, experimentell"
49
+AMF.H264.SliceControlSize.Description="Okänd, experimentell"
50
+AMF.H264.IntraRefresh.NumberOfStripes.Description="Okänd, experimentell"
51
+AMF.H264.IntraRefresh.MacroblocksPerSlot.Description="Hur många Macroblock bör lagras i varje plats?\nEtt värdet på 0 inaktiverar denna funktion.\nIntra-uppdaterade kodning används för snabbare uppspelning och sökning."
52
+AMF.H264.VideoAPI="Video-API"
53
+AMF.H264.VideoAPI.Description="Vilken API att använda för kodning."
54
+AMF.H264.VideoAdapter="Grafikkort"
55
+AMF.H264.OpenCL="OpenCL"
56
+AMF.H264.OpenCL.Description="Bör kodaren använda OpenCL för att skicka de individuella bildrutorna?"
57
 AMF.H264.View="Visningsläge"
58
 AMF.H264.View.Basic="Grundläggande"
59
 AMF.H264.View.Advanced="Avancerad"
60
obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/tr-TR.ini Added
54
 
1
@@ -0,0 +1,52 @@
2
+AMF.Util.Default="Varsayılan"
3
+AMF.Util.Automatic="Otomatik"
4
+AMF.Util.Manual="Elle"
5
+AMF.Util.Toggle.Disabled="Devre Dışı"
6
+AMF.Util.Toggle.Enabled="Etkin"
7
+AMF.H264.Preset="Ön Tanımlı"
8
+AMF.H264.Preset.ResetToDefaults="Varsayılan Ayarlara Geri Dön"
9
+AMF.H264.Preset.Recording="Kaydediliyor"
10
+AMF.H264.Preset.HighQuality="Yüksek Kalite"
11
+AMF.H264.Preset.Lossless="Kayıpsız"
12
+AMF.H264.Preset.Twitch="Twitch"
13
+AMF.H264.Preset.YouTube="YouTube"
14
+AMF.H264.Usage="Kullanım"
15
+AMF.H264.Usage.UltraLowLatency="Ultra Düşük Gecikme"
16
+AMF.H264.Usage.LowLatency="Düşük Gecikme"
17
+AMF.H264.QualityPreset.Speed="Hız"
18
+AMF.H264.QualityPreset.Balanced="Dengeli"
19
+AMF.H264.QualityPreset.Quality="Kalite"
20
+AMF.H264.Profile="Profil"
21
+AMF.H264.ProfileLevel="Profil Seviyesi"
22
+AMF.H264.Bitrate.Target="Hedef Bit Hızı"
23
+AMF.H264.QP.Minimum="Minimum QP"
24
+AMF.H264.QP.Maximum="Maksimum QP"
25
+AMF.H264.VBVBuffer.Size="VBV Arabellek Boyutu"
26
+AMF.H264.FrameSkipping="Kare Atlama"
27
+AMF.H264.ScanType="Tarama Türü"
28
+AMF.H264.MotionEstimation.None="Hiçbiri"
29
+AMF.H264.MotionEstimation.Half="Yarım Piksel"
30
+AMF.H264.MotionEstimation.Quarter="Çeyrek Piksel"
31
+AMF.H264.MotionEstimation.Both="Yarım ve Çeyrek Piksel"
32
+AMF.H264.WaitForTask.Description="Bilinmeyen, Deneysel"
33
+AMF.H264.PreAnalysisPass.Description="Bilinmeyen, Deneysel"
34
+AMF.H264.VBAQ="VBAQ"
35
+AMF.H264.VBAQ.Description="Bilinmeyen, Deneysel"
36
+AMF.H264.GOPSize.Description="Bilinmeyen, Deneysel"
37
+AMF.H264.GOPAlignment.Description="Bilinmeyen, Deneysel"
38
+AMF.H264.MaximumReferenceFrames.Description="Bilinmeyen, Deneysel"
39
+AMF.H264.SliceMode.Description="Bilinmeyen, Deneysel"
40
+AMF.H264.MaximumSliceSize.Description="Bilinmeyen, Deneysel"
41
+AMF.H264.SliceControlMode.Description="Bilinmeyen, Deneysel"
42
+AMF.H264.SliceControlSize.Description="Bilinmeyen, Deneysel"
43
+AMF.H264.IntraRefresh.NumberOfStripes.Description="Bilinmeyen, Deneysel"
44
+AMF.H264.VideoAPI="Video API"
45
+AMF.H264.VideoAdapter="Ekran Kartı"
46
+AMF.H264.OpenCL="OpenCL"
47
+AMF.H264.View="Görüntüleme Modu"
48
+AMF.H264.View.Basic="Temel"
49
+AMF.H264.View.Advanced="Gelişmiş"
50
+AMF.H264.View.Expert="Uzman"
51
+AMF.H264.View.Master="Usta"
52
+AMF.H264.Debug="Hata Ayıklama"
53
+
54
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/uk-UA.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/uk-UA.ini Changed
23
 
1
@@ -66,6 +66,11 @@
2
 AMF.H264.BFrame.Pattern="B-кадри"
3
 AMF.H264.BFrame.Pattern.Description="Визначає кількість послідовних B-кадрів у кодуванні.\nПідтримується принаймні 2-м та 3-м поколінням VCE карт. Маєнегативний вплив на продуктивність."
4
 AMF.H264.BFrame.DeltaQP="B-кадри, відхил QP"
5
+AMF.H264.BFrame.DeltaQP.Description="Відхил QP (параметра квантування) для не опорних B-кадрів, по відношенню до I-кадрів та P-кадрів."
6
+AMF.H264.BFrame.Reference="B-кадри як опорні"
7
+AMF.H264.BFrame.Reference.Description="Дозволяє робити B-кадри опорними для інших B-кадрів в додаток до вже існуючих P- та I-кадрів."
8
+AMF.H264.BFrame.ReferenceDeltaQP="Відхил QP (параметра квантування) для опорних B-кадрів"
9
+AMF.H264.BFrame.ReferenceDeltaQP.Description="Відхил QP (параметра квантування) для опорних B-кадрів, по відношенню до I-кадрів та P-кадрів."
10
 AMF.H264.DeblockingFilter="Деблокінг-фільтр"
11
 AMF.H264.DeblockingFilter.Description="Встановлює позначку, що дозволяє декодеру використовувати Деблокінг-фільтр для цього відео."
12
 AMF.H264.ScanType="Вид розгортки"
13
@@ -92,6 +97,9 @@
14
 AMF.H264.SlicesPerFrame.Description="Скільки фрагментів I-кадрів буде у кожному кадру?\nНульове значення дозволяє енкодеру визначати цю кількість під час кодування самостійно.\nIntra-Refresh кодування використовується для більш швидкого відтворення та навігації."
15
 AMF.H264.IntraRefresh.NumberOfStripes="Кількість рядків Intra-Refresh"
16
 AMF.H264.IntraRefresh.MacroblocksPerSlot="Кількість Intra-Refresh макроблоків на слот"
17
+AMF.H264.IntraRefresh.MacroblocksPerSlot.Description="Визначає скільки Intra-Refresh макроблоків на слот можна використовувати при кодуванні.\nНульове значення вимикає цю опцію.\nIntra-Refresh кодування використовується для більш швидкого відтворення та навігації."
18
+AMF.H264.VideoAPI="Відео API"
19
+AMF.H264.VideoAPI.Description="Визначає який API використовувати для кодування."
20
 AMF.H264.VideoAdapter="Відеоадаптер"
21
 AMF.H264.VideoAdapter.Description="Визначає який відеоадаптер використовувати для кодування."
22
 AMF.H264.OpenCL="OpenCL"
23
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/vi-VN.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/vi-VN.ini Changed
14
 
1
@@ -49,7 +49,12 @@
2
 AMF.H264.MotionEstimation.Both="1/2 và 1/4 Pixel"
3
 AMF.H264.CodingType="Coding Type"
4
 AMF.H264.MaximumLTRFrames="LTR Frames tối đa"
5
+AMF.H264.GOPSize="Kích cỡ GOP"
6
+AMF.H264.GOPSize.Description="Không rõ, thử nghiệm"
7
 AMF.H264.SlicesPerFrame="Lát cho mỗi khung hình"
8
+AMF.H264.VideoAPI="Video API"
9
+AMF.H264.VideoAdapter="Card đồ họa"
10
+AMF.H264.OpenCL="OpenCL"
11
 AMF.H264.View="Chế độ xem"
12
 AMF.H264.View.Basic="Cơ bản"
13
 AMF.H264.View.Advanced="Nâng cao"
14
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Resources/locale/zh-TW.ini -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Resources/locale/zh-TW.ini Changed
99
 
1
@@ -17,6 +17,7 @@
2
 AMF.H264.Usage.UltraLowLatency="超低延遲"
3
 AMF.H264.Usage.LowLatency="低延遲"
4
 AMF.H264.QualityPreset="預設品質"
5
+AMF.H264.QualityPreset.Description="AMF 嘗試達成的預設品質:\n- '\@AMF.H264.QualityPreset.Speed\@' 為最快但最差的品質,\n- '\@AMF.H264.QualityPreset.Balanced\@' 為中間點,\n- '\@AMF.H264.QualityPreset.Quality\@' 在給定的位元速率下有最佳的品質。"
6
 AMF.H264.QualityPreset.Speed="速度"
7
 AMF.H264.QualityPreset.Balanced="平衡"
8
 AMF.H264.QualityPreset.Quality="品質"
9
@@ -39,21 +40,41 @@
10
 AMF.H264.QP.Maximum="最大 QP 值"
11
 AMF.H264.QP.Maximum.Description="一個訊框中使用的最高 QP (量化參數) 值。"
12
 AMF.H264.QP.IFrame="I-訊框 QP"
13
+AMF.H264.QP.IFrame.Description="I 訊框所使用的固定 QP 值"
14
 AMF.H264.QP.PFrame="P-訊框 QP"
15
+AMF.H264.QP.PFrame.Description="P 訊框所使用的固定 QP 值"
16
 AMF.H264.QP.BFrame="B-訊框 QP"
17
 AMF.H264.QP.BFrame.Description="B-訊框使用的固定 QP (量化參數) 值。"
18
 AMF.H264.VBVBuffer="VBV(Video Buffering Verifier) 緩衝區"
19
 AMF.H264.VBVBuffer.Description="決定 VBV 緩衝區大小的方法:\n- '\@AMF.Util.Automatic\@' 根據嚴格性計算大小,\n- '\@AMF.Util.Manual\@' 允許使用者調整大小。\n 某些速率控制方法會使用 VBV (Video Buffering Verifier) 緩衝區讓整體的位元速率保持在給定的條件之內。"
20
 AMF.H264.VBVBuffer.Strictness="VBV 緩衝區嚴格性"
21
+AMF.H264.VBVBuffer.Strictness.Description="決定 VBV 緩衝區的嚴密性,100% 表示盡可能的嚴格,0% 表示完全不限制。"
22
 AMF.H264.VBVBuffer.Size="VBV 緩衝區大小"
23
+AMF.H264.VBVBuffer.Size.Description="VBV緩衝區的大小,這將用於過程中的位元速率控制"
24
 AMF.H264.VBVBuffer.Fullness="初始 VBV 緩衝區填充度"
25
 AMF.H264.VBVBuffer.Fullness.Description="VBV 緩衝區起始該多滿,將只影響編碼的起始。"
26
 AMF.H264.FillerData="填塞空白資料"
27
 AMF.H264.FillerData.Description="啟用填塞空白資料允許編碼器保持位元速率至少有目標位元速率,編碼器將會將不足的位元用空白訊息填滿"
28
 AMF.H264.FrameSkipping="省略訊框"
29
+AMF.H264.FrameSkipping.Description="省略訊框允許編碼器在為了達成目標位元速率時省略部份訊框。\n當編碼器省略訊框時,他將插入重複上一個訊框的指令。\n對極低的目標位元速率有幫助。"
30
 AMF.H264.EnforceHRDCompatibility="與 HRD 相容"
31
+AMF.H264.EnforceHRDCompatibility.Description="執行 Hypothetical Reference Decoder 限制,這將限制單一訊框內 QP 值的最大變化量。"
32
+AMF.H264.KeyframeInterval="關鍵訊框間隔"
33
+AMF.H264.KeyframeInterval.Description="以秒為單位,定義關鍵訊框之間的距離。同時也控制了 GOP 序列的大小。"
34
+AMF.H264.IDRPeriod="IDR 周期"
35
+AMF.H264.IDRPeriod.Description="以訊框為單位,定義瞬間解碼重新更新(Instantaneous Decoding Refreshes)間的距離。同時也控制了 GOP 序列的大小。"
36
+AMF.H264.BFrame.Pattern="B 訊框"
37
+AMF.H264.BFrame.Pattern.Description="編碼時使用的 B 訊框數量。\n搭載第二代和第三代影像編碼引擎的顯示卡支援此參數。對編碼效能會有不良影響。"
38
+AMF.H264.BFrame.DeltaQP="B 訊框的 QP 值變化"
39
+AMF.H264.BFrame.DeltaQP.Description="在沒使用可參照 B 訊框時, B 訊框與上一個I或P訊框間的QP值變化。"
40
+AMF.H264.BFrame.Reference="可參照 B 訊框"
41
+AMF.H264.BFrame.Reference.Description="允許 B 訊框也使用 B 訊框作為參照,而不限於 P 和 I 訊框。"
42
+AMF.H264.BFrame.ReferenceDeltaQP="可參照 B 訊框的 QP 值變化"
43
+AMF.H264.BFrame.ReferenceDeltaQP.Description="在使用可參照 B 訊框時,B 訊框與上一個 I 或 P 訊框間的 QP 值變化。"
44
 AMF.H264.DeblockingFilter="去塊狀色斑濾鏡"
45
+AMF.H264.DeblockingFilter.Description="設定選項,讓解碼器可以使用去塊狀色斑濾鏡。"
46
 AMF.H264.ScanType="掃描類型"
47
+AMF.H264.ScanType.Description="掃描方式,請確保此值為'\@AMF.H264.ScanType.Progressive\@'。"
48
 AMF.H264.ScanType.Progressive="漸進式"
49
 AMF.H264.ScanType.Interlaced="交错式"
50
 AMF.H264.MotionEstimation="動態估算"
51
@@ -62,7 +83,46 @@
52
 AMF.H264.MotionEstimation.Half="半像素"
53
 AMF.H264.MotionEstimation.Quarter="四分之一像素"
54
 AMF.H264.MotionEstimation.Both="半 & 四分之一像素"
55
-AMF.H264.MaximumLTRFrames="長期參照訊框(LTR)最大數量"
56
+AMF.H264.CodingType="Coding Type"
57
+AMF.H264.CodingType.Description="Which type of coding to use:\n* \@AMF.Util.Default\@ lets AMF decide (recommended).\n* CALVC (Context-Adaptive Variable-Length Coding) is faster, but larger.\n* CABAC (Context-Adaptive Binary Arithmetic Coding) is slower, but smaller."
58
+AMF.H264.MaximumLTRFrames="Maximum LTR Frames"
59
+AMF.H264.MaximumLTRFrames.Description="Long Term Reference (LTR) Frames are a feature that allows the encoder to flag certain frames in a sequence as referencable for a long time.\nLTR Frames can't be used with B-Frames and the encoder will disable B-Frames if these are used."
60
+AMF.H264.MaximumAccessUnitSize="Maximum Access Unit Size"
61
+AMF.H264.MaximumAccessUnitSize.Description="Largest Size of an Access Unit for a NAL."
62
+AMF.H264.HeaderInsertionSpacing="Header Insertion Spacing"
63
+AMF.H264.HeaderInsertionSpacing.Description="How many frames should be between NAL headers."
64
+AMF.H264.WaitForTask="Wait For Task"
65
+AMF.H264.WaitForTask.Description="Unknown, Experimental"
66
+AMF.H264.PreAnalysisPass="預分析階段"
67
+AMF.H264.PreAnalysisPass.Description="Unknown, Experimental"
68
+AMF.H264.VBAQ="VBAQ"
69
+AMF.H264.VBAQ.Description="Unknown, Experimental"
70
+AMF.H264.GOPSize="GOP Size"
71
+AMF.H264.GOPSize.Description="Unknown, Experimental"
72
+AMF.H264.GOPAlignment="GOP Alignment"
73
+AMF.H264.GOPAlignment.Description="Unknown, Experimental"
74
+AMF.H264.MaximumReferenceFrames="Maximum Reference Frames"
75
+AMF.H264.MaximumReferenceFrames.Description="Unknown, Experimental"
76
+AMF.H264.SlicesPerFrame="Slices Per Frame"
77
+AMF.H264.SlicesPerFrame.Description="How many I-Frame slices should be stored with each frame?\nA value of zero lets the encoder decide on the fly.\nIntra-Refresh encoding is used for faster playback and seeking."
78
+AMF.H264.SliceMode="Slice Mode"
79
+AMF.H264.SliceMode.Description="Unknown, Experimental"
80
+AMF.H264.MaximumSliceSize="Maximum Slice Size"
81
+AMF.H264.MaximumSliceSize.Description="Unknown, Experimental"
82
+AMF.H264.SliceControlMode="Slice Control Mode"
83
+AMF.H264.SliceControlMode.Description="Unknown, Experimental"
84
+AMF.H264.SliceControlSize="Slice Control Size"
85
+AMF.H264.SliceControlSize.Description="Unknown, Experimental"
86
+AMF.H264.IntraRefresh.NumberOfStripes="Intra-Refresh Number of Stripes"
87
+AMF.H264.IntraRefresh.NumberOfStripes.Description="Unknown, Experimental"
88
+AMF.H264.IntraRefresh.MacroblocksPerSlot="Intra-Refresh Macroblocks per Slot"
89
+AMF.H264.IntraRefresh.MacroblocksPerSlot.Description="How many Macroblocks should be stored in each slot?\nA value of 0 disables this feature.\nIntra-Refresh encoding is used for faster playback and seeking."
90
+AMF.H264.VideoAPI="影像 API"
91
+AMF.H264.VideoAPI.Description="用於編碼的API。"
92
+AMF.H264.VideoAdapter="顯示卡"
93
+AMF.H264.VideoAdapter.Description="用於編碼的顯示卡。"
94
+AMF.H264.OpenCL="OpenCL"
95
+AMF.H264.OpenCL.Description="編碼器應該使用 OpenCL 來發送各個訊框?"
96
 AMF.H264.View="檢視模式"
97
 AMF.H264.View.Description="該顯示哪些屬性?\n使用'\@AMF.H264.View.Master\@'時將不提供任何的支援。"
98
 AMF.H264.View.Basic="基本"
99
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/amf-capabilities.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/amf-capabilities.cpp Changed
218
 
1
@@ -92,26 +92,26 @@
2
 
3
 void Plugin::AMD::VCECapabilities::ReportAdapterCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter) {
4
    auto inst = GetInstance();
5
-   VCEEncoderType types[] = {
6
-       VCEEncoderType_AVC,
7
-       VCEEncoderType_SVC,
8
+   H264EncoderType types[] = {
9
+       H264EncoderType::AVC,
10
+       H264EncoderType::SVC,
11
    };
12
 
13
-   AMF_LOG_INFO("Capabilities for Device '%s' on API %s:",
14
-       adapter.Name.c_str(),
15
-       api->GetName().c_str());
16
+   AMF_LOG_INFO("Capabilities for %s adapter '%s':",
17
+       api->GetName().c_str(),
18
+       adapter.Name.c_str());
19
 
20
    for (auto type : types) {
21
        ReportAdapterTypeCapabilities(api, adapter, type);
22
    }
23
 }
24
 
25
-void Plugin::AMD::VCECapabilities::ReportAdapterTypeCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter, VCEEncoderType type) {
26
+void Plugin::AMD::VCECapabilities::ReportAdapterTypeCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter, H264EncoderType type) {
27
    auto inst = GetInstance();
28
    auto caps = inst->GetAdapterCapabilities(api, adapter, type);
29
 
30
    AMF_LOG_INFO("  %s (Acceleration: %s)",
31
-       (type == VCEEncoderType_AVC ? "AVC" : (type == VCEEncoderType_SVC ? "SVC" : (type == VCEEncoderType_HEVC ? "HEVC" : "Unknown"))),
32
+       (type == H264EncoderType::AVC ? "AVC" : (type == H264EncoderType::SVC ? "SVC" : "Unknown")),
33
        (caps.acceleration_type == amf::AMF_ACCEL_SOFTWARE ? "Software" : (caps.acceleration_type == amf::AMF_ACCEL_GPU ? "GPU" : (caps.acceleration_type == amf::AMF_ACCEL_HARDWARE ? "Hardware" : "None")))
34
    );
35
 
36
@@ -119,11 +119,11 @@
37
        return;
38
 
39
    AMF_LOG_INFO("    Limits");
40
-   AMF_LOG_INFO("      Profile: %s", Plugin::Utility::ProfileAsString((VCEProfile)caps.maxProfile));
41
+   AMF_LOG_INFO("      Profile: %s", Plugin::Utility::ProfileAsString((H264Profile)caps.maxProfile));
42
    AMF_LOG_INFO("      Profile Level: %ld.%ld", caps.maxProfileLevel / 10, caps.maxProfileLevel % 10);
43
    AMF_LOG_INFO("      Bitrate: %ld", caps.maxBitrate);
44
    AMF_LOG_INFO("      Reference Frames: %ld (min) - %ld (max)", caps.minReferenceFrames, caps.maxReferenceFrames);
45
-   if (type == VCEEncoderType_SVC)
46
+   if (type == H264EncoderType::SVC)
47
        AMF_LOG_INFO("      Temporal Layers: %ld", caps.maxTemporalLayers);
48
    AMF_LOG_INFO("    Features");
49
    AMF_LOG_INFO("      B-Frames: %s", caps.supportsBFrames ? "Supported" : "Not Supported");
50
@@ -137,7 +137,7 @@
51
    ReportAdapterTypeIOCapabilities(api, adapter, type, true);
52
 }
53
 
54
-void Plugin::AMD::VCECapabilities::ReportAdapterTypeIOCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter, VCEEncoderType type, bool output) {
55
+void Plugin::AMD::VCECapabilities::ReportAdapterTypeIOCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter, H264EncoderType type, bool output) {
56
    auto amf = Plugin::AMD::AMF::GetInstance();
57
 
58
    auto inst = GetInstance();
59
@@ -229,19 +229,23 @@
60
        try {
61
            adapters = api->EnumerateAdapters();
62
        } catch (std::exception e) {
63
-           AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unexpected exception while enumerating adapters for API '%s':", api->GetName());
64
-           AMF_LOG_ERROR("%s", e.what());
65
+           AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Exception while enumerating %s adapters: %s.",
66
+               api->GetName(),
67
+               e.what());
68
            continue;
69
        } catch (...) {
70
-           AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unexpected critical exception while enumerating adapters for API '%s'.", api->GetName());
71
+           AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Critical exception while enumerating %s adapters.",
72
+               api->GetName());
73
            throw;
74
        }
75
 
76
        for (auto adapter : adapters) {
77
            // Create AMF Instance
78
            amf::AMFContextPtr amfContext;
79
-           if (amfFactory->CreateContext(&amfContext) != AMF_OK) {
80
-               AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> CreateContext failed for device '%s', error %ls (code %d).",
81
+           res = amfFactory->CreateContext(&amfContext);
82
+           if (res != AMF_OK) {
83
+               AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unable to create context on %s adapter '%s', error %ls (code %lld).",
84
+                   api->GetName().c_str(),
85
                    adapter.Name.c_str(),
86
                    amfInstance->GetTrace()->GetResultText(res),
87
                    res);
88
@@ -252,21 +256,25 @@
89
            try {
90
                apiInst = api->CreateInstanceOnAdapter(adapter);
91
            } catch (std::exception e) {
92
-               AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unexpected exception while testing adapter '%s' on API '%s':", adapter.Name, api->GetName());
93
-               AMF_LOG_ERROR("%s", e.what());
94
+               AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Exception while intializing %s adapter '%s': %s.",
95
+                   api->GetName(),
96
+                   adapter.Name,
97
+                   e.what());
98
                continue;
99
            } catch (...) {
100
-               AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unexpected critical exceptionwhile testing adapter '%s' on API '%s'.", adapter.Name, api->GetName());
101
+               AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Critical exception while intializing %s adapter '%s'.",
102
+                   api->GetName(),
103
+                   adapter.Name);
104
                throw;
105
            }
106
            switch (api->GetType()) {
107
-               case Plugin::API::APIType_Direct3D11:
108
+               case Plugin::API::Type::Direct3D11:
109
                    res = amfContext->InitDX11(api->GetContextFromInstance(apiInst));
110
                    break;
111
-               case Plugin::API::APIType_Direct3D9:
112
+               case Plugin::API::Type::Direct3D9:
113
                    res = amfContext->InitDX9(api->GetContextFromInstance(apiInst));
114
                    break;
115
-               case Plugin::API::APIType_OpenGL:
116
+               case Plugin::API::Type::OpenGL:
117
                    res = amfContext->InitOpenGL(api->GetContextFromInstance(apiInst), nullptr, nullptr);
118
                    break;
119
                default:
120
@@ -274,40 +282,42 @@
121
                    break;
122
            }
123
            if (res != AMF_OK) {
124
-               AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Init failed for device '%s', error %ls (code %d).",
125
+               AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Initialization failed for %s adapter '%s', error %ls (code %lld).",
126
+                   api->GetName(),
127
                    adapter.Name.c_str(),
128
                    amfInstance->GetTrace()->GetResultText(res),
129
                    res);
130
                continue;
131
            }
132
 
133
-           VCEEncoderType types[] = {
134
-               VCEEncoderType_AVC,
135
-               VCEEncoderType_SVC
136
+           H264EncoderType types[] = {
137
+               H264EncoderType::AVC,
138
+               H264EncoderType::SVC
139
            };
140
            for (auto type : types) {
141
                VCEDeviceCapabilities devCaps = VCEDeviceCapabilities();
142
 
143
                amf::AMFComponentPtr amfComponent;
144
-               if (amfFactory->CreateComponent(amfContext,
145
+               res = amfFactory->CreateComponent(amfContext,
146
                    Plugin::Utility::VCEEncoderTypeAsAMF(type),
147
-                   &amfComponent) != AMF_OK) {
148
-                   AMF_LOG_ERROR("CreateComponent failed for device '%s' with codec '%s', error %ls (code %d).",
149
+                   &amfComponent);
150
+               if (res != AMF_OK) {
151
+                   AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unable to create component for %s adapter '%s' with codec '%s', error %ls (code %lld).",
152
+                       api->GetName(),
153
                        adapter.Name.c_str(),
154
                        Plugin::Utility::VCEEncoderTypeAsString(type),
155
-                       amfInstance->GetTrace()->GetResultText(res),
156
-                       res);
157
+                       amfInstance->GetTrace()->GetResultText(res), res);
158
                    continue;
159
                }
160
 
161
                amf::AMFCapsPtr amfCaps;
162
                res = amfComponent->GetCaps(&amfCaps);
163
                if (res != AMF_OK) {
164
-                   AMF_LOG_ERROR("GetCaps failed for device '%s' with codec '%s', error %ls (code %d).",
165
+                   AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unable to query capabilities for %s adapter '%s' with codec '%s', error %ls (code %lld).",
166
+                       api->GetName(),
167
                        adapter.Name.c_str(),
168
                        Plugin::Utility::VCEEncoderTypeAsString(type),
169
-                       amfInstance->GetTrace()->GetResultText(res),
170
-                       res);
171
+                       amfInstance->GetTrace()->GetResultText(res), res);
172
                    amfComponent->Terminate();
173
                    continue;
174
                }
175
@@ -325,14 +335,18 @@
176
                    amfCaps->GetProperty(AMF_VIDEO_ENCODER_CAP_FIXED_SLICE_MODE, &(devCaps.supportsFixedSliceMode));
177
                    amfCaps->GetProperty(AMF_VIDEO_ENCODER_CAP_NUM_OF_HW_INSTANCES, &(devCaps.maxNumOfHwInstances));
178
 
179
-                   if (GetIOCapability(false, amfCaps, &(devCaps.input)) != AMF_OK)
180
-                       AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> GetInputCaps failed for device '%s' with codec '%ls', error %ls (code %d).",
181
+                   res = GetIOCapability(false, amfCaps, &(devCaps.input));
182
+                   if (res != AMF_OK)
183
+                       AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unable to query input capabilities for %s adapter '%s' with codec '%s', error %ls (code %lld).",
184
+                           api->GetName(),
185
                            adapter.Name.c_str(),
186
                            Plugin::Utility::VCEEncoderTypeAsString(type),
187
                            amfInstance->GetTrace()->GetResultText(res), res);
188
 
189
-                   if (GetIOCapability(true, amfCaps, &(devCaps.output)) != AMF_OK)
190
-                       AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> GetOutputCaps failed capabilities for device '%s' with codec '%ls', error %ls (code %d).",
191
+                   res = GetIOCapability(true, amfCaps, &(devCaps.output));
192
+                   if (res != AMF_OK)
193
+                       AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Unable to query output capabilities for %s adapter '%s' with codec '%s', error %ls (code %lld).",
194
+                           api->GetName(),
195
                            adapter.Name.c_str(),
196
                            Plugin::Utility::VCEEncoderTypeAsString(type),
197
                            amfInstance->GetTrace()->GetResultText(res), res);
198
@@ -353,8 +367,8 @@
199
    return true;
200
 }
201
 
202
-std::vector<std::pair<VCEEncoderType, VCEDeviceCapabilities>> Plugin::AMD::VCECapabilities::GetAllAdapterCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter) {
203
-   std::vector<std::pair<VCEEncoderType, VCEDeviceCapabilities>> caps;
204
+std::vector<std::pair<H264EncoderType, VCEDeviceCapabilities>> Plugin::AMD::VCECapabilities::GetAllAdapterCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter) {
205
+   std::vector<std::pair<H264EncoderType, VCEDeviceCapabilities>> caps;
206
    for (auto kv : capabilityMap) {
207
        auto apiName = std::get<0>(kv.first);
208
        auto adapter = std::get<1>(kv.first);
209
@@ -370,7 +384,7 @@
210
    return caps;
211
 }
212
 
213
-Plugin::AMD::VCEDeviceCapabilities Plugin::AMD::VCECapabilities::GetAdapterCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter, VCEEncoderType type) {
214
+Plugin::AMD::VCEDeviceCapabilities Plugin::AMD::VCECapabilities::GetAdapterCapabilities(std::shared_ptr<Plugin::API::Base> api, Plugin::API::Adapter adapter, H264EncoderType type) {
215
    auto key = std::make_tuple(api->GetName(), adapter, type);
216
 
217
    if (capabilityMap.count(key) == 0)
218
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/amf-h264.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/amf-h264.cpp Changed
1678
 
1
@@ -40,6 +40,12 @@
2
 // Code
3
 //////////////////////////////////////////////////////////////////////////
4
 
5
+#define AMF_PROPERTY_FRAME L"Frame"
6
+#define AMF_PROPERTY_TIME_SENDINPUT L"TimeSendInput"
7
+#define AMF_PROPERTY_TIME_CREATESURFACE L"TimeCreateSurface"
8
+#define AMF_PROPERTY_TIME_CONVERT L"TimeConvert"
9
+#define AMF_PROPERTY_TIME_ENCODE L"TimeEncode"
10
+
11
 // Logging and Exception Helpers
12
 static void FormatTextWithAMFError(std::vector<char>* buffer, const char* format, AMF_RESULT res) {
13
    sprintf(buffer->data(), format, Plugin::AMD::AMF::GetInstance()->GetTrace()->GetResultText(res), res);
14
@@ -161,12 +167,12 @@
15
 }
16
 #endif
17
 
18
-Plugin::AMD::VCEEncoder::VCEEncoder(
19
-   VCEEncoderType p_Type,
20
+Plugin::AMD::H264Encoder::H264Encoder(
21
+   H264EncoderType p_Type,
22
    std::string p_VideoAPI,
23
    uint64_t p_VideoAdapterId,
24
    bool p_OpenCL,
25
-   VCEColorFormat p_SurfaceFormat/* = VCESurfaceFormat_NV12*/
26
+   H264ColorFormat p_SurfaceFormat/* = VCESurfaceFormat_NV12*/
27
 ) {
28
    #pragma region Assign Default Values
29
    m_EncoderType = p_Type;
30
@@ -179,7 +185,7 @@
31
    m_FrameRate.first = 30; m_FrameRate.second = 1;
32
    m_FrameRateDivisor = ((double_t)m_FrameRate.first / (double_t)m_FrameRate.second);
33
    m_FrameRateReverseDivisor = ((double_t)m_FrameRate.second / (double_t)m_FrameRate.first);
34
-   m_InputQueueLimit = (uint32_t)(m_FrameRateDivisor);
35
+   m_InputQueueLimit = (uint32_t)(m_FrameRateDivisor * 3);
36
    m_InputQueueLastSize = 0;
37
    m_TimerPeriod = 1;
38
    m_LastQueueWarnMessageTime = std::chrono::high_resolution_clock::time_point(std::chrono::high_resolution_clock::duration(0));
39
@@ -199,20 +205,20 @@
40
    m_APIAdapter = m_API->GetAdapterById(p_VideoAdapterId & UINT_MAX, (p_VideoAdapterId >> 32) & UINT_MAX);
41
    m_APIInstance = m_API->CreateInstanceOnAdapter(m_APIAdapter);
42
    switch (m_API->GetType()) {
43
-       case Plugin::API::APIType_Direct3D11:
44
-           m_MemoryType = VCEMemoryType_DirectX11;
45
+       case Plugin::API::Type::Direct3D11:
46
+           m_MemoryType = H264MemoryType::DirectX11;
47
            res = m_AMFContext->InitDX11(m_API->GetContextFromInstance(m_APIInstance));
48
            break;
49
-       case Plugin::API::APIType_Direct3D9:
50
-           m_MemoryType = VCEMemoryType_DirectX9;
51
+       case Plugin::API::Type::Direct3D9:
52
+           m_MemoryType = H264MemoryType::DirectX11;
53
            res = m_AMFContext->InitDX9(m_API->GetContextFromInstance(m_APIInstance));
54
            break;
55
-       case Plugin::API::APIType_OpenGL:
56
-           m_MemoryType = VCEMemoryType_OpenGL;
57
+       case Plugin::API::Type::OpenGL:
58
+           m_MemoryType = H264MemoryType::OpenGL;
59
            res = m_AMFContext->InitOpenGL(m_API->GetContextFromInstance(m_APIInstance), GetDesktopWindow(), nullptr);
60
            break;
61
-       case Plugin::API::APIType_Host:
62
-           m_MemoryType = VCEMemoryType_Host;
63
+       case Plugin::API::Type::Host:
64
+           m_MemoryType = H264MemoryType::Host;
65
            m_OpenCL = false;
66
            break;
67
    }
68
@@ -234,10 +240,6 @@
69
    /// Create the AMF Converter component.
70
    if (m_AMFFactory->CreateComponent(m_AMFContext, AMFVideoConverter, &m_AMFConverter) != AMF_OK)
71
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Unable to create VideoConverter component, error %ls (code %ld).", res);
72
-   if (m_AMFConverter->SetProperty(AMF_VIDEO_CONVERTER_MEMORY_TYPE, Utility::MemoryTypeAsAMF(m_MemoryType)) != AMF_OK)
73
-       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Memory Type not supported by VideoConverter component, error %ls (code %ld).", res);
74
-   if (m_AMFConverter->SetProperty(AMF_VIDEO_CONVERTER_OUTPUT_FORMAT, Utility::SurfaceFormatAsAMF(m_ColorFormat)))
75
-       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Color Format not supported by VideoConverter component, error %ls (code %ld).", res);
76
 
77
    #ifdef _DEBUG
78
    printDebugInfo(m_AMFEncoder);
79
@@ -246,7 +248,7 @@
80
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Initialized.");
81
 }
82
 
83
-Plugin::AMD::VCEEncoder::~VCEEncoder() {
84
+Plugin::AMD::H264Encoder::~H264Encoder() {
85
    if (m_Flag_IsStarted)
86
        Stop();
87
 
88
@@ -268,40 +270,45 @@
89
    m_API = nullptr;
90
 }
91
 
92
-void Plugin::AMD::VCEEncoder::Start() {
93
+void Plugin::AMD::H264Encoder::Start() {
94
+   AMF_RESULT res = AMF_UNEXPECTED;
95
+
96
    // Set proper Timer resolution.
97
    m_TimerPeriod = 1;
98
    while (timeBeginPeriod(m_TimerPeriod) == TIMERR_NOCANDO) {
99
        ++m_TimerPeriod;
100
    }
101
 
102
-   // Create Encoder
103
-   AMF_RESULT res = m_AMFEncoder->Init(Utility::SurfaceFormatAsAMF(m_ColorFormat),
104
-       m_FrameSize.first, m_FrameSize.second);
105
-   if (res != AMF_OK)
106
-       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Encoder initialization failed with error %ls (code %ld).", res);
107
-
108
-   // Create Converter
109
-   m_AMFConverter->SetProperty(AMF_VIDEO_CONVERTER_COLOR_PROFILE, this->GetColorProfile());
110
+   // Initialize Converter
111
+   if (m_AMFConverter->SetProperty(AMF_VIDEO_CONVERTER_MEMORY_TYPE, Utility::MemoryTypeAsAMF(m_MemoryType)) != AMF_OK)
112
+       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Memory Type not supported by VideoConverter component, error %ls (code %ld).", res);
113
+   if (m_AMFConverter->SetProperty(AMF_VIDEO_CONVERTER_OUTPUT_FORMAT, amf::AMF_SURFACE_NV12))
114
+       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Color Format not supported by VideoConverter component, error %ls (code %ld).", res);
115
+   m_AMFConverter->SetProperty(AMF_VIDEO_CONVERTER_COLOR_PROFILE, (size_t)this->GetColorProfile());
116
    if (m_AMFConverter->SetProperty(L"FullRangeColor", this->IsFullRangeColorEnabled()) != AMF_OK)
117
        m_AMFConverter->SetProperty(L"NominalRange", this->IsFullRangeColorEnabled());
118
-
119
    res = m_AMFConverter->Init(Utility::SurfaceFormatAsAMF(m_ColorFormat), m_FrameSize.first, m_FrameSize.second);
120
    if (res != AMF_OK)
121
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Converter initialization failed with error %ls (code %ld).", res);
122
 
123
+   // Initialize Encoder
124
+   res = m_AMFEncoder->Init(amf::AMF_SURFACE_NV12,
125
+       m_FrameSize.first, m_FrameSize.second);
126
+   if (res != AMF_OK)
127
+       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Encoder initialization failed with error %ls (code %ld).", res);
128
+
129
    m_Flag_IsStarted = true;
130
 
131
    // Threading
132
-   m_Input.thread = std::thread(&(Plugin::AMD::VCEEncoder::InputThreadMain), this);
133
-   m_Output.thread = std::thread(&(Plugin::AMD::VCEEncoder::OutputThreadMain), this);
134
+   m_Input.thread = std::thread(&(Plugin::AMD::H264Encoder::InputThreadMain), this);
135
+   m_Output.thread = std::thread(&(Plugin::AMD::H264Encoder::OutputThreadMain), this);
136
 
137
    #ifdef _DEBUG
138
    printDebugInfo(m_AMFEncoder);
139
    #endif
140
 }
141
 
142
-void Plugin::AMD::VCEEncoder::Restart() {
143
+void Plugin::AMD::H264Encoder::Restart() {
144
    if (!m_Flag_IsStarted)
145
        return;
146
 
147
@@ -314,7 +321,7 @@
148
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Initialization failed with error %ls (code %ld).", res);
149
 }
150
 
151
-void Plugin::AMD::VCEEncoder::Stop() {
152
+void Plugin::AMD::H264Encoder::Stop() {
153
    // Restore Timer precision.
154
    if (m_TimerPeriod != 0) {
155
        timeEndPeriod(m_TimerPeriod);
156
@@ -374,13 +381,13 @@
157
    std::queue<amf::AMFDataPtr>().swap(m_Output.queue);
158
    m_PacketDataBuffer.clear();
159
    m_ExtraDataBuffer.clear();
160
-   }
161
+}
162
 
163
-bool Plugin::AMD::VCEEncoder::IsStarted() {
164
+bool Plugin::AMD::H264Encoder::IsStarted() {
165
    return m_Flag_IsStarted;
166
 }
167
 
168
-bool Plugin::AMD::VCEEncoder::SendInput(struct encoder_frame* frame) {
169
+bool Plugin::AMD::H264Encoder::SendInput(struct encoder_frame* frame) {
170
    // Early-Exception if not encoding.
171
    if (!m_Flag_IsStarted) {
172
        const char* error = "<" __FUNCTION_NAME__ "> Attempted to send input while not running.";
173
@@ -388,6 +395,8 @@
174
        throw std::exception(error);
175
    }
176
 
177
+   /* Performance Monitoring */ std::chrono::high_resolution_clock::time_point tpSend = std::chrono::high_resolution_clock::now();
178
+
179
    // Attempt to queue for 1 second (forces "Encoding overloaded" message to appear).
180
    bool queueSuccessful = false;
181
    auto queueStart = std::chrono::high_resolution_clock::now();
182
@@ -404,14 +413,20 @@
183
 
184
        // Push into queue if it has room.
185
        if (queueSize < m_InputQueueLimit) {
186
+           /* Performance Monitoring */ std::chrono::high_resolution_clock::time_point tpCreateSurface = std::chrono::high_resolution_clock::now();
187
            amf::AMFSurfacePtr pAMFSurface = CreateSurfaceFromFrame(frame);
188
+           /* Performance Monitoring */ auto timeCreate = std::chrono::high_resolution_clock::now() - tpCreateSurface;
189
            if (!pAMFSurface) {
190
                AMF_LOG_ERROR("Unable copy frame for submission, terminating...");
191
                return false;
192
            } else {
193
                pAMFSurface->SetPts(frame->pts / m_FrameRate.second);
194
-               pAMFSurface->SetProperty(L"Frame", frame->pts);
195
                pAMFSurface->SetDuration((uint64_t)ceil(m_FrameRateReverseDivisor * AMF_SECOND));
196
+               pAMFSurface->SetProperty(AMF_PROPERTY_FRAME, frame->pts);
197
+               /* Performance Monitoring */ pAMFSurface->SetProperty(AMF_PROPERTY_TIME_SENDINPUT, std::chrono::nanoseconds(tpSend.time_since_epoch()).count());
198
+               /* Performance Monitoring */ pAMFSurface->SetProperty(AMF_PROPERTY_TIME_CREATESURFACE, std::chrono::nanoseconds(timeCreate).count());
199
+               /* Performance Monitoring */ pAMFSurface->SetProperty(AMF_PROPERTY_TIME_CONVERT, 0);
200
+               /* Performance Monitoring */ pAMFSurface->SetProperty(AMF_PROPERTY_TIME_ENCODE, 0);
201
            }
202
 
203
            {
204
@@ -472,7 +487,7 @@
205
    return true;
206
 }
207
 
208
-bool Plugin::AMD::VCEEncoder::GetOutput(struct encoder_packet* packet, bool* received_packet) {
209
+bool Plugin::AMD::H264Encoder::GetOutput(struct encoder_packet* packet, bool* received_packet) {
210
    // Early-Exception if not encoding.
211
    if (!m_Flag_IsStarted) {
212
        const char* error = "<" __FUNCTION_NAME__ "> Attempted to send input while not running.";
213
@@ -480,6 +495,8 @@
214
        throw std::exception(error);
215
    }
216
 
217
+   /* Performance Monitoring */ std::chrono::high_resolution_clock::time_point tpRetrieve = std::chrono::high_resolution_clock::now();
218
+
219
    // Signal Output Thread to wake up.
220
    m_Output.condvar.notify_all();
221
 
222
@@ -549,17 +566,47 @@
223
        *received_packet = true;
224
 
225
        // Debug: Packet Information
226
-       std::vector<wchar_t> fileName(128);
227
+           /// Convert File Name and Function Name
228
+       static std::vector<wchar_t> fileName(2048);
229
        mbstowcs(fileName.data(), __FILE__, fileName.size());
230
-       std::vector<wchar_t> functionName(128);
231
-       mbstowcs(functionName.data(), __FUNCTION__, functionName.size());
232
-       m_AMF->GetTrace()->TraceW(fileName.data(), __LINE__, AMF_TRACE_TRACE, L"Plugin::GetOutput", 4, L"Packet: Type(%lld), PTS(%4lld), DTS(%4lld), Size(%8lld)", (int64_t)packet->priority, (int64_t)packet->pts, (int64_t)packet->dts, (int64_t)packet->size);
233
+
234
+       /// Timing Information
235
+       uint64_t debugPacketType, debugDTS, debugPTS, debugDuration,
236
+           debugTimeSend,
237
+           debugTimeCreate,
238
+           debugTimeConvert,
239
+           debugTimeEncode;
240
+       pAMFData->GetProperty(AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE, &debugPacketType);
241
+       debugDTS = pAMFData->GetPts();
242
+       pAMFData->GetProperty(AMF_PROPERTY_FRAME, &debugPTS);
243
+       debugDuration = pAMFData->GetDuration();
244
+       pAMFData->GetProperty(AMF_PROPERTY_TIME_SENDINPUT, &debugTimeSend);
245
+       pAMFData->GetProperty(AMF_PROPERTY_TIME_CREATESURFACE, &debugTimeCreate);
246
+       pAMFData->GetProperty(AMF_PROPERTY_TIME_CONVERT, &debugTimeConvert);
247
+       pAMFData->GetProperty(AMF_PROPERTY_TIME_ENCODE, &debugTimeEncode);
248
+       uint64_t totalTimeSendRetrieve = std::chrono::nanoseconds(tpRetrieve.time_since_epoch()).count() - debugTimeSend;
249
+
250
+       /// All times are in nanoseconds.
251
+       /// Frame DTS() PTS() Duration() Type() TimeCreate() TimeConvert(SUBMIT,QUERY,TOTAL) TimeEncode(SUBMIT,ENCODE,QUERY,TOTAL) TimeSendToRetrieve()
252
+       m_AMF->GetTrace()->TraceW(
253
+           fileName.data(), __LINE__,
254
+           AMF_TRACE_TRACE, L"Performance Tracking", 9,
255
+           L"Frame DTS(%8lld) PTS(%8lld) Duration(%8lld) Type(%1lld) Size(%8lld) TimeCreate(%8lld) TimeConvert(%8lld) TimeEncode(%8lld) TimeSendToRetrieve(%8lld)",
256
+           (uint64_t)debugDTS,
257
+           (uint64_t)debugPTS,
258
+           (uint64_t)debugDuration,
259
+           (uint64_t)debugPacketType,
260
+           (uint64_t)packet->size,
261
+           (uint64_t)debugTimeCreate,
262
+           (uint64_t)debugTimeConvert,
263
+           (uint64_t)debugTimeEncode,
264
+           (uint64_t)totalTimeSendRetrieve);
265
    }
266
 
267
    return true;
268
 }
269
 
270
-bool Plugin::AMD::VCEEncoder::GetExtraData(uint8_t**& extra_data, size_t*& extra_data_size) {
271
+bool Plugin::AMD::H264Encoder::GetExtraData(uint8_t**& extra_data, size_t*& extra_data_size) {
272
    if (!m_AMFContext || !m_AMFEncoder)
273
        throw std::exception("<" __FUNCTION_NAME__ "> Called while not initialized.");
274
 
275
@@ -581,7 +628,7 @@
276
    return false;
277
 }
278
 
279
-void Plugin::AMD::VCEEncoder::GetVideoInfo(struct video_scale_info*& vsi) {
280
+void Plugin::AMD::H264Encoder::GetVideoInfo(struct video_scale_info*& vsi) {
281
    if (!m_AMFContext || !m_AMFEncoder)
282
        throw std::exception("<" __FUNCTION_NAME__ "> Called while not initialized.");
283
 
284
@@ -590,25 +637,25 @@
285
 
286
    switch (m_ColorFormat) {
287
        // 4:2:0 Formats
288
-       case VCEColorFormat_NV12:
289
+       case H264ColorFormat::NV12:
290
            vsi->format = VIDEO_FORMAT_NV12;
291
            break;
292
-       case VCEColorFormat_I420:
293
+       case H264ColorFormat::I420:
294
            vsi->format = VIDEO_FORMAT_I420;
295
            break;
296
        // 4:2:2 Formats
297
-       case VCEColorFormat_YUY2:
298
+       case H264ColorFormat::YUY2:
299
            vsi->format = VIDEO_FORMAT_YUY2;
300
            break;
301
        // Uncompressed
302
-       case VCEColorFormat_RGBA:
303
+       case H264ColorFormat::RGBA:
304
            vsi->format = VIDEO_FORMAT_RGBA;
305
            break;
306
-       case VCEColorFormat_BGRA:
307
+       case H264ColorFormat::BGRA:
308
            vsi->format = VIDEO_FORMAT_BGRA;
309
            break;
310
        // Other
311
-       case VCEColorFormat_GRAY:
312
+       case H264ColorFormat::GRAY:
313
            vsi->format = VIDEO_FORMAT_Y800;
314
            break;
315
    }
316
@@ -621,15 +668,15 @@
317
    }
318
 }
319
 
320
-void Plugin::AMD::VCEEncoder::InputThreadMain(Plugin::AMD::VCEEncoder* p_this) {
321
+void Plugin::AMD::H264Encoder::InputThreadMain(Plugin::AMD::H264Encoder* p_this) {
322
    p_this->InputThreadLogic();
323
 }
324
 
325
-void Plugin::AMD::VCEEncoder::OutputThreadMain(Plugin::AMD::VCEEncoder* p_this) {
326
+void Plugin::AMD::H264Encoder::OutputThreadMain(Plugin::AMD::H264Encoder* p_this) {
327
    p_this->OutputThreadLogic();
328
 }
329
 
330
-void Plugin::AMD::VCEEncoder::InputThreadLogic() { // Thread Loop that handles Surface Submission
331
+void Plugin::AMD::H264Encoder::InputThreadLogic() {    // Thread Loop that handles Surface Submission
332
    // Assign Thread Name
333
    static const char* __threadName = "enc-amf Input Thread";
334
    SetThreadName(__threadName);
335
@@ -640,10 +687,6 @@
336
    do {
337
        m_Input.condvar.wait(lock);
338
 
339
-       // Assign Thread Name
340
-       static const char* __threadName = "enc-amf Input Thread";
341
-       SetThreadName(__threadName);
342
-
343
        // Skip to check if isStarted is false.
344
        if (!m_Flag_IsStarted)
345
            continue;
346
@@ -661,14 +704,18 @@
347
        AMF_RESULT res;
348
        amf::AMFDataPtr outbuf;
349
 
350
+       /* Performance Monitoring */ std::chrono::high_resolution_clock::time_point tpConvert = std::chrono::high_resolution_clock::now();
351
        res = m_AMFConverter->SubmitInput(surface);
352
        if (res != AMF_OK)
353
            ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Unable to submit Frame to Converter, error %ls (code %ld).", res);
354
        res = m_AMFConverter->QueryOutput(&outbuf);
355
        if (res != AMF_OK)
356
            ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Unable to retrieve Frame from Converter, error %ls (code %ld).", res);
357
+       /* Performance Monitoring */ outbuf->SetProperty(AMF_PROPERTY_TIME_CONVERT,
358
+           std::chrono::nanoseconds(std::chrono::high_resolution_clock::now() - tpConvert).count());
359
 
360
        /// Submit to AMF
361
+       /* Performance Monitoring */ outbuf->SetProperty(AMF_PROPERTY_TIME_ENCODE, std::chrono::nanoseconds(std::chrono::high_resolution_clock::now().time_since_epoch()).count());
362
        res = m_AMFEncoder->SubmitInput(outbuf);
363
        if (res == AMF_OK) {
364
            m_Flag_FirstFrameSubmitted = true;
365
@@ -684,10 +731,10 @@
366
            // Continue with next Surface.
367
            m_Input.condvar.notify_all();
368
        } else if (res == AMF_INPUT_FULL) {
369
-           m_Output.condvar.notify_all();
370
            if (repeatSurfaceSubmission < 5) {
371
                repeatSurfaceSubmission++;
372
                m_Input.condvar.notify_all();
373
+               m_Output.condvar.notify_all();
374
            }
375
        } else if (res == AMF_EOF) {
376
            // This should never happen, but on the off-chance that it does, just straight up leave the loop.
377
@@ -703,7 +750,7 @@
378
    } while (m_Flag_IsStarted);
379
 }
380
 
381
-void Plugin::AMD::VCEEncoder::OutputThreadLogic() {    // Thread Loop that handles Querying
382
+void Plugin::AMD::H264Encoder::OutputThreadLogic() {   // Thread Loop that handles Querying
383
    // Assign Thread Name
384
    static const char* __threadName = "enc-amf Output Thread";
385
    SetThreadName(__threadName);
386
@@ -713,10 +760,6 @@
387
    do {
388
        m_Output.condvar.wait(lock);
389
 
390
-       // Assign Thread Name
391
-       static const char* __threadName = "enc-amf Output Thread";
392
-       SetThreadName(__threadName);
393
-
394
        // Skip to check if isStarted is false.
395
        if (!m_Flag_IsStarted)
396
            continue;
397
@@ -726,6 +769,14 @@
398
        if (res == AMF_OK) {
399
            m_Flag_FirstFrameReceived = true;
400
 
401
+           uint64_t debugTimeEncode = 0;
402
+           pData->GetProperty(AMF_PROPERTY_TIME_ENCODE, &debugTimeEncode);
403
+           /* Performance Monitoring */ pData->SetProperty(AMF_PROPERTY_TIME_ENCODE,
404
+               (uint64_t)(
405
+                   std::chrono::high_resolution_clock::now().time_since_epoch().count() -
406
+                   debugTimeEncode
407
+               ));
408
+
409
            { // Queue
410
                std::unique_lock<std::mutex> qlock(m_Output.queuemutex);
411
                m_Output.queue.push(pData);
412
@@ -749,7 +800,7 @@
413
    } while (m_Flag_IsStarted);
414
 }
415
 
416
-inline amf::AMFSurfacePtr Plugin::AMD::VCEEncoder::CreateSurfaceFromFrame(struct encoder_frame*& frame) {
417
+inline amf::AMFSurfacePtr Plugin::AMD::H264Encoder::CreateSurfaceFromFrame(struct encoder_frame*& frame) {
418
    AMF_RESULT res = AMF_UNEXPECTED;
419
    amf::AMFSurfacePtr pSurface = nullptr;
420
    if (m_OpenCL) {
421
@@ -805,14 +856,14 @@
422
 // AMF Properties
423
 //////////////////////////////////////////////////////////////////////////
424
 
425
-void Plugin::AMD::VCEEncoder::LogProperties() {
426
+void Plugin::AMD::H264Encoder::LogProperties() {
427
    AMF_LOG_INFO("-- AMD Advanced Media Framework Encoder --");
428
 
429
    // Initialization Properties
430
    AMF_LOG_INFO("Initialization Properties: ");
431
    AMF_LOG_INFO("  Type: %s", Utility::VCEEncoderTypeAsString(m_EncoderType));
432
    AMF_LOG_INFO("  Video API: %s", Utility::MemoryTypeAsString(m_MemoryType));
433
-   if (m_MemoryType != VCEMemoryType_Host) {
434
+   if (m_MemoryType != H264MemoryType::Host) {
435
        AMF_LOG_INFO("  Video Adapter: %s", m_APIAdapter.Name.c_str());
436
        AMF_LOG_INFO("  OpenCL: %s", m_OpenCL ? "Enabled" : "Disabled");
437
    }
438
@@ -822,12 +873,13 @@
439
    AMF_LOG_INFO("Startup Properties: ");
440
    AMF_LOG_INFO("  Usage: %s", Utility::UsageAsString(GetUsage()));
441
    AMF_LOG_INFO("  Quality Preset: %s", Utility::QualityPresetAsString(GetQualityPreset()));
442
-   AMF_LOG_INFO("  Profile: %s %d.%d", Utility::ProfileAsString(GetProfile()), GetProfileLevel() / 10, this->GetProfileLevel() % 10);
443
+   uint8_t profileLevel = (uint8_t)this->GetProfileLevel();
444
+   AMF_LOG_INFO("  Profile: %s %d.%d", Utility::ProfileAsString(GetProfile()), profileLevel / 10, profileLevel % 10);
445
 
446
    // Frame Properties
447
    AMF_LOG_INFO("Frame Properties: ");
448
    try {
449
-       AMF_LOG_INFO("  Color Profile: %s", GetColorProfile() == VCEColorProfile_709 ? "709" : "601");
450
+       AMF_LOG_INFO("  Color Profile: %s", GetColorProfile() == H264ColorProfile::Rec709 ? "709" : "601");
451
    } catch (...) {
452
        AMF_LOG_INFO("  Color Profile: N/A");
453
    }
454
@@ -838,47 +890,70 @@
455
    }
456
    AMF_LOG_INFO("  Resolution: %dx%d", GetResolution().first, GetResolution().second);
457
    AMF_LOG_INFO("  Frame Rate: %d/%d", GetFrameRate().first, GetFrameRate().second);
458
-   AMF_LOG_INFO("  Scan Type: %s", GetScanType() == VCEScanType_Progressive ? "Progressive" : "Interlaced");
459
+   AMF_LOG_INFO("  Scan Type: %s", GetScanType() == H264ScanType::Progressive ? "Progressive" : "Interlaced");
460
 
461
    // Rate Control Properties
462
    AMF_LOG_INFO("Rate Control Properties: ");
463
-   AMF_LOG_INFO("  Method: %s", Utility::RateControlMethodAsString(GetRateControlMethod()));
464
+   if (GetUsage() != H264Usage::UltraLowLatency) {
465
+       AMF_LOG_INFO("  Method: %s", Utility::RateControlMethodAsString(GetRateControlMethod()));
466
+   } else {
467
+       AMF_LOG_INFO("  Method: Ultra Low Latency");
468
+   }
469
    AMF_LOG_INFO("  Bitrate: ");
470
    AMF_LOG_INFO("    Target: %d bits", GetTargetBitrate());
471
-   AMF_LOG_INFO("    Peak: %d bits", GetPeakBitrate());
472
+   if (GetUsage() != H264Usage::UltraLowLatency) {
473
+       AMF_LOG_INFO("    Peak: %d bits", GetPeakBitrate());
474
+   } else {
475
+       AMF_LOG_INFO("    Peak: Ultra Low Latency");
476
+   }
477
    AMF_LOG_INFO("  Quantization Parameter: ");
478
    AMF_LOG_INFO("    Minimum: %d", GetMinimumQP());
479
    AMF_LOG_INFO("    Maximum: %d", GetMaximumQP());
480
    AMF_LOG_INFO("    I-Frame: %d", GetIFrameQP());
481
    AMF_LOG_INFO("    P-Frame: %d", GetPFrameQP());
482
-   if (VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, VCEEncoderType_AVC).supportsBFrames) {
483
+   if (VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, H264EncoderType::AVC).supportsBFrames) {
484
        try { AMF_LOG_INFO("    B-Frame: %d", GetBFrameQP()); } catch (...) {}
485
    } else {
486
        AMF_LOG_INFO("    B-Frame: N/A");
487
    }
488
    AMF_LOG_INFO("  VBV Buffer: ");
489
    AMF_LOG_INFO("    Size: %d bits", GetVBVBufferSize());
490
-   AMF_LOG_INFO("    Initial Fullness: %f%%", GetInitialVBVBufferFullness() * 100.0);
491
+   if (GetUsage() != H264Usage::UltraLowLatency) {
492
+       AMF_LOG_INFO("    Initial Fullness: %f%%", GetInitialVBVBufferFullness() * 100.0);
493
+   } else {
494
+       AMF_LOG_INFO("    Initial Fullness: Ultra Low Latency");
495
+   }
496
    AMF_LOG_INFO("  Flags: ");
497
-   AMF_LOG_INFO("    Filler Data: %s", IsFillerDataEnabled() ? "Enabled" : "Disabled");
498
-   AMF_LOG_INFO("    Frame Skipping: %s", IsFrameSkippingEnabled() ? "Enabled" : "Disabled");
499
-   AMF_LOG_INFO("    Enforce HRD Restrictions: %s", IsEnforceHRDRestrictionsEnabled() ? "Enabled" : "Disabled");
500
+   if (GetUsage() != H264Usage::UltraLowLatency) {
501
+       AMF_LOG_INFO("    Filler Data: %s", IsFillerDataEnabled() ? "Enabled" : "Disabled");
502
+       AMF_LOG_INFO("    Frame Skipping: %s", IsFrameSkippingEnabled() ? "Enabled" : "Disabled");
503
+       AMF_LOG_INFO("    Enforce HRD Restrictions: %s", IsEnforceHRDRestrictionsEnabled() ? "Enabled" : "Disabled");
504
+   } else {
505
+       AMF_LOG_INFO("    Filler Data: Ultra Low Latency");
506
+       AMF_LOG_INFO("    Frame Skipping: Ultra Low Latency");
507
+       AMF_LOG_INFO("    Enforce HRD Restrictions: Ultra Low Latency");
508
+   }
509
 
510
    // Picture Control Properties
511
    AMF_LOG_INFO("Picture Control Properties: ");
512
    AMF_LOG_INFO("  IDR Period: %d frames", GetIDRPeriod());
513
-   if (VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, VCEEncoderType_AVC).supportsBFrames) {
514
+   if (VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, H264EncoderType::AVC).supportsBFrames) {
515
        AMF_LOG_INFO("  B-Frame Pattern: %d", GetBFramePattern());
516
        try {
517
            AMF_LOG_INFO("  B-Frame Delta QP: %d", GetBFrameDeltaQP());
518
        } catch (...) {
519
            AMF_LOG_INFO("  B-Frame Delta QP: N/A");
520
        }
521
-       AMF_LOG_INFO("  B-Frame Reference: %s", IsBFrameReferenceEnabled() ? "Enabled" : "Disabled");
522
-       try {
523
-           AMF_LOG_INFO("  B-Frame Reference Delta QP: %d", GetBFrameReferenceDeltaQP());
524
-       } catch (...) {
525
-           AMF_LOG_INFO("  B-Frame Reference Delta QP: N/A");
526
+       if (GetUsage() == H264Usage::Transcoding) {
527
+           AMF_LOG_INFO("  B-Frame Reference: %s", IsBFrameReferenceEnabled() ? "Enabled" : "Disabled");
528
+           try {
529
+               AMF_LOG_INFO("  B-Frame Reference Delta QP: %d", GetBFrameReferenceDeltaQP());
530
+           } catch (...) {
531
+               AMF_LOG_INFO("  B-Frame Reference Delta QP: N/A");
532
+           }
533
+       } else {
534
+           AMF_LOG_INFO("  B-Frame Reference: Low Latency Mode");
535
+           AMF_LOG_INFO("  B-Frame Reference Delta QP: Low Latency Mode");
536
        }
537
    } else {
538
        AMF_LOG_INFO("  B-Frame Pattern: N/A");
539
@@ -888,7 +963,11 @@
540
    }
541
 
542
    AMF_LOG_INFO("Miscellaneous Properties: ");
543
-   AMF_LOG_INFO("  Deblocking Filter: %s", IsDeblockingFilterEnabled() ? "Enabled" : "Disabled");
544
+   if (GetUsage() == H264Usage::Transcoding) {
545
+       AMF_LOG_INFO("  Deblocking Filter: %s", IsDeblockingFilterEnabled() ? "Enabled" : "Disabled");
546
+   } else {
547
+       AMF_LOG_INFO("  Deblocking Filter: Low Latency Mode");
548
+   }
549
    AMF_LOG_INFO("  Motion Estimation: %s",
550
        (this->IsHalfPixelMotionEstimationEnabled()
551
            ? (this->IsQuarterPixelMotionEstimationEnabled()
552
@@ -930,7 +1009,7 @@
553
    AMF_LOG_INFO("-- AMD Advanced Media Framework VCE Encoder --");
554
 }
555
 
556
-void Plugin::AMD::VCEEncoder::SetUsage(VCEUsage usage) {
557
+void Plugin::AMD::H264Encoder::SetUsage(H264Usage usage) {
558
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_USAGE,
559
        (uint32_t)Utility::UsageAsAMF(usage));
560
    if (res != AMF_OK) {
561
@@ -940,7 +1019,7 @@
562
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", Utility::UsageAsString(usage));
563
 }
564
 
565
-Plugin::AMD::VCEUsage Plugin::AMD::VCEEncoder::GetUsage() {
566
+Plugin::AMD::H264Usage Plugin::AMD::H264Encoder::GetUsage() {
567
    uint32_t usage;
568
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_USAGE, &usage);
569
    if (res != AMF_OK) {
570
@@ -951,7 +1030,7 @@
571
    return Utility::UsageFromAMF(usage);
572
 }
573
 
574
-void Plugin::AMD::VCEEncoder::SetQualityPreset(VCEQualityPreset preset) {
575
+void Plugin::AMD::H264Encoder::SetQualityPreset(H264QualityPreset preset) {
576
    static AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM CustomToAMF[] = {
577
        AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED,
578
        AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED,
579
@@ -963,18 +1042,18 @@
580
        "Quality",
581
    };
582
 
583
-   AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_QUALITY_PRESET, (uint32_t)CustomToAMF[preset]);
584
+   AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_QUALITY_PRESET, (uint32_t)CustomToAMF[(uint8_t)preset]);
585
    if (res != AMF_OK) {
586
-       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, CustomToName[preset]);
587
+       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, CustomToName[(uint8_t)preset]);
588
    }
589
-   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", CustomToName[preset]);
590
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", CustomToName[(uint8_t)preset]);
591
 }
592
 
593
-Plugin::AMD::VCEQualityPreset Plugin::AMD::VCEEncoder::GetQualityPreset() {
594
-   static VCEQualityPreset AMFToCustom[] = {
595
-       VCEQualityPreset_Balanced,
596
-       VCEQualityPreset_Speed,
597
-       VCEQualityPreset_Quality,
598
+Plugin::AMD::H264QualityPreset Plugin::AMD::H264Encoder::GetQualityPreset() {
599
+   static H264QualityPreset AMFToCustom[] = {
600
+       H264QualityPreset::Balanced,
601
+       H264QualityPreset::Speed,
602
+       H264QualityPreset::Quality,
603
    };
604
    static char* CustomToName[] = {
605
        "Speed",
606
@@ -987,11 +1066,11 @@
607
    if (res != AMF_OK) {
608
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Failed with error %ls (code %d).", res);
609
    }
610
-   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", CustomToName[AMFToCustom[preset]]);
611
-   return AMFToCustom[preset];
612
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", CustomToName[(uint8_t)AMFToCustom[(uint8_t)preset]]);
613
+   return AMFToCustom[(uint8_t)preset];
614
 }
615
 
616
-void Plugin::AMD::VCEEncoder::SetProfile(VCEProfile profile) {
617
+void Plugin::AMD::H264Encoder::SetProfile(H264Profile profile) {
618
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, (uint32_t)profile);
619
    if (res != AMF_OK) {
620
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, Utility::ProfileAsString(profile));
621
@@ -999,19 +1078,19 @@
622
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", Utility::ProfileAsString(profile));
623
 }
624
 
625
-Plugin::AMD::VCEProfile Plugin::AMD::VCEEncoder::GetProfile() {
626
+Plugin::AMD::H264Profile Plugin::AMD::H264Encoder::GetProfile() {
627
    uint32_t profile;
628
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_PROFILE, &profile);
629
    if (res != AMF_OK) {
630
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Failed with error %ls (code %d).", res);
631
    }
632
-   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", Utility::ProfileAsString((VCEProfile)profile));
633
-   return (VCEProfile)profile;
634
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", Utility::ProfileAsString((H264Profile)profile));
635
+   return (H264Profile)profile;
636
 }
637
 
638
-void Plugin::AMD::VCEEncoder::SetProfileLevel(VCEProfileLevel level) {
639
+void Plugin::AMD::H264Encoder::SetProfileLevel(H264ProfileLevel level) {
640
    // Automatic Detection
641
-   if (level == VCEProfileLevel_Automatic) {
642
+   if (level == H264ProfileLevel::Automatic) {
643
        auto frameSize = this->GetResolution();
644
        auto frameRate = this->GetFrameRate();
645
        level = Plugin::Utility::GetMinimumProfileLevel(frameSize, frameRate);
646
@@ -1024,17 +1103,17 @@
647
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", level);
648
 }
649
 
650
-Plugin::AMD::VCEProfileLevel Plugin::AMD::VCEEncoder::GetProfileLevel() {
651
+Plugin::AMD::H264ProfileLevel Plugin::AMD::H264Encoder::GetProfileLevel() {
652
    uint32_t profileLevel;
653
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_PROFILE_LEVEL, &profileLevel);
654
    if (res != AMF_OK) {
655
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Failed with error %ls (code %d).", res);
656
    }
657
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %d.", profileLevel);
658
-   return (VCEProfileLevel)(profileLevel);
659
+   return (H264ProfileLevel)(profileLevel);
660
 }
661
 
662
-void Plugin::AMD::VCEEncoder::SetColorProfile(VCEColorProfile profile) {
663
+void Plugin::AMD::H264Encoder::SetColorProfile(H264ColorProfile profile) {
664
    AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM pluginToAMF[] = {
665
        AMF_VIDEO_CONVERTER_COLOR_PROFILE_601,
666
        AMF_VIDEO_CONVERTER_COLOR_PROFILE_709,
667
@@ -1047,18 +1126,18 @@
668
    };
669
 
670
    AMF_RESULT res = m_AMFConverter->SetProperty(AMF_VIDEO_CONVERTER_COLOR_PROFILE,
671
-       pluginToAMF[profile]);
672
+       pluginToAMF[(uint8_t)profile]);
673
    if (res != AMF_OK)
674
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Unable to set Color Profile, error %ls (code %ld).", res);
675
    m_ColorProfile = profile;
676
-   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", pluginToString[profile]);
677
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", pluginToString[(uint8_t)profile]);
678
 }
679
 
680
-Plugin::AMD::VCEColorProfile Plugin::AMD::VCEEncoder::GetColorProfile() {
681
+Plugin::AMD::H264ColorProfile Plugin::AMD::H264Encoder::GetColorProfile() {
682
    return m_ColorProfile;
683
 }
684
 
685
-void Plugin::AMD::VCEEncoder::SetFullRangeColorEnabled(bool enabled) {
686
+void Plugin::AMD::H264Encoder::SetFullRangeColorEnabled(bool enabled) {
687
    // Info from Mikhail:
688
    // - Name may change in the future
689
    // - Use GetProperty or GetPropertyDescription to test for older or newer drivers.
690
@@ -1081,7 +1160,7 @@
691
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
692
 }
693
 
694
-bool Plugin::AMD::VCEEncoder::IsFullRangeColorEnabled() {
695
+bool Plugin::AMD::H264Encoder::IsFullRangeColorEnabled() {
696
    // Info from Mikhail:
697
    // - Name may change in the future
698
    // - Use GetProperty or GetPropertyDescription to test for older or newer drivers.
699
@@ -1104,7 +1183,7 @@
700
    return enabled;
701
 }
702
 
703
-void Plugin::AMD::VCEEncoder::SetResolution(uint32_t width, uint32_t height) {
704
+void Plugin::AMD::H264Encoder::SetResolution(uint32_t width, uint32_t height) {
705
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMESIZE, ::AMFConstructSize(width, height));
706
    if (res != AMF_OK) {
707
        std::vector<char> msgBuf(128);
708
@@ -1115,11 +1194,11 @@
709
    m_FrameSize.first = width;
710
    m_FrameSize.second = height;
711
 
712
-   if (this->GetProfileLevel() == VCEProfileLevel_Automatic)
713
-       this->SetProfileLevel(VCEProfileLevel_Automatic);
714
+   if (this->GetProfileLevel() == H264ProfileLevel::Automatic)
715
+       this->SetProfileLevel(H264ProfileLevel::Automatic);
716
 }
717
 
718
-std::pair<uint32_t, uint32_t> Plugin::AMD::VCEEncoder::GetResolution() {
719
+std::pair<uint32_t, uint32_t> Plugin::AMD::H264Encoder::GetResolution() {
720
    AMFSize frameSize;
721
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_FRAMESIZE, &frameSize);
722
    if (res != AMF_OK) {
723
@@ -1129,13 +1208,13 @@
724
    m_FrameSize.first = frameSize.width;
725
    m_FrameSize.second = frameSize.height;
726
 
727
-   if (this->GetProfileLevel() == VCEProfileLevel_Automatic)
728
-       this->SetProfileLevel(VCEProfileLevel_Automatic);
729
+   if (this->GetProfileLevel() == H264ProfileLevel::Automatic)
730
+       this->SetProfileLevel(H264ProfileLevel::Automatic);
731
 
732
    return std::pair<uint32_t, uint32_t>(m_FrameSize);
733
 }
734
 
735
-void Plugin::AMD::VCEEncoder::SetFrameRate(uint32_t num, uint32_t den) {
736
+void Plugin::AMD::H264Encoder::SetFrameRate(uint32_t num, uint32_t den) {
737
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMERATE, ::AMFConstructRate(num, den));
738
    if (res != AMF_OK) {
739
        std::vector<char> msgBuf;
740
@@ -1147,13 +1226,13 @@
741
    m_FrameRate.second = den;
742
    m_FrameRateDivisor = (double_t)m_FrameRate.first / (double_t)m_FrameRate.second;
743
    m_FrameRateReverseDivisor = ((double_t)m_FrameRate.second / (double_t)m_FrameRate.first);
744
-   m_InputQueueLimit = (uint32_t)ceil(m_FrameRateDivisor);
745
+   m_InputQueueLimit = (uint32_t)ceil(m_FrameRateDivisor * 3);
746
 
747
-   if (this->GetProfileLevel() == VCEProfileLevel_Automatic)
748
-       this->SetProfileLevel(VCEProfileLevel_Automatic);
749
+   if (this->GetProfileLevel() == H264ProfileLevel::Automatic)
750
+       this->SetProfileLevel(H264ProfileLevel::Automatic);
751
 }
752
 
753
-std::pair<uint32_t, uint32_t> Plugin::AMD::VCEEncoder::GetFrameRate() {
754
+std::pair<uint32_t, uint32_t> Plugin::AMD::H264Encoder::GetFrameRate() {
755
    AMFRate frameRate;
756
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_FRAMERATE, &frameRate);
757
    if (res != AMF_OK) {
758
@@ -1163,15 +1242,15 @@
759
    m_FrameRate.first = frameRate.num;
760
    m_FrameRate.second = frameRate.den;
761
    m_FrameRateDivisor = (double_t)frameRate.num / (double_t)frameRate.den;
762
-   m_InputQueueLimit = (uint32_t)ceil(m_FrameRateDivisor);
763
+   m_InputQueueLimit = (uint32_t)ceil(m_FrameRateDivisor * 3);
764
 
765
-   if (this->GetProfileLevel() == VCEProfileLevel_Automatic)
766
-       this->SetProfileLevel(VCEProfileLevel_Automatic);
767
+   if (this->GetProfileLevel() == H264ProfileLevel::Automatic)
768
+       this->SetProfileLevel(H264ProfileLevel::Automatic);
769
 
770
    return std::pair<uint32_t, uint32_t>(m_FrameRate);
771
 }
772
 
773
-void Plugin::AMD::VCEEncoder::SetScanType(VCEScanType scanType) {
774
+void Plugin::AMD::H264Encoder::SetScanType(H264ScanType scanType) {
775
    static AMF_VIDEO_ENCODER_SCANTYPE_ENUM CustomToAMF[] = {
776
        AMF_VIDEO_ENCODER_SCANTYPE_PROGRESSIVE,
777
        AMF_VIDEO_ENCODER_SCANTYPE_INTERLACED,
778
@@ -1181,14 +1260,14 @@
779
        "Interlaced",
780
    };
781
 
782
-   AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_SCANTYPE, (uint32_t)CustomToAMF[scanType]);
783
+   AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_SCANTYPE, (uint32_t)CustomToAMF[(uint8_t)scanType]);
784
    if (res != AMF_OK) {
785
-       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, CustomToName[scanType]);
786
+       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, CustomToName[(uint8_t)scanType]);
787
    }
788
-   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", CustomToName[scanType]);
789
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", CustomToName[(uint8_t)scanType]);
790
 }
791
 
792
-Plugin::AMD::VCEScanType Plugin::AMD::VCEEncoder::GetScanType() {
793
+Plugin::AMD::H264ScanType Plugin::AMD::H264Encoder::GetScanType() {
794
    static char* CustomToName[] = {
795
        "Progressive",
796
        "Interlaced",
797
@@ -1200,10 +1279,10 @@
798
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Failed with error %ls (code %d).", res);
799
    }
800
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", CustomToName[scanType]);
801
-   return (Plugin::AMD::VCEScanType)scanType;
802
+   return (Plugin::AMD::H264ScanType)scanType;
803
 }
804
 
805
-void Plugin::AMD::VCEEncoder::SetRateControlMethod(VCERateControlMethod method) {
806
+void Plugin::AMD::H264Encoder::SetRateControlMethod(H264RateControlMethod method) {
807
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD,
808
        (uint64_t)Utility::RateControlMethodAsAMF(method));
809
    if (res != AMF_OK) {
810
@@ -1214,7 +1293,7 @@
811
        Utility::RateControlMethodAsString(method));
812
 }
813
 
814
-Plugin::AMD::VCERateControlMethod Plugin::AMD::VCEEncoder::GetRateControlMethod() {
815
+Plugin::AMD::H264RateControlMethod Plugin::AMD::H264Encoder::GetRateControlMethod() {
816
    uint32_t method;
817
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD, &method);
818
    if (res != AMF_OK) {
819
@@ -1225,10 +1304,10 @@
820
    return Utility::RateControlMethodFromAMF(method);
821
 }
822
 
823
-void Plugin::AMD::VCEEncoder::SetTargetBitrate(uint32_t bitrate) {
824
+void Plugin::AMD::H264Encoder::SetTargetBitrate(uint32_t bitrate) {
825
    // Clamp Value
826
    bitrate = clamp(bitrate, 10000,
827
-       Plugin::AMD::VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, VCEEncoderType_AVC).maxBitrate);
828
+       Plugin::AMD::VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, H264EncoderType::AVC).maxBitrate);
829
 
830
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_TARGET_BITRATE, bitrate);
831
    if (res != AMF_OK) {
832
@@ -1237,7 +1316,7 @@
833
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d bits.", bitrate);
834
 }
835
 
836
-uint32_t Plugin::AMD::VCEEncoder::GetTargetBitrate() {
837
+uint32_t Plugin::AMD::H264Encoder::GetTargetBitrate() {
838
    uint32_t bitrate;
839
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_TARGET_BITRATE, &bitrate);
840
    if (res != AMF_OK) {
841
@@ -1247,10 +1326,10 @@
842
    return bitrate;
843
 }
844
 
845
-void Plugin::AMD::VCEEncoder::SetPeakBitrate(uint32_t bitrate) {
846
+void Plugin::AMD::H264Encoder::SetPeakBitrate(uint32_t bitrate) {
847
    // Clamp Value
848
    bitrate = clamp(bitrate, 10000,
849
-       Plugin::AMD::VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, VCEEncoderType_AVC).maxBitrate);
850
+       Plugin::AMD::VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, H264EncoderType::AVC).maxBitrate);
851
 
852
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_PEAK_BITRATE, (uint32_t)bitrate);
853
    if (res != AMF_OK) {
854
@@ -1259,7 +1338,7 @@
855
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d bits.", bitrate);
856
 }
857
 
858
-uint32_t Plugin::AMD::VCEEncoder::GetPeakBitrate() {
859
+uint32_t Plugin::AMD::H264Encoder::GetPeakBitrate() {
860
    uint32_t bitrate;
861
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_PEAK_BITRATE, &bitrate);
862
    if (res != AMF_OK) {
863
@@ -1269,7 +1348,7 @@
864
    return bitrate;
865
 }
866
 
867
-void Plugin::AMD::VCEEncoder::SetMinimumQP(uint8_t qp) {
868
+void Plugin::AMD::H264Encoder::SetMinimumQP(uint8_t qp) {
869
    // Clamp Value
870
    qp = clamp(qp, 0, 51);
871
 
872
@@ -1280,7 +1359,7 @@
873
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", qp);
874
 }
875
 
876
-uint8_t Plugin::AMD::VCEEncoder::GetMinimumQP() {
877
+uint8_t Plugin::AMD::H264Encoder::GetMinimumQP() {
878
    uint32_t qp;
879
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_MIN_QP, &qp);
880
    if (res != AMF_OK) {
881
@@ -1290,7 +1369,7 @@
882
    return (uint8_t)qp;
883
 }
884
 
885
-void Plugin::AMD::VCEEncoder::SetMaximumQP(uint8_t qp) {
886
+void Plugin::AMD::H264Encoder::SetMaximumQP(uint8_t qp) {
887
    // Clamp Value
888
    qp = clamp(qp, 0, 51);
889
 
890
@@ -1301,7 +1380,7 @@
891
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", qp);
892
 }
893
 
894
-uint8_t Plugin::AMD::VCEEncoder::GetMaximumQP() {
895
+uint8_t Plugin::AMD::H264Encoder::GetMaximumQP() {
896
    uint32_t qp;
897
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_MAX_QP, &qp);
898
    if (res != AMF_OK) {
899
@@ -1311,7 +1390,7 @@
900
    return (uint8_t)qp;
901
 }
902
 
903
-void Plugin::AMD::VCEEncoder::SetIFrameQP(uint8_t qp) {
904
+void Plugin::AMD::H264Encoder::SetIFrameQP(uint8_t qp) {
905
    // Clamp Value
906
    qp = clamp(qp, 0, 51);
907
 
908
@@ -1322,7 +1401,7 @@
909
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", qp);
910
 }
911
 
912
-uint8_t Plugin::AMD::VCEEncoder::GetIFrameQP() {
913
+uint8_t Plugin::AMD::H264Encoder::GetIFrameQP() {
914
    uint32_t qp;
915
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_QP_I, &qp);
916
    if (res != AMF_OK) {
917
@@ -1332,7 +1411,7 @@
918
    return (uint8_t)qp;
919
 }
920
 
921
-void Plugin::AMD::VCEEncoder::SetPFrameQP(uint8_t qp) {
922
+void Plugin::AMD::H264Encoder::SetPFrameQP(uint8_t qp) {
923
    // Clamp Value
924
    qp = clamp(qp, 0, 51);
925
 
926
@@ -1343,7 +1422,7 @@
927
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", qp);
928
 }
929
 
930
-uint8_t Plugin::AMD::VCEEncoder::GetPFrameQP() {
931
+uint8_t Plugin::AMD::H264Encoder::GetPFrameQP() {
932
    uint32_t qp;
933
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_QP_P, &qp);
934
    if (res != AMF_OK) {
935
@@ -1353,7 +1432,7 @@
936
    return (uint8_t)qp;
937
 }
938
 
939
-void Plugin::AMD::VCEEncoder::SetBFrameQP(uint8_t qp) {
940
+void Plugin::AMD::H264Encoder::SetBFrameQP(uint8_t qp) {
941
    // Clamp Value
942
    qp = clamp(qp, 0, 51);
943
 
944
@@ -1364,7 +1443,7 @@
945
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", qp);
946
 }
947
 
948
-uint8_t Plugin::AMD::VCEEncoder::GetBFrameQP() {
949
+uint8_t Plugin::AMD::H264Encoder::GetBFrameQP() {
950
    uint32_t qp;
951
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_QP_B, &qp);
952
    if (res != AMF_OK) {
953
@@ -1374,7 +1453,7 @@
954
    return (uint8_t)qp;
955
 }
956
 
957
-void Plugin::AMD::VCEEncoder::SetVBVBufferSize(uint32_t size) {
958
+void Plugin::AMD::H264Encoder::SetVBVBufferSize(uint32_t size) {
959
    // Clamp Value
960
    size = clamp(size, 1000, 100000000); // 1kbit to 100mbit.
961
 
962
@@ -1385,69 +1464,79 @@
963
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d bits.", size);
964
 }
965
 
966
-void Plugin::AMD::VCEEncoder::SetVBVBufferAutomatic(double_t strictness) {
967
+void Plugin::AMD::H264Encoder::SetVBVBufferAutomatic(double_t strictness) {
968
    uint32_t strictBitrate = 1000, looseBitrate = 100000000;
969
 
970
    // Strict VBV Buffer Size = Bitrate / FPS
971
    // Loose VBV Buffer Size = Bitrate
972
 
973
-   switch (this->GetRateControlMethod()) {
974
-       case VCERateControlMethod_ConstantBitrate:
975
-       case VCERateControlMethod_VariableBitrate_LatencyConstrained:
976
-           looseBitrate = this->GetTargetBitrate();
977
-           break;
978
-       case VCERateControlMethod_VariableBitrate_PeakConstrained:
979
-           looseBitrate = max(this->GetTargetBitrate(), this->GetPeakBitrate());
980
-           break;
981
-       case VCERateControlMethod_ConstantQP:
982
-           // When using Constant QP, one will have to pick a QP that is decent
983
-           //  in both quality and bitrate. We can easily calculate both the QP
984
-           //  required for an average bitrate and the average bitrate itself 
985
-           //  with these formulas:
986
-           // BITRATE = ((1 - (QP / 51)) ^ 2) * ((Width * Height) * 1.5 * (FPSNumerator / FPSDenumerator))
987
-           // QP = (1 - sqrt(BITRATE / ((Width * Height) * 1.5 * (FPSNumerator / FPSDenumerator)))) * 51
988
-
989
-           auto frameSize = this->GetResolution();
990
-           auto frameRate = this->GetFrameRate();
991
-
992
-           double_t bitrate = frameSize.first * frameSize.second;
993
-           switch (this->m_ColorFormat) {
994
-               case VCEColorFormat_NV12:
995
-               case VCEColorFormat_I420:
996
-                   bitrate *= 1.5;
997
-                   break;
998
-               case VCEColorFormat_YUY2:
999
-                   bitrate *= 4;
1000
-                   break;
1001
-               case VCEColorFormat_BGRA:
1002
-               case VCEColorFormat_RGBA:
1003
-                   bitrate *= 3;
1004
-                   break;
1005
-               case VCEColorFormat_GRAY:
1006
-                   bitrate *= 1;
1007
-                   break;
1008
-           }
1009
-           bitrate *= frameRate.first / frameRate.second;
1010
-
1011
-           uint8_t qp_i, qp_p, qp_b;
1012
-           qp_i = this->GetIFrameQP();
1013
-           qp_p = this->GetPFrameQP();
1014
-           try { qp_b = this->GetBFrameQP(); } catch (...) { qp_b = 51; }
1015
-           double_t qp = 1 - ((double_t)(min(min(qp_i, qp_p), qp_b)) / 51.0);
1016
-           qp = max(qp * qp, 0.001); // Needs to be at least 0.001.
1017
-
1018
-           looseBitrate = static_cast<uint32_t>(bitrate * qp);
1019
-           break;
1020
+   if (GetUsage() == H264Usage::UltraLowLatency) {
1021
+       looseBitrate = GetTargetBitrate();
1022
+   } else {
1023
+       switch (this->GetRateControlMethod()) {
1024
+           case H264RateControlMethod::ConstantBitrate:
1025
+           case H264RateControlMethod::VariableBitrate_LatencyConstrained:
1026
+               looseBitrate = this->GetTargetBitrate();
1027
+               break;
1028
+           case H264RateControlMethod::VariableBitrate_PeakConstrained:
1029
+               looseBitrate = max(this->GetTargetBitrate(), this->GetPeakBitrate());
1030
+               break;
1031
+           case H264RateControlMethod::ConstantQP:
1032
+               // When using Constant QP, one will have to pick a QP that is decent
1033
+               //  in both quality and bitrate. We can easily calculate both the QP
1034
+               //  required for an average bitrate and the average bitrate itself 
1035
+               //  with these formulas:
1036
+               // BITRATE = ((1 - (QP / 51)) ^ 2) * ((Width * Height) * 1.5 * (FPSNumerator / FPSDenumerator))
1037
+               // QP = (1 - sqrt(BITRATE / ((Width * Height) * 1.5 * (FPSNumerator / FPSDenumerator)))) * 51
1038
+
1039
+               auto frameSize = this->GetResolution();
1040
+               auto frameRate = this->GetFrameRate();
1041
+
1042
+               double_t bitrate = frameSize.first * frameSize.second;
1043
+               switch (this->m_ColorFormat) {
1044
+                   case H264ColorFormat::NV12:
1045
+                   case H264ColorFormat::I420:
1046
+                       bitrate *= 1.5;
1047
+                       break;
1048
+                   case H264ColorFormat::YUY2:
1049
+                       bitrate *= 4;
1050
+                       break;
1051
+                   case H264ColorFormat::BGRA:
1052
+                   case H264ColorFormat::RGBA:
1053
+                       bitrate *= 3;
1054
+                       break;
1055
+                   case H264ColorFormat::GRAY:
1056
+                       bitrate *= 1;
1057
+                       break;
1058
+               }
1059
+               bitrate *= frameRate.first / frameRate.second;
1060
+
1061
+               uint8_t qp_i, qp_p, qp_b;
1062
+               qp_i = this->GetIFrameQP();
1063
+               qp_p = this->GetPFrameQP();
1064
+               try { qp_b = this->GetBFrameQP(); } catch (...) { qp_b = 51; }
1065
+               double_t qp = 1 - ((double_t)(min(min(qp_i, qp_p), qp_b)) / 51.0);
1066
+               qp = max(qp * qp, 0.001); // Needs to be at least 0.001.
1067
+
1068
+               looseBitrate = static_cast<uint32_t>(bitrate * qp);
1069
+               break;
1070
+       }
1071
    }
1072
    strictBitrate = static_cast<uint32_t>(looseBitrate * m_FrameRateReverseDivisor);
1073
 
1074
-   #define PI 3.14159265
1075
-   double_t interpVal = (sin(max(min(strictness, 1.0), 0.0) * 90 * (PI / 180))); // sin curve?
1076
-   uint32_t realBitrate = static_cast<uint32_t>(ceil((strictBitrate * interpVal) + (looseBitrate * (1.0 - interpVal))));
1077
-   this->SetVBVBufferSize(realBitrate);
1078
+   // 0% = 100000, 50% = looseBitrate, 100% = strictBitrate
1079
+   strictness = min(max(strictness, 0.0), 1.0);
1080
+   double_t aAB = min(strictness * 2.0, 1.0f);
1081
+   double_t bAB = max(strictness * 2.0 - 1.0, 0.0);
1082
+
1083
+   double_t aFade = (looseBitrate * aAB) + (100000 * (1.0 - aAB));
1084
+   double_t bFade = (strictness * bAB) + (aFade * (1.0 - bAB));
1085
+
1086
+   uint32_t vbvBufferSize = static_cast<uint32_t>(round(bFade));
1087
+   this->SetVBVBufferSize(vbvBufferSize);
1088
 }
1089
 
1090
-uint32_t Plugin::AMD::VCEEncoder::GetVBVBufferSize() {
1091
+uint32_t Plugin::AMD::H264Encoder::GetVBVBufferSize() {
1092
    uint32_t size;
1093
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE, &size);
1094
    if (res != AMF_OK) {
1095
@@ -1457,7 +1546,7 @@
1096
    return size;
1097
 }
1098
 
1099
-void Plugin::AMD::VCEEncoder::SetInitialVBVBufferFullness(double_t fullness) {
1100
+void Plugin::AMD::H264Encoder::SetInitialVBVBufferFullness(double_t fullness) {
1101
    // Clamp Value
1102
    fullness = max(min(fullness, 1), 0); // 0 to 100 %
1103
 
1104
@@ -1468,7 +1557,7 @@
1105
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %f%%.", fullness * 100);
1106
 }
1107
 
1108
-double_t Plugin::AMD::VCEEncoder::GetInitialVBVBufferFullness() {
1109
+double_t Plugin::AMD::H264Encoder::GetInitialVBVBufferFullness() {
1110
    uint32_t vbvBufferFullness;
1111
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_INITIAL_VBV_BUFFER_FULLNESS, &vbvBufferFullness);
1112
    if (res != AMF_OK) {
1113
@@ -1478,7 +1567,7 @@
1114
    return ((double_t)vbvBufferFullness / 64.0);
1115
 }
1116
 
1117
-void Plugin::AMD::VCEEncoder::SetFillerDataEnabled(bool enabled) {
1118
+void Plugin::AMD::H264Encoder::SetFillerDataEnabled(bool enabled) {
1119
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, enabled);
1120
    if (res != AMF_OK) {
1121
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1122
@@ -1486,7 +1575,7 @@
1123
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1124
 }
1125
 
1126
-bool Plugin::AMD::VCEEncoder::IsFillerDataEnabled() {
1127
+bool Plugin::AMD::H264Encoder::IsFillerDataEnabled() {
1128
    bool enabled;
1129
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, &enabled);
1130
    if (res != AMF_OK) {
1131
@@ -1496,7 +1585,7 @@
1132
    return enabled;
1133
 }
1134
 
1135
-void Plugin::AMD::VCEEncoder::SetFrameSkippingEnabled(bool enabled) {
1136
+void Plugin::AMD::H264Encoder::SetFrameSkippingEnabled(bool enabled) {
1137
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, enabled);
1138
    if (res != AMF_OK) {
1139
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1140
@@ -1504,7 +1593,7 @@
1141
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1142
 }
1143
 
1144
-bool Plugin::AMD::VCEEncoder::IsFrameSkippingEnabled() {
1145
+bool Plugin::AMD::H264Encoder::IsFrameSkippingEnabled() {
1146
    bool enabled;
1147
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, &enabled);
1148
    if (res != AMF_OK) {
1149
@@ -1514,7 +1603,7 @@
1150
    return enabled;
1151
 }
1152
 
1153
-void Plugin::AMD::VCEEncoder::SetEnforceHRDRestrictionsEnabled(bool enabled) {
1154
+void Plugin::AMD::H264Encoder::SetEnforceHRDRestrictionsEnabled(bool enabled) {
1155
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_ENFORCE_HRD, enabled);
1156
    if (res != AMF_OK) {
1157
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1158
@@ -1522,7 +1611,7 @@
1159
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1160
 }
1161
 
1162
-bool Plugin::AMD::VCEEncoder::IsEnforceHRDRestrictionsEnabled() {
1163
+bool Plugin::AMD::H264Encoder::IsEnforceHRDRestrictionsEnabled() {
1164
    bool enabled;
1165
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_ENFORCE_HRD, &enabled);
1166
    if (res != AMF_OK) {
1167
@@ -1532,7 +1621,7 @@
1168
    return enabled;
1169
 }
1170
 
1171
-void Plugin::AMD::VCEEncoder::SetIDRPeriod(uint32_t period) {
1172
+void Plugin::AMD::H264Encoder::SetIDRPeriod(uint32_t period) {
1173
    // Clamp Value
1174
    period = max(min(period, 1000), 1); // 1-1000 so that OBS can actually quit.
1175
 
1176
@@ -1543,7 +1632,7 @@
1177
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", period);
1178
 }
1179
 
1180
-uint32_t Plugin::AMD::VCEEncoder::GetIDRPeriod() {
1181
+uint32_t Plugin::AMD::H264Encoder::GetIDRPeriod() {
1182
    int32_t period;
1183
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_IDR_PERIOD, &period);
1184
    if (res != AMF_OK) {
1185
@@ -1553,7 +1642,7 @@
1186
    return period;
1187
 }
1188
 
1189
-void Plugin::AMD::VCEEncoder::SetBFramePattern(VCEBFramePattern pattern) {
1190
+void Plugin::AMD::H264Encoder::SetBFramePattern(H264BFramePattern pattern) {
1191
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_B_PIC_PATTERN, (uint32_t)pattern);
1192
    if (res != AMF_OK) {
1193
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %d failed with error %ls (code %d).", res, pattern);
1194
@@ -1561,17 +1650,17 @@
1195
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", pattern);
1196
 }
1197
 
1198
-Plugin::AMD::VCEBFramePattern Plugin::AMD::VCEEncoder::GetBFramePattern() {
1199
+Plugin::AMD::H264BFramePattern Plugin::AMD::H264Encoder::GetBFramePattern() {
1200
    uint32_t pattern;
1201
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_B_PIC_PATTERN, &pattern);
1202
    if (res != AMF_OK) {
1203
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Failed with error %ls (code %d).", res);
1204
    }
1205
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %d.", pattern);
1206
-   return (Plugin::AMD::VCEBFramePattern)pattern;
1207
+   return (Plugin::AMD::H264BFramePattern)pattern;
1208
 }
1209
 
1210
-void Plugin::AMD::VCEEncoder::SetBFrameDeltaQP(int8_t qp) {
1211
+void Plugin::AMD::H264Encoder::SetBFrameDeltaQP(int8_t qp) {
1212
    // Clamp Value
1213
    qp = clamp(qp, -10, 10);
1214
 
1215
@@ -1582,7 +1671,7 @@
1216
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", qp);
1217
 }
1218
 
1219
-int8_t Plugin::AMD::VCEEncoder::GetBFrameDeltaQP() {
1220
+int8_t Plugin::AMD::H264Encoder::GetBFrameDeltaQP() {
1221
    int32_t qp;
1222
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_B_PIC_DELTA_QP, &qp);
1223
    if (res != AMF_OK) {
1224
@@ -1592,7 +1681,7 @@
1225
    return (int8_t)qp;
1226
 }
1227
 
1228
-void Plugin::AMD::VCEEncoder::SetBFrameReferenceEnabled(bool enabled) {
1229
+void Plugin::AMD::H264Encoder::SetBFrameReferenceEnabled(bool enabled) {
1230
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE, enabled);
1231
    if (res != AMF_OK) {
1232
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1233
@@ -1600,7 +1689,7 @@
1234
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1235
 }
1236
 
1237
-bool Plugin::AMD::VCEEncoder::IsBFrameReferenceEnabled() {
1238
+bool Plugin::AMD::H264Encoder::IsBFrameReferenceEnabled() {
1239
    bool enabled;
1240
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE, &enabled);
1241
    if (res != AMF_OK) {
1242
@@ -1610,7 +1699,7 @@
1243
    return enabled;
1244
 }
1245
 
1246
-void Plugin::AMD::VCEEncoder::SetBFrameReferenceDeltaQP(int8_t qp) {
1247
+void Plugin::AMD::H264Encoder::SetBFrameReferenceDeltaQP(int8_t qp) {
1248
    // Clamp Value
1249
    qp = clamp(qp, -10, 10);
1250
 
1251
@@ -1621,7 +1710,7 @@
1252
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", qp);
1253
 }
1254
 
1255
-int8_t Plugin::AMD::VCEEncoder::GetBFrameReferenceDeltaQP() {
1256
+int8_t Plugin::AMD::H264Encoder::GetBFrameReferenceDeltaQP() {
1257
    int32_t qp;
1258
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP, &qp);
1259
    if (res != AMF_OK) {
1260
@@ -1631,7 +1720,7 @@
1261
    return (int8_t)qp;
1262
 }
1263
 
1264
-void Plugin::AMD::VCEEncoder::SetDeblockingFilterEnabled(bool enabled) {
1265
+void Plugin::AMD::H264Encoder::SetDeblockingFilterEnabled(bool enabled) {
1266
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER, enabled);
1267
    if (res != AMF_OK) {
1268
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1269
@@ -1639,7 +1728,7 @@
1270
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1271
 }
1272
 
1273
-bool Plugin::AMD::VCEEncoder::IsDeblockingFilterEnabled() {
1274
+bool Plugin::AMD::H264Encoder::IsDeblockingFilterEnabled() {
1275
    bool enabled;
1276
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER, &enabled);
1277
    if (res != AMF_OK) {
1278
@@ -1649,7 +1738,7 @@
1279
    return enabled;
1280
 }
1281
 
1282
-void Plugin::AMD::VCEEncoder::SetHalfPixelMotionEstimationEnabled(bool enabled) {
1283
+void Plugin::AMD::H264Encoder::SetHalfPixelMotionEstimationEnabled(bool enabled) {
1284
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL, enabled);
1285
    if (res != AMF_OK) {
1286
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1287
@@ -1657,7 +1746,7 @@
1288
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1289
 }
1290
 
1291
-bool Plugin::AMD::VCEEncoder::IsHalfPixelMotionEstimationEnabled() {
1292
+bool Plugin::AMD::H264Encoder::IsHalfPixelMotionEstimationEnabled() {
1293
    bool enabled;
1294
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL, &enabled);
1295
    if (res != AMF_OK) {
1296
@@ -1667,7 +1756,7 @@
1297
    return enabled;
1298
 }
1299
 
1300
-void Plugin::AMD::VCEEncoder::SetQuarterPixelMotionEstimationEnabled(bool enabled) {
1301
+void Plugin::AMD::H264Encoder::SetQuarterPixelMotionEstimationEnabled(bool enabled) {
1302
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL, enabled);
1303
    if (res != AMF_OK) {
1304
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1305
@@ -1675,7 +1764,7 @@
1306
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1307
 }
1308
 
1309
-bool Plugin::AMD::VCEEncoder::IsQuarterPixelMotionEstimationEnabled() {
1310
+bool Plugin::AMD::H264Encoder::IsQuarterPixelMotionEstimationEnabled() {
1311
    bool enabled;
1312
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL, &enabled);
1313
    if (res != AMF_OK) {
1314
@@ -1690,7 +1779,7 @@
1315
 //////////////////////////////////////////////////////////////////////////
1316
 // Their effect may vary from driver to driver, card to card.
1317
 
1318
-uint32_t Plugin::AMD::VCEEncoder::GetMaxMBPerSec() {
1319
+uint32_t Plugin::AMD::H264Encoder::GetMaxMBPerSec() {
1320
    uint32_t maxMBPerSec;
1321
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"MaxMBPerSec", &maxMBPerSec);
1322
    if (res != AMF_OK) {
1323
@@ -1700,7 +1789,7 @@
1324
    return maxMBPerSec;
1325
 }
1326
 
1327
-void Plugin::AMD::VCEEncoder::SetHeaderInsertionSpacing(uint32_t spacing) {
1328
+void Plugin::AMD::H264Encoder::SetHeaderInsertionSpacing(uint32_t spacing) {
1329
    // Clamp Value
1330
    spacing = max(min(spacing, m_FrameRate.second * 1000), 0);
1331
 
1332
@@ -1711,7 +1800,7 @@
1333
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", spacing);
1334
 }
1335
 
1336
-uint32_t Plugin::AMD::VCEEncoder::GetHeaderInsertionSpacing() {
1337
+uint32_t Plugin::AMD::H264Encoder::GetHeaderInsertionSpacing() {
1338
    int32_t headerInsertionSpacing;
1339
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_HEADER_INSERTION_SPACING, &headerInsertionSpacing);
1340
    if (res != AMF_OK) {
1341
@@ -1721,7 +1810,7 @@
1342
    return headerInsertionSpacing;
1343
 }
1344
 
1345
-void Plugin::AMD::VCEEncoder::SetMaximumLongTermReferenceFrames(uint32_t maximumLTRFrames) {
1346
+void Plugin::AMD::H264Encoder::SetMaximumLongTermReferenceFrames(uint32_t maximumLTRFrames) {
1347
    // Clamp Parameter Value
1348
    maximumLTRFrames = max(min(maximumLTRFrames, 2), 0);
1349
 
1350
@@ -1732,7 +1821,7 @@
1351
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", maximumLTRFrames);
1352
 }
1353
 
1354
-uint32_t Plugin::AMD::VCEEncoder::GetMaximumLongTermReferenceFrames() {
1355
+uint32_t Plugin::AMD::H264Encoder::GetMaximumLongTermReferenceFrames() {
1356
    uint32_t maximumLTRFrames;
1357
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_MAX_LTR_FRAMES, &maximumLTRFrames);
1358
    if (res != AMF_OK) {
1359
@@ -1742,25 +1831,25 @@
1360
    return maximumLTRFrames;
1361
 }
1362
 
1363
-void Plugin::AMD::VCEEncoder::SetCodingType(VCECodingType type) {
1364
-   AMF_RESULT res = m_AMFEncoder->SetProperty(L"CABACEnable", type);
1365
+void Plugin::AMD::H264Encoder::SetCodingType(H264CodingType type) {
1366
+   AMF_RESULT res = m_AMFEncoder->SetProperty(L"CABACEnable", (size_t)type);
1367
    if (res != AMF_OK) {
1368
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, Utility::CodingTypeAsString(type));
1369
    }
1370
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", Utility::CodingTypeAsString(type));
1371
 }
1372
 
1373
-VCECodingType Plugin::AMD::VCEEncoder::GetCodingType() {
1374
+H264CodingType Plugin::AMD::H264Encoder::GetCodingType() {
1375
    uint64_t type;
1376
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"CABACEnable", &type);
1377
    if (res != AMF_OK) {
1378
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Failed with error %ls (code %d).", res);
1379
    }
1380
-   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", Utility::CodingTypeAsString((VCECodingType)type));
1381
-   return (VCECodingType)type;
1382
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", Utility::CodingTypeAsString((H264CodingType)type));
1383
+   return (H264CodingType)type;
1384
 }
1385
 
1386
-void Plugin::AMD::VCEEncoder::SetMaximumAccessUnitSize(uint32_t size) {
1387
+void Plugin::AMD::H264Encoder::SetMaximumAccessUnitSize(uint32_t size) {
1388
    // Clamp Value
1389
    size = max(min(size, 100000000), 0); // 1kbit to 100mbit.
1390
 
1391
@@ -1771,7 +1860,7 @@
1392
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d bits.", size);
1393
 }
1394
 
1395
-uint32_t Plugin::AMD::VCEEncoder::GetMaximumAccessUnitSize() {
1396
+uint32_t Plugin::AMD::H264Encoder::GetMaximumAccessUnitSize() {
1397
    uint32_t size;
1398
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_MAX_AU_SIZE, &size);
1399
    if (res != AMF_OK) {
1400
@@ -1781,7 +1870,7 @@
1401
    return size;
1402
 }
1403
 
1404
-void Plugin::AMD::VCEEncoder::SetWaitForTaskEnabled(bool enabled) {
1405
+void Plugin::AMD::H264Encoder::SetWaitForTaskEnabled(bool enabled) {
1406
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"WaitForTask", enabled);
1407
    if (res != AMF_OK) {
1408
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1409
@@ -1789,7 +1878,7 @@
1410
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1411
 }
1412
 
1413
-bool Plugin::AMD::VCEEncoder::IsWaitForTaskEnabled() {
1414
+bool Plugin::AMD::H264Encoder::IsWaitForTaskEnabled() {
1415
    bool enabled;
1416
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"WaitForTask", &enabled);
1417
    if (res != AMF_OK) {
1418
@@ -1799,7 +1888,7 @@
1419
    return enabled;
1420
 }
1421
 
1422
-void Plugin::AMD::VCEEncoder::SetPreAnalysisPassEnabled(bool enabled) {
1423
+void Plugin::AMD::H264Encoder::SetPreAnalysisPassEnabled(bool enabled) {
1424
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"RateControlPreanalysisEnable", enabled);
1425
    if (res != AMF_OK) {
1426
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1427
@@ -1807,7 +1896,7 @@
1428
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1429
 }
1430
 
1431
-bool Plugin::AMD::VCEEncoder::IsPreAnalysisPassEnabled() {
1432
+bool Plugin::AMD::H264Encoder::IsPreAnalysisPassEnabled() {
1433
    bool enabled;
1434
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"RateControlPreanalysisEnable", &enabled);
1435
    if (res != AMF_OK) {
1436
@@ -1817,7 +1906,7 @@
1437
    return enabled;
1438
 }
1439
 
1440
-void Plugin::AMD::VCEEncoder::SetVBAQEnabled(bool enabled) {
1441
+void Plugin::AMD::H264Encoder::SetVBAQEnabled(bool enabled) {
1442
    const wchar_t* names[] = {
1443
        L"EnableVBAQ", // 16.12.1
1444
        L"EanbleVBAQ", // 16.11.5 and below.
1445
@@ -1838,7 +1927,7 @@
1446
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1447
 }
1448
 
1449
-bool Plugin::AMD::VCEEncoder::IsVBAQEnabled() {
1450
+bool Plugin::AMD::H264Encoder::IsVBAQEnabled() {
1451
    const wchar_t* names[] = {
1452
        L"EnableVBAQ", // 16.12.1
1453
        L"EanbleVBAQ", // 16.11.5 and below.
1454
@@ -1859,7 +1948,7 @@
1455
    return enabled;
1456
 }
1457
 
1458
-void Plugin::AMD::VCEEncoder::SetGOPSize(uint32_t size) {
1459
+void Plugin::AMD::H264Encoder::SetGOPSize(uint32_t size) {
1460
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"GOPSize", (uint32_t)size);
1461
    if (res != AMF_OK) {
1462
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %d failed with error %ls (code %d).", res, size);
1463
@@ -1867,7 +1956,7 @@
1464
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", size);
1465
 }
1466
 
1467
-uint32_t Plugin::AMD::VCEEncoder::GetGOPSize() {
1468
+uint32_t Plugin::AMD::H264Encoder::GetGOPSize() {
1469
    uint32_t size;
1470
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"GOPSize", &size);
1471
    if (res != AMF_OK) {
1472
@@ -1877,7 +1966,7 @@
1473
    return size;
1474
 }
1475
 
1476
-void Plugin::AMD::VCEEncoder::SetGOPAlignmentEnabled(bool enabled) {
1477
+void Plugin::AMD::H264Encoder::SetGOPAlignmentEnabled(bool enabled) {
1478
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"EnableGOPAlignment", enabled);
1479
    if (res != AMF_OK) {
1480
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, enabled ? "Enabled" : "Disabled");
1481
@@ -1885,7 +1974,7 @@
1482
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", enabled ? "Enabled" : "Disabled");
1483
 }
1484
 
1485
-bool Plugin::AMD::VCEEncoder::IsGOPAlignementEnabled() {
1486
+bool Plugin::AMD::H264Encoder::IsGOPAlignementEnabled() {
1487
    bool enabled;
1488
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"EnableGOPAlignment", &enabled);
1489
    if (res != AMF_OK) {
1490
@@ -1895,8 +1984,8 @@
1491
    return enabled;
1492
 }
1493
 
1494
-void Plugin::AMD::VCEEncoder::SetMaximumReferenceFrames(uint32_t numFrames) {
1495
-   auto caps = VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, VCEEncoderType_AVC);
1496
+void Plugin::AMD::H264Encoder::SetMaximumReferenceFrames(uint32_t numFrames) {
1497
+   auto caps = VCECapabilities::GetInstance()->GetAdapterCapabilities(m_API, m_APIAdapter, H264EncoderType::AVC);
1498
    numFrames = clamp(numFrames,
1499
        caps.minReferenceFrames,
1500
        caps.maxReferenceFrames);
1501
@@ -1908,7 +1997,7 @@
1502
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", numFrames);
1503
 }
1504
 
1505
-uint32_t Plugin::AMD::VCEEncoder::GetMaximumReferenceFrames() {
1506
+uint32_t Plugin::AMD::H264Encoder::GetMaximumReferenceFrames() {
1507
    uint32_t numFrames;
1508
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"MaxNumRefFrames", &numFrames);
1509
    if (res != AMF_OK) {
1510
@@ -1918,7 +2007,7 @@
1511
    return numFrames;
1512
 }
1513
 
1514
-void Plugin::AMD::VCEEncoder::SetAspectRatio(uint32_t num, uint32_t den) {
1515
+void Plugin::AMD::H264Encoder::SetAspectRatio(uint32_t num, uint32_t den) {
1516
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"AspectRatio", ::AMFConstructRate(num, den));
1517
    if (res != AMF_OK) {
1518
        std::vector<char> msgBuf;
1519
@@ -1928,7 +2017,7 @@
1520
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d:%d.", num, den);
1521
 }
1522
 
1523
-std::pair<uint32_t, uint32_t> Plugin::AMD::VCEEncoder::GetAspectRatio() {
1524
+std::pair<uint32_t, uint32_t> Plugin::AMD::H264Encoder::GetAspectRatio() {
1525
    AMFRate aspectRatio;
1526
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"AspectRatio", &aspectRatio);
1527
    if (res != AMF_OK) {
1528
@@ -1938,7 +2027,7 @@
1529
    return std::pair<uint32_t, uint32_t>(aspectRatio.num, aspectRatio.den);
1530
 }
1531
 
1532
-void Plugin::AMD::VCEEncoder::SetIntraRefreshMacroblocksPerSlot(uint32_t mbs) {
1533
+void Plugin::AMD::H264Encoder::SetIntraRefreshMacroblocksPerSlot(uint32_t mbs) {
1534
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_INTRA_REFRESH_NUM_MBS_PER_SLOT, (uint32_t)mbs);
1535
    if (res != AMF_OK) {
1536
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %d failed with error %ls (code %d).", res, mbs);
1537
@@ -1946,7 +2035,7 @@
1538
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", mbs);
1539
 }
1540
 
1541
-uint32_t Plugin::AMD::VCEEncoder::GetIntraRefreshMacroblocksPerSlot() {
1542
+uint32_t Plugin::AMD::H264Encoder::GetIntraRefreshMacroblocksPerSlot() {
1543
    int32_t mbs;
1544
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_INTRA_REFRESH_NUM_MBS_PER_SLOT, &mbs);
1545
    if (res != AMF_OK) {
1546
@@ -1956,7 +2045,7 @@
1547
    return mbs;
1548
 }
1549
 
1550
-void Plugin::AMD::VCEEncoder::SetIntraRefreshNumberOfStripes(uint32_t stripes) {
1551
+void Plugin::AMD::H264Encoder::SetIntraRefreshNumberOfStripes(uint32_t stripes) {
1552
    stripes = clamp(stripes, 0, INT_MAX);
1553
 
1554
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"IntraRefreshNumOfStripes", (uint32_t)stripes);
1555
@@ -1967,7 +2056,7 @@
1556
 
1557
 }
1558
 
1559
-uint32_t Plugin::AMD::VCEEncoder::GetIntraRefreshNumberOfStripes() {
1560
+uint32_t Plugin::AMD::H264Encoder::GetIntraRefreshNumberOfStripes() {
1561
    uint32_t stripes;
1562
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"IntraRefreshNumOfStripes", &stripes);
1563
    if (res != AMF_OK) {
1564
@@ -1977,7 +2066,7 @@
1565
    return stripes;
1566
 }
1567
 
1568
-void Plugin::AMD::VCEEncoder::SetSlicesPerFrame(uint32_t slices) {
1569
+void Plugin::AMD::H264Encoder::SetSlicesPerFrame(uint32_t slices) {
1570
    slices = max(slices, 1);
1571
 
1572
    AMF_RESULT res = m_AMFEncoder->SetProperty(AMF_VIDEO_ENCODER_SLICES_PER_FRAME, (uint32_t)slices);
1573
@@ -1987,7 +2076,7 @@
1574
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", slices);
1575
 }
1576
 
1577
-uint32_t Plugin::AMD::VCEEncoder::GetSlicesPerFrame() {
1578
+uint32_t Plugin::AMD::H264Encoder::GetSlicesPerFrame() {
1579
    uint32_t slices;
1580
    AMF_RESULT res = m_AMFEncoder->GetProperty(AMF_VIDEO_ENCODER_SLICES_PER_FRAME, &slices);
1581
    if (res != AMF_OK) {
1582
@@ -1997,7 +2086,7 @@
1583
    return slices;
1584
 }
1585
 
1586
-void Plugin::AMD::VCEEncoder::SetSliceMode(VCESliceMode mode) {
1587
+void Plugin::AMD::H264Encoder::SetSliceMode(H264SliceMode mode) {
1588
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"SliceMode", (uint32_t)mode);
1589
    if (res != AMF_OK) {
1590
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, Utility::SliceModeAsString(mode));
1591
@@ -2005,17 +2094,17 @@
1592
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", Utility::SliceModeAsString(mode));
1593
 }
1594
 
1595
-Plugin::AMD::VCESliceMode Plugin::AMD::VCEEncoder::GetSliceMode() {
1596
+Plugin::AMD::H264SliceMode Plugin::AMD::H264Encoder::GetSliceMode() {
1597
    uint32_t mode;
1598
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"SliceMode", &mode);
1599
    if (res != AMF_OK) {
1600
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Failed with error %ls (code %d).", res);
1601
    }
1602
-   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", Utility::SliceModeAsString((VCESliceMode)mode));
1603
-   return (VCESliceMode)mode;
1604
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", Utility::SliceModeAsString((H264SliceMode)mode));
1605
+   return (H264SliceMode)mode;
1606
 }
1607
 
1608
-void Plugin::AMD::VCEEncoder::SetMaximumSliceSize(uint32_t size) {
1609
+void Plugin::AMD::H264Encoder::SetMaximumSliceSize(uint32_t size) {
1610
    size = clamp(size, 1, INT_MAX);
1611
 
1612
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"MaxSliceSize", (uint32_t)size);
1613
@@ -2025,7 +2114,7 @@
1614
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", size);
1615
 }
1616
 
1617
-uint32_t Plugin::AMD::VCEEncoder::GetMaximumSliceSize() {
1618
+uint32_t Plugin::AMD::H264Encoder::GetMaximumSliceSize() {
1619
    uint32_t size;
1620
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"MaxSliceSize", &size);
1621
    if (res != AMF_OK) {
1622
@@ -2035,7 +2124,7 @@
1623
    return size;
1624
 }
1625
 
1626
-void Plugin::AMD::VCEEncoder::SetSliceControlMode(VCESliceControlMode mode) {
1627
+void Plugin::AMD::H264Encoder::SetSliceControlMode(H264SliceControlMode mode) {
1628
    AMF_RESULT res = m_AMFEncoder->SetProperty(L"SliceControlMode", (uint32_t)mode);
1629
    if (res != AMF_OK) {
1630
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Setting to %s failed with error %ls (code %d).", res, Utility::SliceControlModeAsString(mode));
1631
@@ -2043,17 +2132,17 @@
1632
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %s.", Utility::SliceControlModeAsString(mode));
1633
 }
1634
 
1635
-Plugin::AMD::VCESliceControlMode Plugin::AMD::VCEEncoder::GetSliceControlMode() {
1636
+Plugin::AMD::H264SliceControlMode Plugin::AMD::H264Encoder::GetSliceControlMode() {
1637
    uint32_t mode;
1638
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"SliceControlMode", &mode);
1639
    if (res != AMF_OK) {
1640
        ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Failed with error %ls (code %d).", res);
1641
    }
1642
-   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", Utility::SliceControlModeAsString((VCESliceControlMode)mode));
1643
-   return (VCESliceControlMode)mode;
1644
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Value is %s.", Utility::SliceControlModeAsString((H264SliceControlMode)mode));
1645
+   return (H264SliceControlMode)mode;
1646
 }
1647
 
1648
-void Plugin::AMD::VCEEncoder::SetSliceControlSize(uint32_t size) {
1649
+void Plugin::AMD::H264Encoder::SetSliceControlSize(uint32_t size) {
1650
    // If GetSliceMode() is VCESliceMode_Vertical, then it outputs nothing with the following settings:
1651
    // - SliceControlMode: VCESliceControlMode_Macroblock
1652
    // - SliceControlSize: < 3600
1653
@@ -2063,12 +2152,12 @@
1654
 
1655
    // H264 Macroblock = 16*16 = 256
1656
    switch (GetSliceControlMode()) {
1657
-       case VCESliceControlMode_Off:
1658
+       case H264SliceControlMode::Off:
1659
            return;
1660
-       case VCESliceControlMode_Macroblock:
1661
+       case H264SliceControlMode::Macroblock:
1662
            size = clamp(size, 0, (uint32_t)(ceil(m_FrameSize.first / 16) * ceil(m_FrameSize.second / 16)));
1663
            break;
1664
-       case VCESliceControlMode_Macroblock_Row:
1665
+       case H264SliceControlMode::Macroblock_Row:
1666
            size = clamp(size, 0, (uint32_t)ceil(m_FrameSize.second / 16));
1667
            break;
1668
    }
1669
@@ -2080,7 +2169,7 @@
1670
    AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Set to %d.", size);
1671
 }
1672
 
1673
-uint32_t Plugin::AMD::VCEEncoder::GetSliceControlSize() {
1674
+uint32_t Plugin::AMD::H264Encoder::GetSliceControlSize() {
1675
    uint32_t size;
1676
    AMF_RESULT res = m_AMFEncoder->GetProperty(L"SliceControlSize", &size);
1677
    if (res != AMF_OK) {
1678
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/amf.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/amf.cpp Changed
154
 
1
@@ -43,25 +43,18 @@
2
 
3
 class CustomWriter : public amf::AMFTraceWriter {
4
    public:
5
+
6
    virtual void Write(const wchar_t* scope, const wchar_t* message) override {
7
        const wchar_t* realmsg = &(message[(33 + wcslen(scope) + 2)]); // Skip Time & Scope
8
        size_t msgLen = wcslen(realmsg) - (sizeof(wchar_t));
9
 
10
-       blog(LOG_INFO, "[AMF Encoder] [%.*ls][%ls] %.*ls", 
11
+       blog(LOG_INFO, "[AMF Encoder] [%.*ls][%ls] %.*ls",
12
            12, &(message[11]),
13
-           scope, 
14
+           scope,
15
            msgLen, realmsg);
16
    }
17
 
18
    virtual void Flush() override {}
19
-
20
-   static std::shared_ptr<CustomWriter> GetInstance() {
21
-       static std::shared_ptr<CustomWriter> __instance = std::make_shared<CustomWriter>();
22
-       static std::mutex __mutex;
23
-
24
-       const std::lock_guard<std::mutex> lock(__mutex);
25
-       return __instance;
26
-   }
27
 };
28
 
29
 std::shared_ptr<Plugin::AMD::AMF> Plugin::AMD::AMF::GetInstance() {
30
@@ -76,7 +69,7 @@
31
    AMF_RESULT res = AMF_OK;
32
 
33
    // Initialize AMF Library
34
-   AMF_LOG_DEBUG("<Plugin::AMD::AMF::AMF> Initializing...");
35
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Initializing...");
36
 
37
    #pragma region Null Class Members
38
    m_TimerPeriod = 0;
39
@@ -97,10 +90,9 @@
40
        DWORD error = GetLastError();
41
        std::vector<char> buf(1024);
42
        sprintf(buf.data(), "Unable to load '%ls', error code %ld.", AMF_DLL_NAME, error);
43
-       AMF_LOG_ERROR("%s", buf.data());
44
-       throw std::exception(buf.data(), error);
45
+       throw std::exception(buf.data());
46
    }
47
-   AMF_LOG_DEBUG("<Plugin::AMD::AMF::AMF> Loaded '%ls'.", AMF_DLL_NAME);
48
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Loaded '%ls'.", AMF_DLL_NAME);
49
    #ifdef _WIN32 // Windows: Get Product Version
50
    std::vector<char> verbuf(GetFileVersionInfoSizeW(AMF_DLL_NAME, nullptr));
51
    GetFileVersionInfoW(AMF_DLL_NAME, 0, (DWORD)verbuf.size(), verbuf.data());
52
@@ -135,15 +127,14 @@
53
    if (!AMFQueryVersion) {
54
        DWORD error = GetLastError();
55
        std::vector<char> buf(1024);
56
-       sprintf(buf.data(), "<Plugin::AMD::AMF::AMF> Finding Address of Function '%s' failed with error code %ld.", AMF_QUERY_VERSION_FUNCTION_NAME, error);
57
-       AMF_LOG_ERROR("%s", buf.data());
58
-       throw std::exception(buf.data(), error);
59
+       sprintf(buf.data(), "<" __FUNCTION_NAME__ "> Finding Address of Function '%s' failed with error code %ld.", AMF_QUERY_VERSION_FUNCTION_NAME, error);
60
+       throw std::exception(buf.data());
61
    }
62
    /// Query Runtime Version
63
    m_AMFVersion_Compiler = AMF_FULL_VERSION;
64
    res = AMFQueryVersion(&m_AMFVersion_Runtime);
65
    if (res != AMF_OK)
66
-       ThrowExceptionWithAMFError("<Plugin::AMD::AMF::AMF> Querying Version failed with error %ls (code %ld).", res);
67
+       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Querying Version failed with error %ls (code %ld).", res);
68
    #pragma endregion Query AMF Runtime Version
69
 
70
        /// Find Function for Initializing AMF.
71
@@ -151,31 +142,31 @@
72
    if (!AMFInit) {
73
        DWORD error = GetLastError();
74
        std::vector<char> buf(1024);
75
-       sprintf(buf.data(), "<Plugin::AMD::AMF::AMF> Finding Address of Function '%s' failed with error code %ld.", AMF_INIT_FUNCTION_NAME, error);
76
-       AMF_LOG_ERROR("%s", buf.data());
77
+       sprintf(buf.data(), "<" __FUNCTION_NAME__ "> Finding Address of Function '%s' failed with error code %ld.", AMF_INIT_FUNCTION_NAME, error);
78
        throw std::exception(buf.data(), error);
79
    } else {
80
        res = AMFInit(m_AMFVersion_Runtime, &m_AMFFactory);
81
        if (res != AMF_OK)
82
-           ThrowExceptionWithAMFError("<Plugin::AMD::AMF::AMF> Initializing AMF Library failed with error %ls (code %ld).", res);
83
+           ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Initializing AMF Library failed with error %ls (code %ld).", res);
84
    }
85
-   AMF_LOG_DEBUG("<Plugin::AMD::AMF::AMF> AMF Library initialized.");
86
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> AMF Library initialized.");
87
 
88
    /// Retrieve Trace Object.
89
    res = m_AMFFactory->GetTrace(&m_AMFTrace);
90
    if (res != AMF_OK) {
91
-       ThrowExceptionWithAMFError("<Plugin::AMD::AMF::AMF> Retrieving Trace object failed with error %ls (code %ld).", res);
92
+       ThrowExceptionWithAMFError("<" __FUNCTION_NAME__ "> Retrieving Trace object failed with error %ls (code %ld).", res);
93
    }
94
 
95
    /// Retrieve Debug Object.
96
    res = m_AMFFactory->GetDebug(&m_AMFDebug);
97
    if (res != AMF_OK) {
98
-       AMF_LOG_ERROR("<Plugin::AMD::AMF::AMF> Retrieving Debug object failed with error code %ls (code %ld).", res);
99
+       AMF_LOG_ERROR("<" __FUNCTION_NAME__ "> Retrieving Debug object failed with error code %ls (code %ld).", res);
100
        throw std::exception("", res);
101
    }
102
 
103
-   /// Register Custom Trace Writer and disable Debug Tracing.
104
-   m_AMFTrace->RegisterWriter(L"OBSWriter", CustomWriter::GetInstance().get(), true);
105
+   /// Register Trace Writer and disable Debug Tracing.
106
+   m_TraceWriter = new CustomWriter();
107
+   m_AMFTrace->RegisterWriter(L"OBSWriter", m_TraceWriter, true);
108
    this->EnableDebugTrace(false);
109
 
110
    // Log success
111
@@ -191,15 +182,16 @@
112
        lProductVersionSize, pProductVersion
113
    );
114
 
115
-   AMF_LOG_DEBUG("<Plugin::AMD::AMF::AMF> Initialized.");
116
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Initialized.");
117
 }
118
 
119
 Plugin::AMD::AMF::~AMF() {
120
-   AMF_LOG_DEBUG("<Plugin::AMD::AMF::AMF> Finalizing.");
121
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Finalizing.");
122
 
123
-   /// Unregister Writer
124
-   if (m_AMFTrace)
125
-       m_AMFTrace->UnregisterWriter(L"OBSWriter");
126
+   /// Unregister Trace Writer
127
+   m_AMFTrace->UnregisterWriter(L"OBSWriter");
128
+   delete m_TraceWriter;
129
+   m_TraceWriter = nullptr;
130
 
131
    // Free Library again
132
    if (m_AMFModule)
133
@@ -218,7 +210,7 @@
134
    AMFInit = nullptr;
135
    #pragma endregion Null Class Members
136
 
137
-   AMF_LOG_DEBUG("<Plugin::AMD::AMF::AMF> Finalized.");
138
+   AMF_LOG_DEBUG("<" __FUNCTION_NAME__ "> Finalized.");
139
 }
140
 
141
 amf::AMFFactory* Plugin::AMD::AMF::GetFactory() {
142
@@ -235,9 +227,9 @@
143
 
144
 void Plugin::AMD::AMF::EnableDebugTrace(bool enable) {
145
    if (!m_AMFTrace)
146
-       throw std::exception(__FUNCTION_NAME__ " called without a AMFTrace object!");
147
+       throw std::exception("<" __FUNCTION_NAME__ "> called without a AMFTrace object!");
148
    if (!m_AMFDebug)
149
-       throw std::exception(__FUNCTION_NAME__ " called without a AMFDebug object!");
150
+       throw std::exception("<" __FUNCTION_NAME__ "> called without a AMFDebug object!");
151
 
152
    m_AMFTrace->EnableWriter(AMF_TRACE_WRITER_CONSOLE, false);
153
    m_AMFTrace->SetWriterLevel(AMF_TRACE_WRITER_CONSOLE, AMF_TRACE_ERROR);
154
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/api-d3d11.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/api-d3d11.cpp Changed
10
 
1
@@ -352,6 +352,6 @@
2
    delete instance;
3
 }
4
 
5
-Plugin::API::APIType Plugin::API::Direct3D11::GetType() {
6
-   return APIType_Direct3D11;
7
+Plugin::API::Type Plugin::API::Direct3D11::GetType() {
8
+   return Type::Direct3D11;
9
 }
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/api-d3d9.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/api-d3d9.cpp Changed
10
 
1
@@ -236,6 +236,6 @@
2
    delete instance;
3
 }
4
 
5
-Plugin::API::APIType Plugin::API::Direct3D9::GetType() {
6
-   return APIType_Direct3D9;
7
+Plugin::API::Type Plugin::API::Direct3D9::GetType() {
8
+   return Type::Direct3D9;
9
 }
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/api-host.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/api-host.cpp Changed
12
 
1
@@ -36,8 +36,8 @@
2
    return "Host";
3
 }
4
 
5
-Plugin::API::APIType Plugin::API::Host::GetType() {
6
-   return APIType_Host;
7
+Plugin::API::Type Plugin::API::Host::GetType() {
8
+   return Type::Host;
9
 }
10
 
11
 std::vector<Adapter> Plugin::API::Host::EnumerateAdapters() {
12
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/api-opengl.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/api-opengl.cpp Changed
10
 
1
@@ -81,6 +81,6 @@
2
    return nullptr;
3
 }
4
 
5
-Plugin::API::APIType Plugin::API::OpenGL::GetType() {
6
-   return APIType_OpenGL;
7
+Plugin::API::Type Plugin::API::OpenGL::GetType() {
8
+   return Type::OpenGL;
9
 }
10
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/enc-h264.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/enc-h264.cpp Changed
1486
 
1
@@ -44,7 +44,7 @@
2
 using namespace Plugin::AMD;
3
 using namespace Plugin::Interface;
4
 
5
-enum Presets {
6
+enum class Presets : int8_t {
7
    None = -1,
8
    ResetToDefaults = 0,
9
    Recording,
10
@@ -54,7 +54,7 @@
11
    Twitch,
12
    YouTube,
13
 };
14
-enum ViewMode {
15
+enum class ViewMode :uint8_t {
16
    Basic,
17
    Advanced,
18
    Expert,
19
@@ -66,7 +66,7 @@
20
    bool haveAVCsupport = false;
21
    for (auto api : Plugin::API::Base::EnumerateAPIs()) {
22
        for (auto adapter : api->EnumerateAdapters()) {
23
-           auto caps = VCECapabilities::GetInstance()->GetAdapterCapabilities(api, adapter, VCEEncoderType_AVC);
24
+           auto caps = VCECapabilities::GetInstance()->GetAdapterCapabilities(api, adapter, H264EncoderType::AVC);
25
            if (caps.acceleration_type != amf::AMF_ACCEL_NOT_SUPPORTED)
26
                haveAVCsupport = true;
27
        }
28
@@ -118,7 +118,7 @@
29
        AMF_LOG_ERROR("%s", e->what());
30
        delete e;
31
    } catch (...) {
32
-       AMF_LOG_ERROR("Unknown Exception during start up.");
33
+       AMF_LOG_ERROR("Unknown Exception.");
34
    }
35
    if (enc)
36
        delete enc;
37
@@ -136,7 +136,7 @@
38
        AMF_LOG_ERROR("%s", e->what());
39
        delete e;
40
    } catch (...) {
41
-       AMF_LOG_ERROR("Unknown Exception during shut down.");
42
+       AMF_LOG_ERROR("Unknown Exception.");
43
    }
44
    data = nullptr;
45
 }
46
@@ -145,12 +145,15 @@
47
    try {
48
        return static_cast<Plugin::Interface::H264Interface*>(data)->encode(frame, packet, received_packet);
49
    } catch (std::exception e) {
50
-       AMF_LOG_ERROR("Exception: %s", e.what());
51
-       AMF_LOG_ERROR("Unable to encode, see log for more information.");
52
-       return false;
53
+       AMF_LOG_ERROR("%s", e.what());
54
+   } catch (std::exception* e) {
55
+       AMF_LOG_ERROR("%s", e->what());
56
+       delete e;
57
    } catch (...) {
58
+       AMF_LOG_ERROR("Unknown Exception.");
59
        throw;
60
    }
61
+   return false;
62
 }
63
 
64
 void Plugin::Interface::H264Interface::get_defaults(obs_data_t *data) {
65
@@ -168,20 +171,20 @@
66
    #pragma endregion OBS - Enforce Streaming Service Restrictions
67
 
68
    // Preset
69
-   obs_data_set_default_int(data, AMF_H264_PRESET, -1);
70
+   obs_data_set_default_int(data, AMF_H264_PRESET, static_cast<int32_t>(Presets::None));
71
 
72
    // Static Properties
73
-   obs_data_set_default_int(data, AMF_H264_USAGE, VCEUsage_Transcoding);
74
-   obs_data_set_default_int(data, AMF_H264_QUALITY_PRESET, VCEQualityPreset_Balanced);
75
-   obs_data_set_default_int(data, AMF_H264_PROFILE, VCEProfile_Main);
76
-   obs_data_set_default_int(data, AMF_H264_PROFILELEVEL, VCEProfileLevel_Automatic);
77
+   obs_data_set_default_int(data, AMF_H264_USAGE, static_cast<int32_t>(H264Usage::Transcoding));
78
+   obs_data_set_default_int(data, AMF_H264_QUALITY_PRESET, static_cast<int32_t>(H264QualityPreset::Balanced));
79
+   obs_data_set_default_int(data, AMF_H264_PROFILE, static_cast<int32_t>(H264Profile::Main));
80
+   obs_data_set_default_int(data, AMF_H264_PROFILELEVEL, static_cast<int32_t>(H264ProfileLevel::Automatic));
81
 
82
    // Rate Control Properties
83
    obs_data_set_int(data, "last" vstr(AMF_H264_RATECONTROLMETHOD), -1);
84
-   obs_data_set_default_int(data, AMF_H264_RATECONTROLMETHOD, VCERateControlMethod_ConstantBitrate);
85
+   obs_data_set_default_int(data, AMF_H264_RATECONTROLMETHOD, static_cast<int32_t>(H264RateControlMethod::ConstantBitrate));
86
    obs_data_set_default_int(data, AMF_H264_BITRATE_TARGET, 3500);
87
    obs_data_set_default_int(data, AMF_H264_BITRATE_PEAK, 9000);
88
-   obs_data_set_default_int(data, AMF_H264_QP_MINIMUM, 0);
89
+   obs_data_set_default_int(data, AMF_H264_QP_MINIMUM, 11);
90
    obs_data_set_default_int(data, AMF_H264_QP_MAXIMUM, 51);
91
    obs_data_set_default_int(data, AMF_H264_QP_IFRAME, 22);
92
    obs_data_set_default_int(data, AMF_H264_QP_PFRAME, 22);
93
@@ -189,7 +192,7 @@
94
    obs_data_set_int(data, "last" vstr(AMF_H264_VBVBUFFER), -1);
95
    obs_data_set_default_int(data, AMF_H264_VBVBUFFER, 0);
96
    obs_data_set_default_int(data, AMF_H264_VBVBUFFER_SIZE, 3500);
97
-   obs_data_set_default_double(data, AMF_H264_VBVBUFFER_STRICTNESS, 0);
98
+   obs_data_set_default_double(data, AMF_H264_VBVBUFFER_STRICTNESS, 50);
99
    obs_data_set_default_double(data, AMF_H264_VBVBUFFER_FULLNESS, 100);
100
    obs_data_set_default_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE, 0);
101
    obs_data_set_default_int(data, AMF_H264_FILLERDATA, 1);
102
@@ -200,7 +203,7 @@
103
    obs_data_set_default_double(data, AMF_H264_KEYFRAME_INTERVAL, 2);
104
    obs_data_set_default_int(data, AMF_H264_IDR_PERIOD, 60);
105
    obs_data_set_int(data, "last" vstr(AMF_H264_BFRAME_PATTERN), -1);
106
-   obs_data_set_default_int(data, AMF_H264_BFRAME_PATTERN, VCEBFramePattern_None);
107
+   obs_data_set_default_int(data, AMF_H264_BFRAME_PATTERN, static_cast<int32_t>(H264BFramePattern::None));
108
    obs_data_set_int(data, "last" vstr(AMF_H264_BFRAME_REFERENCE), -1);
109
    obs_data_set_default_int(data, AMF_H264_BFRAME_REFERENCE, 0);
110
    obs_data_set_default_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP, 2);
111
@@ -208,17 +211,17 @@
112
    obs_data_set_default_int(data, AMF_H264_DEBLOCKINGFILTER, 1);
113
 
114
    // Miscellaneous Control Properties
115
-   obs_data_set_default_int(data, AMF_H264_SCANTYPE, VCEScanType_Progressive);
116
+   obs_data_set_default_int(data, AMF_H264_SCANTYPE, static_cast<int32_t>(H264ScanType::Progressive));
117
    obs_data_set_default_int(data, AMF_H264_MOTIONESTIMATION, 3);
118
 
119
    // Experimental Properties
120
    obs_data_set_default_int(data, AMF_H264_MAXIMUMLTRFRAMES, 0);
121
-   obs_data_set_default_int(data, AMF_H264_CODINGTYPE, VCECodingType_Default);
122
+   obs_data_set_default_int(data, AMF_H264_CODINGTYPE, static_cast<int32_t>(H264CodingType::Default));
123
    obs_data_set_default_int(data, AMF_H264_HEADER_INSERTION_SPACING, 0);
124
    obs_data_set_default_int(data, AMF_H264_SLICESPERFRAME, 1);
125
-   obs_data_set_default_int(data, AMF_H264_SLICEMODE, VCESliceMode_Horizontal);
126
+   obs_data_set_default_int(data, AMF_H264_SLICEMODE, static_cast<int32_t>(H264SliceMode::Horizontal));
127
    obs_data_set_default_int(data, AMF_H264_MAXIMUMSLICESIZE, INT_MAX);
128
-   obs_data_set_default_int(data, AMF_H264_SLICECONTROLMODE, VCESliceControlMode_Off);
129
+   obs_data_set_default_int(data, AMF_H264_SLICECONTROLMODE, static_cast<int32_t>(H264SliceControlMode::Off));
130
    obs_data_set_default_int(data, AMF_H264_SLICECONTROLSIZE, 0);
131
    obs_data_set_default_int(data, AMF_H264_INTRAREFRESH_NUMBEROFSTRIPES, 0);
132
    obs_data_set_default_int(data, AMF_H264_INTRAREFRESH_MACROBLOCKSPERSLOT, 0);
133
@@ -236,8 +239,9 @@
134
    obs_data_set_default_int(data, AMF_H264_VIDEOADAPTER, 0);
135
    obs_data_set_default_int(data, AMF_H264_OPENCL, 0);
136
    obs_data_set_int(data, "last" vstr(AMF_H264_VIEW), -1);
137
-   obs_data_set_default_int(data, AMF_H264_VIEW, ViewMode::Basic);
138
+   obs_data_set_default_int(data, AMF_H264_VIEW, static_cast<int32_t>(ViewMode::Basic));
139
    obs_data_set_default_bool(data, AMF_H264_DEBUG, false);
140
+   obs_data_set_default_int(data, AMF_H264_VERSION, 0x0001000400030005ull);
141
 }
142
 
143
 static void fill_api_list(obs_property_t* p) {
144
@@ -263,22 +267,22 @@
145
    p = obs_properties_add_list(props, AMF_H264_PRESET, TEXT_T(AMF_H264_PRESET), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
146
    obs_property_set_modified_callback(p, properties_modified);
147
    obs_property_list_add_int(p, "", -1);
148
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_RESETTODEFAULTS), Presets::ResetToDefaults);
149
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_RECORDING), Presets::Recording);
150
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_HIGHQUALITY), Presets::HighQuality);
151
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_INDISTINGUISHABLE), Presets::Indistinguishable);
152
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_LOSSLESS), Presets::Lossless);
153
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_TWITCH), Presets::Twitch);
154
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_YOUTUBE), Presets::YouTube);
155
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_RESETTODEFAULTS), static_cast<int32_t>(Presets::ResetToDefaults));
156
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_RECORDING), static_cast<int32_t>(Presets::Recording));
157
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_HIGHQUALITY), static_cast<int32_t>(Presets::HighQuality));
158
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_INDISTINGUISHABLE), static_cast<int32_t>(Presets::Indistinguishable));
159
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_LOSSLESS), static_cast<int32_t>(Presets::Lossless));
160
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_TWITCH), static_cast<int32_t>(Presets::Twitch));
161
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_PRESET_YOUTUBE), static_cast<int32_t>(Presets::YouTube));
162
    #pragma endregion Preset
163
 
164
    #pragma region Static Properties
165
    #pragma region Usage
166
    p = obs_properties_add_list(props, AMF_H264_USAGE, TEXT_T(AMF_H264_USAGE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
167
    obs_property_set_long_description(p, TEXT_T(AMF_H264_USAGE_DESCRIPTION));
168
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_USAGE_TRANSCODING), VCEUsage_Transcoding);
169
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_USAGE_ULTRALOWLATENCY), VCEUsage_UltraLowLatency);
170
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_USAGE_LOWLATENCY), VCEUsage_LowLatency);
171
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_USAGE_TRANSCODING), static_cast<int32_t>(H264Usage::Transcoding));
172
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_USAGE_ULTRALOWLATENCY), static_cast<int32_t>(H264Usage::UltraLowLatency));
173
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_USAGE_LOWLATENCY), static_cast<int32_t>(H264Usage::LowLatency));
174
    // Webcam requires SVC, which is not something OBSs properties API makes easy to support. Nor would it look like anything usable.
175
    //obs_property_list_add_int(list, TEXT_T(AMF_H264_USAGE_WEBCAM), VCEUsage_Webcam);
176
    #pragma endregion Usage
177
@@ -286,9 +290,9 @@
178
    #pragma region Quality Preset
179
    p = obs_properties_add_list(props, AMF_H264_QUALITY_PRESET, TEXT_T(AMF_H264_QUALITY_PRESET), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
180
    obs_property_set_long_description(p, TEXT_T(AMF_H264_QUALITY_PRESET_DESCRIPTION));
181
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_QUALITY_PRESET_SPEED), VCEQualityPreset_Speed);
182
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_QUALITY_PRESET_BALANCED), VCEQualityPreset_Balanced);
183
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_QUALITY_PRESET_QUALITY), VCEQualityPreset_Quality);
184
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_QUALITY_PRESET_SPEED), static_cast<int32_t>(H264QualityPreset::Speed));
185
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_QUALITY_PRESET_BALANCED), static_cast<int32_t>(H264QualityPreset::Balanced));
186
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_QUALITY_PRESET_QUALITY), static_cast<int32_t>(H264QualityPreset::Quality));
187
    #pragma endregion Quality Preset
188
 
189
    #pragma region Profile
190
@@ -306,20 +310,20 @@
191
    #pragma region Method
192
    p = obs_properties_add_list(props, AMF_H264_RATECONTROLMETHOD, TEXT_T(AMF_H264_RATECONTROLMETHOD), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
193
    obs_property_set_long_description(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_DESCRIPTION));
194
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_CQP), VCERateControlMethod_ConstantQP);
195
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_CBR), VCERateControlMethod_ConstantBitrate);
196
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_VBR), VCERateControlMethod_VariableBitrate_PeakConstrained);
197
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_VBR_LAT), VCERateControlMethod_VariableBitrate_LatencyConstrained);
198
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_CQP), static_cast<int32_t>(H264RateControlMethod::ConstantQP));
199
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_CBR), static_cast<int32_t>(H264RateControlMethod::ConstantBitrate));
200
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_VBR), static_cast<int32_t>(H264RateControlMethod::VariableBitrate_PeakConstrained));
201
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_RATECONTROLMETHOD_VBR_LAT), static_cast<int32_t>(H264RateControlMethod::VariableBitrate_LatencyConstrained));
202
    obs_property_set_modified_callback(p, properties_modified);
203
    #pragma endregion Method
204
 
205
    #pragma region Method Parameters
206
    /// Bitrate Constraints
207
    p = obs_properties_add_int(props, AMF_H264_BITRATE_TARGET, TEXT_T(AMF_H264_BITRATE_TARGET), 0,
208
-       1, 1);
209
+                              1, 1);
210
    obs_property_set_long_description(p, TEXT_T(AMF_H264_BITRATE_TARGET_DESCRIPTION));
211
    p = obs_properties_add_int(props, AMF_H264_BITRATE_PEAK, TEXT_T(AMF_H264_BITRATE_PEAK), 0,
212
-       1, 1);
213
+                              1, 1);
214
    obs_property_set_long_description(p, TEXT_T(AMF_H264_BITRATE_PEAK_DESCRIPTION));
215
 
216
    /// Minimum QP, Maximum QP
217
@@ -387,7 +391,9 @@
218
    #pragma region B-Frames
219
    /// B-Frames Pattern
220
    p = obs_properties_add_int_slider(props, AMF_H264_BFRAME_PATTERN, TEXT_T(AMF_H264_BFRAME_PATTERN),
221
-       VCEBFramePattern_None, VCEBFramePattern_Three, 1);
222
+                                     static_cast<int32_t>(H264BFramePattern::None),
223
+                                     static_cast<int32_t>(H264BFramePattern::Three),
224
+                                     1);
225
    obs_property_set_long_description(p, TEXT_T(AMF_H264_BFRAME_PATTERN_DESCRIPTION));
226
    obs_property_set_modified_callback(p, properties_modified);
227
    /// Enable Reference to B-Frames (2nd Generation GCN and newer)
228
@@ -414,8 +420,8 @@
229
    /// Scan Type
230
    p = obs_properties_add_list(props, AMF_H264_SCANTYPE, TEXT_T(AMF_H264_SCANTYPE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
231
    obs_property_set_long_description(p, TEXT_T(AMF_H264_SCANTYPE_DESCRIPTION));
232
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_SCANTYPE_PROGRESSIVE), VCEScanType_Progressive);
233
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_SCANTYPE_INTERLACED), VCEScanType_Interlaced);
234
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_SCANTYPE_PROGRESSIVE), static_cast<int32_t>(H264ScanType::Progressive));
235
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_SCANTYPE_INTERLACED), static_cast<int32_t>(H264ScanType::Interlaced));
236
 
237
    /// Motion Estimation
238
    p = obs_properties_add_list(props, AMF_H264_MOTIONESTIMATION, TEXT_T(AMF_H264_MOTIONESTIMATION), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
239
@@ -430,9 +436,9 @@
240
    #pragma region Coding Type
241
    p = obs_properties_add_list(props, AMF_H264_CODINGTYPE, TEXT_T(AMF_H264_CODINGTYPE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
242
    obs_property_set_long_description(p, TEXT_T(AMF_H264_CODINGTYPE_DESCRIPTION));
243
-   obs_property_list_add_int(p, TEXT_T(AMF_UTIL_DEFAULT), VCECodingType_Default);
244
-   obs_property_list_add_int(p, "CABAC", VCECodingType_CABAC);
245
-   obs_property_list_add_int(p, "CALVC", VCECodingType_CALVC);
246
+   obs_property_list_add_int(p, TEXT_T(AMF_UTIL_DEFAULT), static_cast<int32_t>(H264CodingType::Default));
247
+   obs_property_list_add_int(p, "CABAC", static_cast<int32_t>(H264CodingType::CABAC));
248
+   obs_property_list_add_int(p, "CALVC", static_cast<int32_t>(H264CodingType::CALVC));
249
    #pragma endregion Coding Type
250
 
251
    #pragma region Long Term Reference Frames
252
@@ -453,8 +459,8 @@
253
    /// Slice Mode
254
    p = obs_properties_add_list(props, AMF_H264_SLICEMODE, TEXT_T(AMF_H264_SLICEMODE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
255
    obs_property_set_long_description(p, TEXT_T(AMF_H264_SLICEMODE_DESCRIPTION));
256
-   obs_property_list_add_int(p, "Horizontal", VCESliceMode_Horizontal);
257
-   obs_property_list_add_int(p, "Vertical", VCESliceMode_Vertical);
258
+   obs_property_list_add_int(p, "Horizontal", static_cast<int32_t>(H264SliceMode::Horizontal));
259
+   obs_property_list_add_int(p, "Vertical", static_cast<int32_t>(H264SliceMode::Vertical));
260
 
261
    /// Maximum Slice Size
262
    p = obs_properties_add_int_slider(props, AMF_H264_MAXIMUMSLICESIZE, TEXT_T(AMF_H264_MAXIMUMSLICESIZE), 1, INT_MAX, 1);
263
@@ -463,9 +469,9 @@
264
    /// Slice Control Mode
265
    p = obs_properties_add_list(props, AMF_H264_SLICECONTROLMODE, TEXT_T(AMF_H264_SLICECONTROLMODE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
266
    obs_property_set_long_description(p, TEXT_T(AMF_H264_SLICECONTROLMODE_DESCRIPTION));
267
-   obs_property_list_add_int(p, Utility::SliceControlModeAsString(VCESliceControlMode_Off), VCESliceControlMode_Off);
268
-   obs_property_list_add_int(p, Utility::SliceControlModeAsString(VCESliceControlMode_Macroblock), VCESliceControlMode_Macroblock);
269
-   obs_property_list_add_int(p, Utility::SliceControlModeAsString(VCESliceControlMode_Macroblock_Row), VCESliceControlMode_Macroblock_Row);
270
+   obs_property_list_add_int(p, Utility::SliceControlModeAsString(H264SliceControlMode::Off), static_cast<int32_t>(H264SliceControlMode::Off));
271
+   obs_property_list_add_int(p, Utility::SliceControlModeAsString(H264SliceControlMode::Macroblock), static_cast<int32_t>(H264SliceControlMode::Macroblock));
272
+   obs_property_list_add_int(p, Utility::SliceControlModeAsString(H264SliceControlMode::Macroblock_Row), static_cast<int32_t>(H264SliceControlMode::Macroblock_Row));
273
 
274
    /// Slice Control Size
275
    p = obs_properties_add_int_slider(props, AMF_H264_SLICECONTROLSIZE, TEXT_T(AMF_H264_SLICECONTROLSIZE), 0, 34560, 1); // 4096x2160 / 16x16
276
@@ -537,10 +543,10 @@
277
    /// View Mode
278
    p = obs_properties_add_list(props, AMF_H264_VIEW, TEXT_T(AMF_H264_VIEW), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
279
    obs_property_set_long_description(p, TEXT_T(AMF_H264_VIEW_DESCRIPTION));
280
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_VIEW_BASIC), ViewMode::Basic);
281
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_VIEW_ADVANCED), ViewMode::Advanced);
282
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_VIEW_EXPERT), ViewMode::Expert);
283
-   obs_property_list_add_int(p, TEXT_T(AMF_H264_VIEW_MASTER), ViewMode::Master);
284
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_VIEW_BASIC), static_cast<int32_t>(ViewMode::Basic));
285
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_VIEW_ADVANCED), static_cast<int32_t>(ViewMode::Advanced));
286
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_VIEW_EXPERT), static_cast<int32_t>(ViewMode::Expert));
287
+   obs_property_list_add_int(p, TEXT_T(AMF_H264_VIEW_MASTER), static_cast<int32_t>(ViewMode::Master));
288
    obs_property_set_modified_callback(p, properties_modified);
289
 
290
    /// Debug
291
@@ -594,13 +600,28 @@
292
    }
293
 }
294
 
295
+static void obs_data_transfer_settings(obs_data_t * data) {
296
+   #pragma region Version Differences
297
+   uint64_t version = obs_data_get_int(data, AMF_H264_VERSION);
298
+   switch (version) {
299
+       case 0x0001000400030005ull:
300
+           obs_data_set_double(data, AMF_H264_VBVBUFFER_STRICTNESS, obs_data_get_double(data, AMF_H264_VBVBUFFER_STRICTNESS) + 50.0);
301
+       case PLUGIN_VERSION_FULL:
302
+           obs_data_set_int(data, AMF_H264_VERSION, PLUGIN_VERSION_FULL);
303
+           break;
304
+   }
305
+   #pragma endregion Version Differences
306
+}
307
+
308
 bool Plugin::Interface::H264Interface::properties_modified(obs_properties_t *props, obs_property_t *, obs_data_t *data) {
309
    bool result = false;
310
    obs_property_t* p;
311
 
312
+   obs_data_transfer_settings(data);
313
+
314
    #pragma region Presets
315
-   Presets lastPreset = (Presets)obs_data_get_int(data, "last" vstr(AMF_H264_PRESET)),
316
-       preset = (Presets)obs_data_get_int(data, AMF_H264_PRESET);
317
+   Presets lastPreset = static_cast<Presets>(obs_data_get_int(data, "last" vstr(AMF_H264_PRESET))),
318
+       preset = static_cast<Presets>(obs_data_get_int(data, AMF_H264_PRESET));
319
    if (lastPreset != preset) { // Reset State
320
        obs_property_t* pn = obs_properties_first(props);
321
        do {
322
@@ -613,125 +634,98 @@
323
        result = true;
324
 
325
    switch (preset) {
326
-       case ResetToDefaults:
327
+       case Presets::ResetToDefaults:
328
            #pragma region Default
329
-       {
330
-           obs_property_t* pn = obs_properties_first(props);
331
-           do {
332
-               const char* name = obs_property_name(pn);
333
-
334
-               // Do not reset Video Adapter or API.
335
-               if ((strcmp(name, AMF_H264_VIDEOAPI) == 0) || (strcmp(name, AMF_H264_VIDEOADAPTER) == 0))
336
-                   continue;
337
-
338
-               switch (obs_property_get_type(pn)) {
339
-                   case obs_property_type::OBS_PROPERTY_BOOL:
340
-                       obs_data_set_bool(data, name, obs_data_get_default_bool(data, name));
341
-                       break;
342
-                   case obs_property_type::OBS_PROPERTY_FLOAT:
343
-                       obs_data_set_double(data, name, obs_data_get_default_double(data, name));
344
-                       break;
345
-                   case obs_property_type::OBS_PROPERTY_INT:
346
-                       obs_data_set_int(data, name, obs_data_get_default_int(data, name));
347
-                       break;
348
-                   case obs_property_type::OBS_PROPERTY_TEXT:
349
-                       obs_data_set_string(data, name, obs_data_get_default_string(data, name));
350
-                       break;
351
-                   case obs_property_type::OBS_PROPERTY_LIST:
352
-                       switch (obs_property_list_format(pn)) {
353
-                           case obs_combo_format::OBS_COMBO_FORMAT_INT:
354
-                               obs_data_set_int(data, name, obs_data_get_default_int(data, name));
355
-                               break;
356
-                           case obs_combo_format::OBS_COMBO_FORMAT_FLOAT:
357
-                               obs_data_set_double(data, name, obs_data_get_default_double(data, name));
358
-                               break;
359
-                           case obs_combo_format::OBS_COMBO_FORMAT_STRING:
360
-                               obs_data_set_string(data, name, obs_data_get_default_string(data, name));
361
-                               break;
362
-                       }
363
-                       break;
364
-               }
365
-               obs_property_set_enabled(pn, true);
366
-           } while (obs_property_next(&pn));
367
-       }
368
-       break;
369
-       #pragma endregion Default
370
-       case Recording:
371
+           {
372
+               obs_property_t* pn = obs_properties_first(props);
373
+               do {
374
+                   const char* name = obs_property_name(pn);
375
+
376
+                   // Do not reset Video Adapter or API.
377
+                   if ((strcmp(name, AMF_H264_VIDEOAPI) == 0) || (strcmp(name, AMF_H264_VIDEOADAPTER) == 0))
378
+                       continue;
379
+
380
+                   switch (obs_property_get_type(pn)) {
381
+                       case obs_property_type::OBS_PROPERTY_BOOL:
382
+                           obs_data_set_bool(data, name, obs_data_get_default_bool(data, name));
383
+                           break;
384
+                       case obs_property_type::OBS_PROPERTY_FLOAT:
385
+                           obs_data_set_double(data, name, obs_data_get_default_double(data, name));
386
+                           break;
387
+                       case obs_property_type::OBS_PROPERTY_INT:
388
+                           obs_data_set_int(data, name, obs_data_get_default_int(data, name));
389
+                           break;
390
+                       case obs_property_type::OBS_PROPERTY_TEXT:
391
+                           obs_data_set_string(data, name, obs_data_get_default_string(data, name));
392
+                           break;
393
+                       case obs_property_type::OBS_PROPERTY_LIST:
394
+                           switch (obs_property_list_format(pn)) {
395
+                               case obs_combo_format::OBS_COMBO_FORMAT_INT:
396
+                                   obs_data_set_int(data, name, obs_data_get_default_int(data, name));
397
+                                   break;
398
+                               case obs_combo_format::OBS_COMBO_FORMAT_FLOAT:
399
+                                   obs_data_set_double(data, name, obs_data_get_default_double(data, name));
400
+                                   break;
401
+                               case obs_combo_format::OBS_COMBO_FORMAT_STRING:
402
+                                   obs_data_set_string(data, name, obs_data_get_default_string(data, name));
403
+                                   break;
404
+                           }
405
+                           break;
406
+                   }
407
+                   obs_property_set_enabled(pn, true);
408
+               } while (obs_property_next(&pn));
409
+           }
410
+           break;
411
+           #pragma endregion Default
412
+       case Presets::Recording:
413
            #pragma region Recording
414
            // Static Properties
415
            //obs_data_set_int(data, AMF_H264_USAGE, VCEUsage_Transcoding);
416
-           obs_data_set_int(data, AMF_H264_PROFILE, VCEProfile_High);
417
+           obs_data_set_int(data, AMF_H264_PROFILE, static_cast<int32_t>(H264Profile::High));
418
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILE), false);
419
-           obs_data_set_int(data, AMF_H264_PROFILELEVEL, VCEProfileLevel_Automatic);
420
+           obs_data_set_int(data, AMF_H264_PROFILELEVEL, static_cast<int32_t>(H264ProfileLevel::Automatic));
421
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILELEVEL), false);
422
            //obs_data_set_int(data, AMF_H264_MAXIMUMLTRFRAMES, obs_data_get_default_int(data, AMF_H264_MAXIMUMLTRFRAMES));
423
 
424
            // Rate Control Properties
425
-           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, VCERateControlMethod_VariableBitrate_LatencyConstrained);
426
+           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, static_cast<int32_t>(H264RateControlMethod::VariableBitrate_LatencyConstrained));
427
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_RATECONTROLMETHOD), false);
428
            if (obs_data_get_int(data, AMF_H264_BITRATE_TARGET) < 10000)
429
                obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 10000);
430
            obs_property_int_set_limits(obs_properties_get(props, AMF_H264_BITRATE_TARGET), 10000, 100000, 1);
431
-           //obs_data_set_int(data, AMF_H264_BITRATE_PEAK, VCECapabilities::GetInstance()->GetEncoderCaps(VCEEncoderType_AVC)->maxBitrate / (obs_data_get_bool(data, AMF_H264_UNLOCK_PROPERTIES) ? 1 : 1000));
432
-           obs_data_set_int(data, AMF_H264_QP_MINIMUM, 0);
433
+           obs_data_default_single(props, data, AMF_H264_QP_MINIMUM);
434
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_MINIMUM), false);
435
-           obs_data_set_int(data, AMF_H264_QP_MAXIMUM, 51);
436
+           obs_data_default_single(props, data, AMF_H264_QP_MAXIMUM);
437
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_MAXIMUM), false);
438
-           /*obs_data_set_int(data, AMF_H264_QP_IFRAME, 0);
439
-           obs_data_set_int(data, AMF_H264_QP_PFRAME, 0);
440
-           obs_data_set_int(data, AMF_H264_QP_BFRAME, 0);*/
441
            obs_data_set_int(data, AMF_H264_BFRAME_DELTAQP, 0);
442
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_DELTAQP), false);
443
            obs_data_set_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP, 0);
444
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_REFERENCEDELTAQP), false);
445
-           //obs_data_set_int(data, AMF_H264_VBVBUFFER, 0);
446
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER), false);
447
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_STRICTNESS, 0);
448
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_STRICTNESS), false);
449
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_FULLNESS, 0);
450
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_FULLNESS), false);
451
-           //obs_data_set_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE, 0);
452
            obs_data_set_int(data, AMF_H264_FILLERDATA, 0);
453
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_FILLERDATA), false);
454
-           //obs_data_set_int(data, AMF_H264_FRAMESKIPPING, 0);
455
-           //obs_data_set_int(data, AMF_H264_ENFORCEHRDCOMPATIBILITY, 0);
456
 
457
            // Frame Control Properties
458
            obs_data_set_double(data, AMF_H264_KEYFRAME_INTERVAL, 1);
459
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_KEYFRAME_INTERVAL), false);
460
-           //obs_data_set_int(data, AMF_H264_IDR_PERIOD, 60);
461
-           //obs_data_set_int(data, AMF_H264_HEADER_INSERTION_SPACING, 0);
462
-           //obs_data_set_int(data, AMF_H264_BFrame_PATTERN, obs_data_get_default_int(data, AMF_H264_BFrame_PATTERN));
463
-           //obs_data_set_int(data, AMF_H264_BFrame_REFERENCE, obs_data_get_default_int(data, AMF_H264_BFrame_REFERENCE));
464
-           //obs_data_set_int(data, AMF_H264_SLICESPERFRAME, 0);
465
-           //obs_data_set_int(data, AMF_H264_INTRAREFRESHNUMMBSPERSLOT, 0);
466
 
467
            // Miscellaneous Properties
468
-           //obs_data_set_int(data, AMF_H264_QUALITY_PRESET, VCEQualityPreset_Quality);
469
-           obs_data_set_int(data, AMF_H264_SCANTYPE, VCEScanType_Progressive);
470
+           obs_data_set_int(data, AMF_H264_SCANTYPE, static_cast<int32_t>(H264ScanType::Progressive));
471
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_SCANTYPE), false);
472
            obs_data_set_int(data, AMF_H264_MOTIONESTIMATION, 3);
473
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_MOTIONESTIMATION), false);
474
-           //obs_data_set_int(data, AMF_H264_CABAC, 0);
475
            break;
476
            #pragma endregion Recording
477
-       case HighQuality:
478
+       case Presets::HighQuality:
479
            #pragma region High Quality
480
            // Static Properties
481
-           //obs_data_set_int(data, AMF_H264_USAGE, VCEUsage_Transcoding);
482
-           obs_data_set_int(data, AMF_H264_PROFILE, VCEProfile_High);
483
+           obs_data_set_int(data, AMF_H264_PROFILE, static_cast<int32_t>(H264Profile::High));
484
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILE), false);
485
-           obs_data_set_int(data, AMF_H264_PROFILELEVEL, VCEProfileLevel_Automatic);
486
+           obs_data_set_int(data, AMF_H264_PROFILELEVEL, static_cast<int32_t>(H264ProfileLevel::Automatic));
487
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILELEVEL), false);
488
-           //obs_data_set_int(data, AMF_H264_MAXIMUMLTRFRAMES, obs_data_get_default_int(data, AMF_H264_MAXIMUMLTRFRAMES));
489
 
490
            // Rate Control Properties
491
-           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, VCERateControlMethod_ConstantQP);
492
+           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, static_cast<int32_t>(H264RateControlMethod::ConstantQP));
493
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_RATECONTROLMETHOD), false);
494
-           //obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 35000 * (obs_data_get_bool(data, AMF_H264_UNLOCK_PROPERTIES) ? 1000 : 1));
495
-           //obs_data_set_int(data, AMF_H264_BITRATE_PEAK, VCECapabilities::GetInstance()->GetEncoderCaps(VCEEncoderType_AVC)->maxBitrate / (obs_data_get_bool(data, AMF_H264_UNLOCK_PROPERTIES) ? 1 : 1000));
496
-           /*obs_data_set_int(data, AMF_H264_QP_MINIMUM, 0);
497
-           obs_data_set_int(data, AMF_H264_QP_MAXIMUM, 51);*/
498
            obs_data_set_int(data, AMF_H264_QP_IFRAME, 26);
499
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_IFRAME), false);
500
            obs_data_set_int(data, AMF_H264_QP_PFRAME, 24);
501
@@ -742,53 +736,29 @@
502
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_DELTAQP), false);
503
            obs_data_set_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP, -2);
504
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_REFERENCEDELTAQP), false);
505
-           //obs_data_set_int(data, AMF_H264_VBVBUFFER, 0);
506
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER), false);
507
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_STRICTNESS, 0);
508
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_STRICTNESS), false);
509
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_FULLNESS, 0);
510
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_FULLNESS), false);
511
-           //obs_data_set_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE, 0);
512
-           //obs_data_set_int(data, AMF_H264_FILLERDATA, 0);
513
-           //obs_data_set_int(data, AMF_H264_FRAMESKIPPING, 0);
514
-           //obs_data_set_int(data, AMF_H264_ENFORCEHRDCOMPATIBILITY, 0);
515
 
516
            // Frame Control Properties
517
            obs_data_set_double(data, AMF_H264_KEYFRAME_INTERVAL, 1);
518
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_KEYFRAME_INTERVAL), false);
519
-           //obs_data_set_int(data, AMF_H264_IDR_PERIOD, 60);
520
-           //obs_data_set_int(data, AMF_H264_HEADER_INSERTION_SPACING, 0);
521
-           //obs_data_set_int(data, AMF_H264_BFrame_PATTERN, obs_data_get_default_int(data, AMF_H264_BFrame_PATTERN));
522
-           //obs_data_set_int(data, AMF_H264_BFrame_REFERENCE, obs_data_get_default_int(data, AMF_H264_BFrame_REFERENCE));
523
-           //obs_data_set_int(data, AMF_H264_SLICESPERFRAME, 0);
524
-           //obs_data_set_int(data, AMF_H264_INTRAREFRESHNUMMBSPERSLOT, 0);
525
 
526
            // Miscellaneous Properties
527
-           //obs_data_set_int(data, AMF_H264_QUALITY_PRESET, VCEQualityPreset_Quality);
528
-           obs_data_set_int(data, AMF_H264_SCANTYPE, VCEScanType_Progressive);
529
+           obs_data_set_int(data, AMF_H264_SCANTYPE, static_cast<int32_t>(H264ScanType::Progressive));
530
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_SCANTYPE), false);
531
            obs_data_set_int(data, AMF_H264_MOTIONESTIMATION, 3);
532
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_MOTIONESTIMATION), false);
533
-           //obs_data_set_int(data, AMF_H264_CABAC, 0);
534
            break;
535
            #pragma endregion High Quality
536
-       case Indistinguishable:
537
+       case Presets::Indistinguishable:
538
            #pragma region Indistinguishable
539
            // Static Properties
540
-           //obs_data_set_int(data, AMF_H264_USAGE, VCEUsage_Transcoding);
541
-           obs_data_set_int(data, AMF_H264_PROFILE, VCEProfile_High);
542
+           obs_data_set_int(data, AMF_H264_PROFILE, static_cast<int32_t>(H264Profile::High));
543
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILE), false);
544
-           obs_data_set_int(data, AMF_H264_PROFILELEVEL, VCEProfileLevel_Automatic);
545
+           obs_data_set_int(data, AMF_H264_PROFILELEVEL, static_cast<int32_t>(H264ProfileLevel::Automatic));
546
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILELEVEL), false);
547
-           //obs_data_set_int(data, AMF_H264_MAXIMUMLTRFRAMES, obs_data_get_default_int(data, AMF_H264_MAXIMUMLTRFRAMES));
548
 
549
            // Rate Control Properties
550
-           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, VCERateControlMethod_ConstantQP);
551
+           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, static_cast<int32_t>(H264RateControlMethod::ConstantQP));
552
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_RATECONTROLMETHOD), false);
553
-           //obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 35000 * (obs_data_get_bool(data, AMF_H264_UNLOCK_PROPERTIES) ? 1000 : 1));
554
-           //obs_data_set_int(data, AMF_H264_BITRATE_PEAK, VCECapabilities::GetInstance()->GetEncoderCaps(VCEEncoderType_AVC)->maxBitrate / (obs_data_get_bool(data, AMF_H264_UNLOCK_PROPERTIES) ? 1 : 1000));
555
-           /*obs_data_set_int(data, AMF_H264_QP_MINIMUM, 0);
556
-           obs_data_set_int(data, AMF_H264_QP_MAXIMUM, 51);*/
557
            obs_data_set_int(data, AMF_H264_QP_IFRAME, 21);
558
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_IFRAME), false);
559
            obs_data_set_int(data, AMF_H264_QP_PFRAME, 19);
560
@@ -799,53 +769,29 @@
561
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_DELTAQP), false);
562
            obs_data_set_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP, -2);
563
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_REFERENCEDELTAQP), false);
564
-           //obs_data_set_int(data, AMF_H264_VBVBUFFER, 0);
565
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER), false);
566
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_STRICTNESS, 0);
567
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_STRICTNESS), false);
568
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_FULLNESS, 0);
569
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_FULLNESS), false);
570
-           //obs_data_set_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE, 0);
571
-           //obs_data_set_int(data, AMF_H264_FILLERDATA, 0);
572
-           //obs_data_set_int(data, AMF_H264_FRAMESKIPPING, 0);
573
-           //obs_data_set_int(data, AMF_H264_ENFORCEHRDCOMPATIBILITY, 0);
574
 
575
            // Frame Control Properties
576
            obs_data_set_double(data, AMF_H264_KEYFRAME_INTERVAL, 1);
577
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_KEYFRAME_INTERVAL), false);
578
-           //obs_data_set_int(data, AMF_H264_IDR_PERIOD, 60);
579
-           //obs_data_set_int(data, AMF_H264_HEADER_INSERTION_SPACING, 0);
580
-           //obs_data_set_int(data, AMF_H264_BFRAME_PATTERN, obs_data_get_default_int(data, AMF_H264_BFRAME_PATTERN));
581
-           //obs_data_set_int(data, AMF_H264_BFRAME_REFERENCE, obs_data_get_default_int(data, AMF_H264_BFRAME_REFERENCE));
582
-           //obs_data_set_int(data, AMF_H264_SLICESPERFRAME, 0);
583
-           //obs_data_set_int(data, AMF_H264_INTRAREFRESHNUMMBSPERSLOT, 0);
584
 
585
            // Miscellaneous Properties
586
-           //obs_data_set_int(data, AMF_H264_QUALITY_PRESET, VCEQualityPreset_Quality);
587
-           obs_data_set_int(data, AMF_H264_SCANTYPE, VCEScanType_Progressive);
588
+           obs_data_set_int(data, AMF_H264_SCANTYPE, static_cast<int32_t>(H264ScanType::Progressive));
589
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_SCANTYPE), false);
590
            obs_data_set_int(data, AMF_H264_MOTIONESTIMATION, 3);
591
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_MOTIONESTIMATION), false);
592
-           //obs_data_set_int(data, AMF_H264_CABAC, 0);
593
            break;
594
            #pragma endregion Indistinguishable
595
-       case Lossless:
596
+       case Presets::Lossless:
597
            #pragma region Lossless
598
            // Static Properties
599
-           //obs_data_set_int(data, AMF_H264_USAGE, VCEUsage_Transcoding);
600
-           obs_data_set_int(data, AMF_H264_PROFILE, VCEProfile_High);
601
+           obs_data_set_int(data, AMF_H264_PROFILE, static_cast<int32_t>(H264Profile::High));
602
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILE), false);
603
-           obs_data_set_int(data, AMF_H264_PROFILELEVEL, VCEProfileLevel_Automatic);
604
+           obs_data_set_int(data, AMF_H264_PROFILELEVEL, static_cast<int32_t>(H264ProfileLevel::Automatic));
605
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILELEVEL), false);
606
-           //obs_data_set_int(data, AMF_H264_MAXIMUMLTRFRAMES, 0);
607
 
608
            // Rate Control Properties
609
-           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, VCERateControlMethod_ConstantQP);
610
+           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, static_cast<int32_t>(H264RateControlMethod::ConstantQP));
611
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_RATECONTROLMETHOD), false);
612
-           //obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 35000 * (obs_data_get_bool(data, AMF_H264_UNLOCK_PROPERTIES) ? 1000 : 1));
613
-           //obs_data_set_int(data, AMF_H264_BITRATE_PEAK, VCECapabilities::GetInstance()->GetEncoderCaps(VCEEncoderType_AVC)->maxBitrate / (obs_data_get_bool(data, AMF_H264_UNLOCK_PROPERTIES) ? 1 : 1000));
614
-           /*obs_data_set_int(data, AMF_H264_QP_MINIMUM, 0);
615
-           obs_data_set_int(data, AMF_H264_QP_MAXIMUM, 51);*/
616
            obs_data_set_int(data, AMF_H264_QP_IFRAME, 0);
617
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_IFRAME), false);
618
            obs_data_set_int(data, AMF_H264_QP_PFRAME, 0);
619
@@ -856,160 +802,88 @@
620
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_DELTAQP), false);
621
            obs_data_set_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP, 0);
622
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_REFERENCEDELTAQP), false);
623
-           //obs_data_set_int(data, AMF_H264_VBVBUFFER, 0);
624
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER), false);
625
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_STRICTNESS, 0);
626
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_STRICTNESS), false);
627
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_FULLNESS, 0);
628
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_FULLNESS), false);
629
-           //obs_data_set_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE, 0);
630
-           //obs_data_set_int(data, AMF_H264_FILLERDATA, 0);
631
-           //obs_data_set_int(data, AMF_H264_FRAMESKIPPING, 0);
632
-           //obs_data_set_int(data, AMF_H264_ENFORCEHRDCOMPATIBILITY, 0);
633
 
634
            // Frame Control Properties
635
            obs_data_set_double(data, AMF_H264_KEYFRAME_INTERVAL, 1);
636
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_KEYFRAME_INTERVAL), false);
637
-           obs_data_set_int(data, AMF_H264_IDR_PERIOD, 30);
638
-           obs_property_set_enabled(obs_properties_get(props, AMF_H264_IDR_PERIOD), false);
639
-           //obs_data_set_int(data, AMF_H264_HEADER_INSERTION_SPACING, 0);
640
            obs_data_set_int(data, AMF_H264_BFRAME_PATTERN, 0);
641
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_PATTERN), false);
642
            obs_data_set_int(data, AMF_H264_BFRAME_REFERENCE, 0);
643
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_REFERENCE), false);
644
-           //obs_data_set_int(data, AMF_H264_SLICESPERFRAME, 0);
645
-           //obs_data_set_int(data, AMF_H264_INTRAREFRESHNUMMBSPERSLOT, 0);
646
 
647
            // Miscellaneous Properties
648
-           //obs_data_set_int(data, AMF_H264_QUALITY_PRESET, VCEQualityPreset_Quality);
649
-           obs_data_set_int(data, AMF_H264_SCANTYPE, VCEScanType_Progressive);
650
+           obs_data_set_int(data, AMF_H264_SCANTYPE, static_cast<int32_t>(H264ScanType::Progressive));
651
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_SCANTYPE), false);
652
            obs_data_set_int(data, AMF_H264_MOTIONESTIMATION, 3);
653
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_MOTIONESTIMATION), false);
654
-           //obs_data_set_int(data, AMF_H264_CABAC, 0);
655
            break;
656
            #pragma endregion Lossless
657
-       case Twitch:
658
+       case Presets::Twitch:
659
            #pragma region Twitch
660
            // Static Properties
661
-           obs_data_set_int(data, AMF_H264_USAGE, VCEUsage_Transcoding);
662
+           obs_data_set_int(data, AMF_H264_USAGE, static_cast<int32_t>(H264Usage::Transcoding));
663
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_USAGE), false);
664
-           obs_data_set_int(data, AMF_H264_PROFILE, VCEProfile_Main);
665
+           obs_data_set_int(data, AMF_H264_PROFILE, static_cast<int32_t>(H264Profile::Main));
666
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILE), false);
667
-           obs_data_set_int(data, AMF_H264_PROFILELEVEL, VCEProfileLevel_Automatic);
668
+           obs_data_set_int(data, AMF_H264_PROFILELEVEL, static_cast<int32_t>(H264ProfileLevel::Automatic));
669
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILELEVEL), false);
670
-           //obs_data_set_int(data, AMF_H264_MAXIMUMLTRFRAMES, obs_data_get);
671
 
672
            // Rate Control Properties
673
-           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, VCERateControlMethod_ConstantBitrate);
674
+           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, static_cast<int32_t>(H264RateControlMethod::ConstantBitrate));
675
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_RATECONTROLMETHOD), false);
676
-           if (obs_data_get_int(data, AMF_H264_BITRATE_TARGET) < 1000)
677
-               obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 1000);
678
-           if (obs_data_get_int(data, AMF_H264_BITRATE_TARGET) > 4000)
679
-               obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 4000);
680
-           obs_property_int_set_limits(obs_properties_get(props, AMF_H264_BITRATE_TARGET), 1000, 4000, 1);
681
-           //obs_data_set_int(data, AMF_H264_BITRATE_PEAK, VCECapabilities::GetInstance()->GetEncoderCaps(VCEEncoderType_AVC)->maxBitrate / (obs_data_get_bool(data, AMF_H264_UNLOCK_PROPERTIES) ? 1 : 1000));
682
-           obs_data_set_int(data, AMF_H264_QP_MINIMUM, 0);
683
+           if (obs_data_get_int(data, AMF_H264_BITRATE_TARGET) < 500)
684
+               obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 500);
685
+           obs_property_int_set_limits(obs_properties_get(props, AMF_H264_BITRATE_TARGET), 500, 100000, 1);
686
+           obs_data_default_single(props, data, AMF_H264_QP_MINIMUM);
687
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_MINIMUM), false);
688
-           obs_data_set_int(data, AMF_H264_QP_MAXIMUM, 51);
689
+           obs_data_default_single(props, data, AMF_H264_QP_MAXIMUM);
690
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_MAXIMUM), false);
691
-           /*obs_data_set_int(data, AMF_H264_QP_IFRAME, 0);
692
-           obs_data_set_int(data, AMF_H264_QP_PFRAME, 0);
693
-           obs_data_set_int(data, AMF_H264_QP_BFRAME, 0);*/
694
-           obs_data_set_int(data, AMF_H264_BFRAME_DELTAQP, 0);
695
-           obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_DELTAQP), false);
696
-           obs_data_set_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP, 0);
697
-           obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_REFERENCEDELTAQP), false);
698
-           //obs_data_set_int(data, AMF_H264_VBVBUFFER, 0);
699
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER), false);
700
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_STRICTNESS, 80);
701
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_STRICTNESS), false);
702
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_FULLNESS, 100);
703
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_FULLNESS), false);
704
-           //obs_data_set_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE, 0);
705
            obs_data_set_int(data, AMF_H264_FILLERDATA, 1);
706
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_FILLERDATA), false);
707
-           //obs_data_set_int(data, AMF_H264_FRAMESKIPPING, 0);
708
-           //obs_data_set_int(data, AMF_H264_ENFORCEHRDCOMPATIBILITY, 0);
709
 
710
            // Frame Control Properties
711
            obs_data_set_double(data, AMF_H264_KEYFRAME_INTERVAL, 2);
712
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_KEYFRAME_INTERVAL), false);
713
-           //obs_data_set_int(data, AMF_H264_IDR_PERIOD, 120);
714
-           //obs_data_set_int(data, AMF_H264_HEADER_INSERTION_SPACING, 0);
715
-           //obs_data_set_int(data, AMF_H264_BFRAME_PATTERN, 0);
716
-           //obs_data_set_int(data, AMF_H264_BFRAME_REFERENCE, 0);
717
-           //obs_data_set_int(data, AMF_H264_SLICESPERFRAME, 0);
718
-           //obs_data_set_int(data, AMF_H264_INTRAREFRESHNUMMBSPERSLOT, 0);
719
 
720
            // Miscellaneous Properties
721
-           //obs_data_set_int(data, AMF_H264_QUALITY_PRESET, VCEQualityPreset_Quality);
722
-           obs_data_set_int(data, AMF_H264_SCANTYPE, VCEScanType_Progressive);
723
+           obs_data_set_int(data, AMF_H264_SCANTYPE, static_cast<int32_t>(H264ScanType::Progressive));
724
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_SCANTYPE), false);
725
            obs_data_set_int(data, AMF_H264_MOTIONESTIMATION, 3);
726
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_MOTIONESTIMATION), false);
727
-           //obs_data_set_int(data, AMF_H264_CABAC, 0);
728
            break;
729
            #pragma endregion Twitch
730
-       case YouTube:
731
+       case Presets::YouTube:
732
            #pragma region YouTube
733
            // Static Properties
734
-           obs_data_set_int(data, AMF_H264_USAGE, VCEUsage_Transcoding);
735
+           obs_data_set_int(data, AMF_H264_USAGE, static_cast<int32_t>(H264Usage::Transcoding));
736
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_USAGE), false);
737
-           obs_data_set_int(data, AMF_H264_PROFILE, VCEProfile_Main);
738
+           obs_data_set_int(data, AMF_H264_PROFILE, static_cast<int32_t>(H264Profile::Main));
739
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILE), false);
740
-           obs_data_set_int(data, AMF_H264_PROFILELEVEL, VCEProfileLevel_Automatic);
741
+           obs_data_set_int(data, AMF_H264_PROFILELEVEL, static_cast<int32_t>(H264ProfileLevel::Automatic));
742
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_PROFILELEVEL), false);
743
-           //obs_data_set_int(data, AMF_H264_MAXIMUMLTRFRAMES, obs_data_get);
744
 
745
            // Rate Control Properties
746
-           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, VCERateControlMethod_ConstantBitrate);
747
+           obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, static_cast<int32_t>(H264RateControlMethod::ConstantBitrate));
748
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_RATECONTROLMETHOD), false);
749
-           if (obs_data_get_int(data, AMF_H264_BITRATE_TARGET) < 1000)
750
-               obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 1000);
751
-           if (obs_data_get_int(data, AMF_H264_BITRATE_PEAK) > 25000)
752
-               obs_data_set_int(data, AMF_H264_BITRATE_PEAK, 25000);
753
-           obs_property_int_set_limits(obs_properties_get(props, AMF_H264_BITRATE_TARGET), 1000, 25000, 1);
754
-           obs_data_set_int(data, AMF_H264_QP_MINIMUM, 0);
755
+           if (obs_data_get_int(data, AMF_H264_BITRATE_TARGET) < 500)
756
+               obs_data_set_int(data, AMF_H264_BITRATE_TARGET, 500);
757
+           obs_property_int_set_limits(obs_properties_get(props, AMF_H264_BITRATE_TARGET), 500, 100000, 1);
758
+           obs_data_default_single(props, data, AMF_H264_QP_MINIMUM);
759
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_MINIMUM), false);
760
-           obs_data_set_int(data, AMF_H264_QP_MAXIMUM, 51);
761
+           obs_data_default_single(props, data, AMF_H264_QP_MAXIMUM);
762
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_QP_MAXIMUM), false);
763
-           /*obs_data_set_int(data, AMF_H264_QP_IFRAME, 0);
764
-           obs_data_set_int(data, AMF_H264_QP_PFRAME, 0);
765
-           obs_data_set_int(data, AMF_H264_QP_BFRAME, 0);*/
766
-           obs_data_set_int(data, AMF_H264_BFRAME_DELTAQP, 0);
767
-           obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_DELTAQP), false);
768
-           obs_data_set_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP, 0);
769
-           obs_property_set_enabled(obs_properties_get(props, AMF_H264_BFRAME_REFERENCEDELTAQP), false);
770
-           //obs_data_set_int(data, AMF_H264_VBVBUFFER, 0);
771
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER), false);
772
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_STRICTNESS, 80);
773
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_STRICTNESS), false);
774
-           //obs_data_set_double(data, AMF_H264_VBVBUFFER_FULLNESS, 100);
775
-           //obs_property_set_enabled(obs_properties_get(props, AMF_H264_VBVBUFFER_FULLNESS), false);
776
-           //obs_data_set_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE, 0);
777
            obs_data_set_int(data, AMF_H264_FILLERDATA, 1);
778
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_FILLERDATA), false);
779
-           //obs_data_set_int(data, AMF_H264_FRAMESKIPPING, 0);
780
-           //obs_data_set_int(data, AMF_H264_ENFORCEHRDCOMPATIBILITY, 0);
781
 
782
            // Frame Control Properties
783
            obs_data_set_double(data, AMF_H264_KEYFRAME_INTERVAL, 2);
784
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_KEYFRAME_INTERVAL), false);
785
-           //obs_data_set_int(data, AMF_H264_IDR_PERIOD, 120);
786
-           //obs_data_set_int(data, AMF_H264_HEADER_INSERTION_SPACING, 0);
787
-           //obs_data_set_int(data, AMF_H264_BFRAME_PATTERN, 0);
788
-           //obs_data_set_int(data, AMF_H264_BFRAME_REFERENCE, 0);
789
-           //obs_data_set_int(data, AMF_H264_SLICESPERFRAME, 0);
790
-           //obs_data_set_int(data, AMF_H264_INTRAREFRESHNUMMBSPERSLOT, 0);
791
 
792
            // Miscellaneous Properties
793
-           //obs_data_set_int(data, AMF_H264_QUALITY_PRESET, VCEQualityPreset_Quality);
794
-           obs_data_set_int(data, AMF_H264_SCANTYPE, VCEScanType_Progressive);
795
+           obs_data_set_int(data, AMF_H264_SCANTYPE, static_cast<int32_t>(H264ScanType::Progressive));
796
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_SCANTYPE), false);
797
            obs_data_set_int(data, AMF_H264_MOTIONESTIMATION, 3);
798
            obs_property_set_enabled(obs_properties_get(props, AMF_H264_MOTIONESTIMATION), false);
799
-           //obs_data_set_int(data, AMF_H264_CABAC, 0);
800
            break;
801
            #pragma endregion YouTube
802
    }
803
@@ -1023,7 +897,7 @@
804
        //fill_api_list(p);
805
 
806
        obs_data_set_string(data, AMF_H264_VIDEOAPI,
807
-           obs_property_list_item_string(p, 0));
808
+                           obs_property_list_item_string(p, 0));
809
        curVideoAPI = obs_data_get_string(data, AMF_H264_VIDEOAPI);
810
    }
811
    if ((strcmp(lastVideoAPI, curVideoAPI) != 0)
812
@@ -1033,7 +907,7 @@
813
 
814
        // Reset Video Adapter to first in list.
815
        obs_data_set_int(data, AMF_H264_VIDEOADAPTER,
816
-           obs_property_list_item_int(obs_properties_get(props, AMF_H264_VIDEOADAPTER), 0));
817
+                        obs_property_list_item_int(obs_properties_get(props, AMF_H264_VIDEOADAPTER), 0));
818
    }
819
    #pragma endregion Video API
820
 
821
@@ -1044,7 +918,7 @@
822
    {
823
        auto api = Plugin::API::Base::GetAPIByName(obs_data_get_string(data, AMF_H264_VIDEOAPI));
824
        auto adapter = api->GetAdapterById(curAdapterId & UINT_MAX, (curAdapterId >> 32) & UINT_MAX);
825
-       devCaps = Plugin::AMD::VCECapabilities::GetInstance()->GetAdapterCapabilities(api, adapter, VCEEncoderType_AVC);
826
+       devCaps = Plugin::AMD::VCECapabilities::GetInstance()->GetAdapterCapabilities(api, adapter, H264EncoderType::AVC);
827
    }
828
    if (lastAdapterId != curAdapterId) {
829
        obs_data_set_int(data, "last" vstr(AMF_H264_VIDEOADAPTER), curAdapterId);
830
@@ -1054,13 +928,13 @@
831
        obs_property_list_clear(p);
832
        switch (devCaps.maxProfile) {
833
            case 100:
834
-               obs_property_list_add_int(p, "High", VCEProfile_High);
835
-               obs_property_list_add_int(p, "Constrained High", VCEProfile_ConstrainedHigh);
836
+               obs_property_list_add_int(p, "High", (int32_t)H264Profile::High);
837
+               obs_property_list_add_int(p, "Constrained High", (int32_t)H264Profile::ConstrainedHigh);
838
            case 77:
839
-               obs_property_list_add_int(p, "Main", VCEProfile_Main);
840
+               obs_property_list_add_int(p, "Main", (int32_t)H264Profile::Main);
841
            case 66:
842
-               obs_property_list_add_int(p, "Baseline", VCEProfile_Baseline);
843
-               obs_property_list_add_int(p, "Constrained Baseline", VCEProfile_ConstrainedBaseline);
844
+               obs_property_list_add_int(p, "Baseline", (int32_t)H264Profile::Baseline);
845
+               obs_property_list_add_int(p, "Constrained Baseline", (int32_t)H264Profile::ConstrainedBaseline);
846
                break;
847
        }
848
        #pragma endregion Profile
849
@@ -1068,72 +942,66 @@
850
        #pragma region Profile Level
851
        p = obs_properties_get(props, AMF_H264_PROFILELEVEL);
852
        obs_property_list_clear(p);
853
-       obs_property_list_add_int(p, TEXT_T(AMF_UTIL_AUTOMATIC), VCEProfileLevel_Automatic);
854
+       obs_property_list_add_int(p, TEXT_T(AMF_UTIL_AUTOMATIC), (int32_t)H264ProfileLevel::Automatic);
855
        switch (devCaps.maxProfileLevel) {
856
-           case 62:
857
-               obs_property_list_add_int(p, "6.2", VCEProfileLevel_62);
858
-           case 61:
859
-               obs_property_list_add_int(p, "6.1", VCEProfileLevel_61);
860
-           case 60:
861
-               obs_property_list_add_int(p, "6.0", VCEProfileLevel_60);
862
            case 52:
863
-               obs_property_list_add_int(p, "5.2", VCEProfileLevel_52);
864
+               obs_property_list_add_int(p, "5.2", (int32_t)H264ProfileLevel::L52);
865
            case 51:
866
-               obs_property_list_add_int(p, "5.1", VCEProfileLevel_51);
867
+               obs_property_list_add_int(p, "5.1", (int32_t)H264ProfileLevel::L51);
868
            case 50:
869
-               obs_property_list_add_int(p, "5.0", VCEProfileLevel_50);
870
+               obs_property_list_add_int(p, "5.0", (int32_t)H264ProfileLevel::L50);
871
            case 42: // Some VCE 2.0 Cards.
872
-               obs_property_list_add_int(p, "4.2", VCEProfileLevel_42);
873
+               obs_property_list_add_int(p, "4.2", (int32_t)H264ProfileLevel::L42);
874
            case 41: // Some APUs and VCE 1.0 Cards.
875
-               obs_property_list_add_int(p, "4.1", VCEProfileLevel_41);
876
+               obs_property_list_add_int(p, "4.1", (int32_t)H264ProfileLevel::L41);
877
            case 40: // These should in theory be supported by all VCE 1.0 devices and APUs.
878
-               obs_property_list_add_int(p, "4.0", VCEProfileLevel_40);
879
+               obs_property_list_add_int(p, "4.0", (int32_t)H264ProfileLevel::L40);
880
            case 32:
881
-               obs_property_list_add_int(p, "3.2", VCEProfileLevel_32);
882
+               obs_property_list_add_int(p, "3.2", (int32_t)H264ProfileLevel::L32);
883
            case 31:
884
-               obs_property_list_add_int(p, "3.1", VCEProfileLevel_31);
885
+               obs_property_list_add_int(p, "3.1", (int32_t)H264ProfileLevel::L31);
886
            case 30:
887
-               obs_property_list_add_int(p, "3.0", VCEProfileLevel_30);
888
+               obs_property_list_add_int(p, "3.0", (int32_t)H264ProfileLevel::L30);
889
            case 22:
890
-               obs_property_list_add_int(p, "2.2", VCEProfileLevel_22);
891
+               obs_property_list_add_int(p, "2.2", (int32_t)H264ProfileLevel::L22);
892
            case 21:
893
-               obs_property_list_add_int(p, "2.1", VCEProfileLevel_21);
894
+               obs_property_list_add_int(p, "2.1", (int32_t)H264ProfileLevel::L21);
895
            case 20:
896
-               obs_property_list_add_int(p, "2.0", VCEProfileLevel_20);
897
+               obs_property_list_add_int(p, "2.0", (int32_t)H264ProfileLevel::L20);
898
            case 13:
899
-               obs_property_list_add_int(p, "1.3", VCEProfileLevel_13);
900
+               obs_property_list_add_int(p, "1.3", (int32_t)H264ProfileLevel::L13);
901
            case 12:
902
-               obs_property_list_add_int(p, "1.2", VCEProfileLevel_12);
903
+               obs_property_list_add_int(p, "1.2", (int32_t)H264ProfileLevel::L12);
904
            case 11:
905
-               obs_property_list_add_int(p, "1.1", VCEProfileLevel_11);
906
+               obs_property_list_add_int(p, "1.1", (int32_t)H264ProfileLevel::L11);
907
            case 10:
908
            default:
909
-               obs_property_list_add_int(p, "1.0", VCEProfileLevel_10);
910
+               obs_property_list_add_int(p, "1.0", (int32_t)H264ProfileLevel::L10);
911
        }
912
        #pragma endregion Profile Level
913
 
914
        obs_property_int_set_limits(obs_properties_get(props, AMF_H264_BITRATE_TARGET),
915
-           10, devCaps.maxBitrate / 1000, 1);
916
+                                   10, devCaps.maxBitrate / 1000, 1);
917
        obs_property_int_set_limits(obs_properties_get(props, AMF_H264_BITRATE_PEAK),
918
-           10, devCaps.maxBitrate / 1000, 1);
919
+                                   10, devCaps.maxBitrate / 1000, 1);
920
        obs_property_int_set_limits(obs_properties_get(props, AMF_H264_VBVBUFFER_SIZE),
921
-           1, 100000, 1);
922
+                                   1, 100000, 1);
923
        obs_property_float_set_limits(obs_properties_get(props, AMF_H264_KEYFRAME_INTERVAL),
924
-           1.0 / 144.0, 30, 1.0 / 144.0);
925
+                                     1.0 / 144.0, 30, 1.0 / 144.0);
926
        obs_property_int_set_limits(obs_properties_get(props, AMF_H264_IDR_PERIOD),
927
-           1, 1000, 1);
928
+                                   1, 1000, 1);
929
 
930
-       // Experimental
931
+                               // Experimental
932
        obs_property_int_set_limits(obs_properties_get(props, AMF_H264_MAXIMUMREFERENCEFRAMES),
933
-           devCaps.minReferenceFrames, devCaps.maxReferenceFrames, 1);
934
+                                   devCaps.minReferenceFrames, devCaps.maxReferenceFrames, 1);
935
    }
936
    #pragma endregion Video Adapter
937
 
938
    #pragma region View Mode
939
-   uint32_t lastView = (uint32_t)obs_data_get_int(data, "last" vstr(AMF_H264_VIEW)),
940
-       curView = (uint32_t)obs_data_get_int(data, AMF_H264_VIEW);
941
+   ViewMode lastView = static_cast<ViewMode>(obs_data_get_int(data, "last" vstr(AMF_H264_VIEW))),
942
+       curView = static_cast<ViewMode>(obs_data_get_int(data, AMF_H264_VIEW));
943
    if (lastView != curView) {
944
-       obs_data_set_int(data, "last" vstr(AMF_H264_VIEW), curView);
945
+       obs_data_set_int(data, "last" vstr(AMF_H264_VIEW), static_cast<int32_t>(curView));
946
        result = true;
947
    }
948
 
949
@@ -1217,7 +1085,7 @@
950
    #pragma endregion Master
951
 
952
    #pragma region Special Logic
953
-   uint32_t ltrFrames = (uint32_t)obs_data_get_int(data, AMF_H264_MAXIMUMLTRFRAMES);
954
+   uint32_t ltrFrames = static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_MAXIMUMLTRFRAMES));
955
    bool usingLTRFrames = ltrFrames > 0;
956
 
957
    // Key-frame Interval
958
@@ -1264,26 +1132,26 @@
959
        vis_rcm_qp_b = false,
960
        vis_rcm_fillerdata = false;
961
 
962
-   VCERateControlMethod lastRCM = (VCERateControlMethod)obs_data_get_int(data, "last" vstr(AMF_H264_RATECONTROLMETHOD)),
963
-       curRCM = (VCERateControlMethod)obs_data_get_int(data, AMF_H264_RATECONTROLMETHOD);
964
+   H264RateControlMethod lastRCM = static_cast<H264RateControlMethod>(obs_data_get_int(data, "last" vstr(AMF_H264_RATECONTROLMETHOD))),
965
+       curRCM = static_cast<H264RateControlMethod>(obs_data_get_int(data, AMF_H264_RATECONTROLMETHOD));
966
    if (lastRCM != curRCM) {
967
-       obs_data_set_int(data, "last" vstr(AMF_H264_RATECONTROLMETHOD), curRCM);
968
+       obs_data_set_int(data, "last" vstr(AMF_H264_RATECONTROLMETHOD), static_cast<int32_t>(curRCM));
969
        result = true;
970
    }
971
    switch (curRCM) {
972
-       case VCERateControlMethod_ConstantBitrate:
973
+       case H264RateControlMethod::ConstantBitrate:
974
            vis_rcm_bitrate_target = true;
975
            vis_rcm_fillerdata = true;
976
            break;
977
-       case VCERateControlMethod_VariableBitrate_PeakConstrained:
978
+       case H264RateControlMethod::VariableBitrate_PeakConstrained:
979
            vis_rcm_bitrate_target = true;
980
            vis_rcm_bitrate_peak = true;
981
            break;
982
-       case VCERateControlMethod_VariableBitrate_LatencyConstrained:
983
+       case H264RateControlMethod::VariableBitrate_LatencyConstrained:
984
            vis_rcm_bitrate_target = true;
985
            vis_rcm_bitrate_peak = true;
986
            break;
987
-       case VCERateControlMethod_ConstantQP:
988
+       case H264RateControlMethod::ConstantQP:
989
            vis_rcm_qp = true;
990
            vis_rcm_qp_b = (!usingLTRFrames) && devCaps.supportsBFrames && usingBFrames;
991
            break;
992
@@ -1323,10 +1191,10 @@
993
    #pragma endregion Rate Control
994
 
995
    #pragma region VBV Buffer
996
-   uint32_t vbvBufferMode = (uint32_t)obs_data_get_int(data, AMF_H264_VBVBUFFER);
997
+   uint32_t vbvBufferMode = static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_VBVBUFFER));
998
    bool vbvBufferVisible = vis_advanced;
999
 
1000
-   uint32_t lastVBVBufferMode = (uint32_t)obs_data_get_int(data, "last" vstr(AMF_H264_VBVBUFFER));
1001
+   uint32_t lastVBVBufferMode = static_cast<uint32_t>(obs_data_get_int(data, "last" vstr(AMF_H264_VBVBUFFER)));
1002
    if (lastVBVBufferMode != vbvBufferMode) {
1003
        obs_data_set_int(data, "last" vstr(AMF_H264_VBVBUFFER), vbvBufferMode);
1004
        result = true;
1005
@@ -1359,27 +1227,43 @@
1006
 bool Plugin::Interface::H264Interface::update(void *data, obs_data_t *settings) {
1007
    try {
1008
        return static_cast<Plugin::Interface::H264Interface*>(data)->update(settings);
1009
+   } catch (std::exception e) {
1010
+       AMF_LOG_ERROR("%s", e.what());
1011
+   } catch (std::exception* e) {
1012
+       AMF_LOG_ERROR("%s", e->what());
1013
+       delete e;
1014
    } catch (...) {
1015
-       AMF_LOG_ERROR("Unable to update Encoder, see log for more information.");
1016
-       return false;
1017
+       AMF_LOG_ERROR("Unknown Exception.");
1018
    }
1019
+   return false;
1020
 }
1021
 
1022
 void Plugin::Interface::H264Interface::get_video_info(void *data, struct video_scale_info *info) {
1023
    try {
1024
        return static_cast<Plugin::Interface::H264Interface*>(data)->get_video_info(info);
1025
+   } catch (std::exception e) {
1026
+       AMF_LOG_ERROR("%s", e.what());
1027
+   } catch (std::exception* e) {
1028
+       AMF_LOG_ERROR("%s", e->what());
1029
+       delete e;
1030
    } catch (...) {
1031
-       AMF_LOG_ERROR("Unable to get video info, see log for more information.");
1032
+       AMF_LOG_ERROR("Unknown Exception.");
1033
+       return;
1034
    }
1035
 }
1036
 
1037
 bool Plugin::Interface::H264Interface::get_extra_data(void *data, uint8_t** extra_data, size_t* size) {
1038
    try {
1039
        return static_cast<Plugin::Interface::H264Interface*>(data)->get_extra_data(extra_data, size);
1040
+   } catch (std::exception e) {
1041
+       AMF_LOG_ERROR("%s", e.what());
1042
+   } catch (std::exception* e) {
1043
+       AMF_LOG_ERROR("%s", e->what());
1044
+       delete e;
1045
    } catch (...) {
1046
-       AMF_LOG_ERROR("Unable to get extra data, see log for more information.");
1047
-       return false;
1048
+       AMF_LOG_ERROR("Unknown Exception.");
1049
    }
1050
+   return false;
1051
 }
1052
 
1053
 //////////////////////////////////////////////////////////////////////////
1054
@@ -1396,55 +1280,57 @@
1055
    uint32_t m_cfgFPSnum = voi->fps_num;
1056
    uint32_t m_cfgFPSden = voi->fps_den;
1057
 
1058
+   obs_data_transfer_settings(data);
1059
+
1060
    //////////////////////////////////////////////////////////////////////////
1061
    /// Initialize Encoder
1062
    bool debug = obs_data_get_bool(data, AMF_H264_DEBUG);
1063
    Plugin::AMD::AMF::GetInstance()->EnableDebugTrace(debug);
1064
 
1065
-   VCEColorFormat surfFormat = VCEColorFormat_NV12;
1066
+   H264ColorFormat surfFormat = H264ColorFormat::NV12;
1067
    switch (voi->format) {
1068
        case VIDEO_FORMAT_NV12:
1069
-           surfFormat = VCEColorFormat_NV12;
1070
+           surfFormat = H264ColorFormat::NV12;
1071
            break;
1072
        case VIDEO_FORMAT_I420:
1073
-           surfFormat = VCEColorFormat_I420;
1074
+           surfFormat = H264ColorFormat::I420;
1075
            break;
1076
        case VIDEO_FORMAT_YUY2:
1077
-           surfFormat = VCEColorFormat_YUY2;
1078
+           surfFormat = H264ColorFormat::YUY2;
1079
            break;
1080
        case VIDEO_FORMAT_RGBA:
1081
-           surfFormat = VCEColorFormat_RGBA;
1082
+           surfFormat = H264ColorFormat::RGBA;
1083
            break;
1084
        case VIDEO_FORMAT_BGRA:
1085
-           surfFormat = VCEColorFormat_BGRA;
1086
+           surfFormat = H264ColorFormat::BGRA;
1087
            break;
1088
        case VIDEO_FORMAT_Y800:
1089
-           surfFormat = VCEColorFormat_GRAY;
1090
+           surfFormat = H264ColorFormat::GRAY;
1091
            break;
1092
    }
1093
-   m_VideoEncoder = new VCEEncoder(VCEEncoderType_AVC, obs_data_get_string(data, AMF_H264_VIDEOAPI),
1094
-       obs_data_get_int(data, AMF_H264_VIDEOADAPTER), !!obs_data_get_int(data, AMF_H264_OPENCL), surfFormat);
1095
+   m_VideoEncoder = new H264Encoder(H264EncoderType::AVC, obs_data_get_string(data, AMF_H264_VIDEOAPI),
1096
+                                    obs_data_get_int(data, AMF_H264_VIDEOADAPTER), !!obs_data_get_int(data, AMF_H264_OPENCL), surfFormat);
1097
 
1098
-   /// Static Properties
1099
-   m_VideoEncoder->SetUsage((VCEUsage)obs_data_get_int(data, AMF_H264_USAGE));
1100
-   m_VideoEncoder->SetQualityPreset((VCEQualityPreset)obs_data_get_int(data, AMF_H264_QUALITY_PRESET));
1101
+                                /// Static Properties
1102
+   m_VideoEncoder->SetUsage(static_cast<H264Usage>(obs_data_get_int(data, AMF_H264_USAGE)));
1103
+   m_VideoEncoder->SetQualityPreset(static_cast<H264QualityPreset>(obs_data_get_int(data, AMF_H264_QUALITY_PRESET)));
1104
 
1105
    /// Frame
1106
-   m_VideoEncoder->SetColorProfile(voi->colorspace == VIDEO_CS_709 ? VCEColorProfile_709 : VCEColorProfile_601);
1107
+   m_VideoEncoder->SetColorProfile(voi->colorspace == VIDEO_CS_709 ? H264ColorProfile::Rec709 : H264ColorProfile::Rec601);
1108
    try { m_VideoEncoder->SetFullRangeColorEnabled(voi->range == VIDEO_RANGE_FULL); } catch (...) {}
1109
    m_VideoEncoder->SetResolution(m_cfgWidth, m_cfgHeight);
1110
    m_VideoEncoder->SetFrameRate(m_cfgFPSnum, m_cfgFPSden);
1111
-   m_VideoEncoder->SetScanType((VCEScanType)obs_data_get_int(data, AMF_H264_SCANTYPE)); /// Progressive or Interlaced
1112
+   m_VideoEncoder->SetScanType(static_cast<H264ScanType>(obs_data_get_int(data, AMF_H264_SCANTYPE)));
1113
 
1114
    /// Profile & Level
1115
-   m_VideoEncoder->SetProfile((VCEProfile)obs_data_get_int(data, AMF_H264_PROFILE));
1116
-   m_VideoEncoder->SetProfileLevel((VCEProfileLevel)obs_data_get_int(data, AMF_H264_PROFILELEVEL));
1117
+   m_VideoEncoder->SetProfile(static_cast<H264Profile>(obs_data_get_int(data, AMF_H264_PROFILE)));
1118
+   m_VideoEncoder->SetProfileLevel(static_cast<H264ProfileLevel>(obs_data_get_int(data, AMF_H264_PROFILELEVEL)));
1119
 
1120
    #pragma region Experimental
1121
    /// Long Term Reference
1122
-   if ((uint32_t)obs_data_get_int(data, AMF_H264_MAXIMUMLTRFRAMES) > 0)
1123
-       m_VideoEncoder->SetBFramePattern(VCEBFramePattern_None);
1124
-   m_VideoEncoder->SetMaximumLongTermReferenceFrames((uint32_t)obs_data_get_int(data, AMF_H264_MAXIMUMLTRFRAMES));
1125
+   if (static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_MAXIMUMLTRFRAMES) > 0))
1126
+       m_VideoEncoder->SetBFramePattern(H264BFramePattern::None);
1127
+   m_VideoEncoder->SetMaximumLongTermReferenceFrames(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_MAXIMUMLTRFRAMES)));
1128
 
1129
    #pragma endregion Experimental
1130
 
1131
@@ -1455,31 +1341,31 @@
1132
        const char* p_str = obs_data_get_string(data, "profile");
1133
        if (strcmp(p_str, "") != 0) {
1134
            if (strcmp(p_str, "constrained_baseline")) {
1135
-               m_VideoEncoder->SetProfile(VCEProfile_ConstrainedBaseline);
1136
+               m_VideoEncoder->SetProfile(H264Profile::ConstrainedBaseline);
1137
            } else if (strcmp(p_str, "baseline")) {
1138
-               m_VideoEncoder->SetProfile(VCEProfile_Baseline);
1139
+               m_VideoEncoder->SetProfile(H264Profile::Baseline);
1140
            } else if (strcmp(p_str, "main")) {
1141
-               m_VideoEncoder->SetProfile(VCEProfile_Main);
1142
+               m_VideoEncoder->SetProfile(H264Profile::Main);
1143
            } else if (strcmp(p_str, "constrained_high")) {
1144
-               m_VideoEncoder->SetProfile(VCEProfile_ConstrainedHigh);
1145
+               m_VideoEncoder->SetProfile(H264Profile::ConstrainedHigh);
1146
            } else if (strcmp(p_str, "high")) {
1147
-               m_VideoEncoder->SetProfile(VCEProfile_High);
1148
+               m_VideoEncoder->SetProfile(H264Profile::High);
1149
            }
1150
        } else {
1151
            switch (m_VideoEncoder->GetProfile()) {
1152
-               case VCEProfile_ConstrainedBaseline:
1153
+               case H264Profile::ConstrainedBaseline:
1154
                    obs_data_set_string(data, "profile", "constrained_baseline");
1155
                    break;
1156
-               case VCEProfile_Baseline:
1157
+               case H264Profile::Baseline:
1158
                    obs_data_set_string(data, "profile", "baseline");
1159
                    break;
1160
-               case VCEProfile_Main:
1161
+               case H264Profile::Main:
1162
                    obs_data_set_string(data, "profile", "main");
1163
                    break;
1164
-               case VCEProfile_ConstrainedHigh:
1165
+               case H264Profile::ConstrainedHigh:
1166
                    obs_data_set_string(data, "profile", "constrained_high");
1167
                    break;
1168
-               case VCEProfile_High:
1169
+               case H264Profile::High:
1170
                    obs_data_set_string(data, "profile", "high");
1171
                    break;
1172
            }
1173
@@ -1489,22 +1375,22 @@
1174
        const char* preset = obs_data_get_string(data, "preset");
1175
        if (strcmp(preset, "") != 0) {
1176
            if (strcmp(preset, "speed") == 0) {
1177
-               m_VideoEncoder->SetQualityPreset(VCEQualityPreset_Speed);
1178
+               m_VideoEncoder->SetQualityPreset(H264QualityPreset::Speed);
1179
            } else if (strcmp(preset, "balanced") == 0) {
1180
-               m_VideoEncoder->SetQualityPreset(VCEQualityPreset_Balanced);
1181
+               m_VideoEncoder->SetQualityPreset(H264QualityPreset::Balanced);
1182
            } else if (strcmp(preset, "quality") == 0) {
1183
-               m_VideoEncoder->SetQualityPreset(VCEQualityPreset_Quality);
1184
+               m_VideoEncoder->SetQualityPreset(H264QualityPreset::Quality);
1185
            }
1186
-           obs_data_set_int(data, AMF_H264_QUALITY_PRESET, m_VideoEncoder->GetQualityPreset());
1187
+           obs_data_set_int(data, AMF_H264_QUALITY_PRESET, (int32_t)m_VideoEncoder->GetQualityPreset());
1188
        } else {
1189
            switch (m_VideoEncoder->GetQualityPreset()) {
1190
-               case VCEQualityPreset_Speed:
1191
+               case H264QualityPreset::Speed:
1192
                    obs_data_set_string(data, "preset", "speed");
1193
                    break;
1194
-               case VCEQualityPreset_Balanced:
1195
+               case H264QualityPreset::Balanced:
1196
                    obs_data_set_string(data, "preset", "balanced");
1197
                    break;
1198
-               case VCEQualityPreset_Quality:
1199
+               case H264QualityPreset::Quality:
1200
                    obs_data_set_string(data, "preset", "quality");
1201
                    break;
1202
            }
1203
@@ -1542,70 +1428,85 @@
1204
    auto api = Plugin::API::Base::GetAPIByName(obs_data_get_string(data, AMF_H264_VIDEOAPI));
1205
    int64_t adapterId = obs_data_get_int(data, AMF_H264_VIDEOADAPTER);
1206
    auto adapter = api->GetAdapterById(adapterId & UINT_MAX, (adapterId >> 32) & UINT_MAX);
1207
-   auto devCaps = Plugin::AMD::VCECapabilities::GetInstance()->GetAdapterCapabilities(api, adapter, VCEEncoderType_AVC);
1208
+   auto devCaps = Plugin::AMD::VCECapabilities::GetInstance()->GetAdapterCapabilities(api, adapter, H264EncoderType::AVC);
1209
    #pragma endregion Device Capabilities
1210
 
1211
    #pragma region Rate Control
1212
    // Rate Control Properties
1213
-   m_VideoEncoder->SetRateControlMethod((VCERateControlMethod)obs_data_get_int(data, AMF_H264_RATECONTROLMETHOD));
1214
-   m_VideoEncoder->SetMinimumQP((uint8_t)obs_data_get_int(data, AMF_H264_QP_MINIMUM));
1215
-   m_VideoEncoder->SetMaximumQP((uint8_t)obs_data_get_int(data, AMF_H264_QP_MAXIMUM));
1216
-   switch ((VCERateControlMethod)obs_data_get_int(data, AMF_H264_RATECONTROLMETHOD)) {
1217
-       case VCERateControlMethod_ConstantBitrate:
1218
-           m_VideoEncoder->SetTargetBitrate((uint32_t)obs_data_get_int(data, AMF_H264_BITRATE_TARGET) * 1000);
1219
-           m_VideoEncoder->SetPeakBitrate(m_VideoEncoder->GetTargetBitrate());
1220
-           break;
1221
-       case VCERateControlMethod_VariableBitrate_PeakConstrained:
1222
-           m_VideoEncoder->SetTargetBitrate((uint32_t)obs_data_get_int(data, AMF_H264_BITRATE_TARGET) * 1000);
1223
-           m_VideoEncoder->SetPeakBitrate((uint32_t)obs_data_get_int(data, AMF_H264_BITRATE_PEAK) * 1000);
1224
-           break;
1225
-       case VCERateControlMethod_VariableBitrate_LatencyConstrained:
1226
-           m_VideoEncoder->SetTargetBitrate((uint32_t)obs_data_get_int(data, AMF_H264_BITRATE_TARGET) * 1000);
1227
-           m_VideoEncoder->SetPeakBitrate((uint32_t)obs_data_get_int(data, AMF_H264_BITRATE_PEAK) * 1000);
1228
-           break;
1229
-       case VCERateControlMethod_ConstantQP:
1230
-           m_VideoEncoder->SetIFrameQP((uint8_t)obs_data_get_int(data, AMF_H264_QP_IFRAME));
1231
-           m_VideoEncoder->SetPFrameQP((uint8_t)obs_data_get_int(data, AMF_H264_QP_PFRAME));
1232
-           try {
1233
-               m_VideoEncoder->SetBFrameQP((uint8_t)obs_data_get_int(data, AMF_H264_QP_BFRAME));
1234
-           } catch (std::exception e) {} catch (...) {}
1235
-           break;
1236
-   }
1237
-   if (obs_data_get_int(data, AMF_H264_VBVBUFFER) == 0) {
1238
-       m_VideoEncoder->SetVBVBufferAutomatic(obs_data_get_double(data, AMF_H264_VBVBUFFER_STRICTNESS) / 100.0);
1239
+   if (m_VideoEncoder->GetUsage() != H264Usage::UltraLowLatency) {
1240
+       m_VideoEncoder->SetRateControlMethod(static_cast<H264RateControlMethod>(obs_data_get_int(data, AMF_H264_RATECONTROLMETHOD)));
1241
+       m_VideoEncoder->SetMinimumQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_MINIMUM)));
1242
+       m_VideoEncoder->SetMaximumQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_MAXIMUM)));
1243
+       switch (static_cast<H264RateControlMethod>(obs_data_get_int(data, AMF_H264_RATECONTROLMETHOD))) {
1244
+           case H264RateControlMethod::ConstantBitrate:
1245
+               m_VideoEncoder->SetTargetBitrate(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_BITRATE_TARGET) * 1000));
1246
+               m_VideoEncoder->SetPeakBitrate(m_VideoEncoder->GetTargetBitrate());
1247
+               break;
1248
+           case H264RateControlMethod::VariableBitrate_PeakConstrained:
1249
+           case H264RateControlMethod::VariableBitrate_LatencyConstrained:
1250
+               m_VideoEncoder->SetTargetBitrate(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_BITRATE_TARGET) * 1000));
1251
+               m_VideoEncoder->SetPeakBitrate(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_BITRATE_PEAK) * 1000));
1252
+               break;
1253
+           case H264RateControlMethod::ConstantQP:
1254
+               m_VideoEncoder->SetIFrameQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_IFRAME)));
1255
+               m_VideoEncoder->SetPFrameQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_PFRAME)));
1256
+               if (devCaps.supportsBFrames && m_VideoEncoder->GetUsage() != H264Usage::UltraLowLatency)
1257
+                   try { m_VideoEncoder->SetBFrameQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_BFRAME))); } catch (...) {}
1258
+               break;
1259
+       }
1260
+       if (obs_data_get_int(data, AMF_H264_VBVBUFFER) == 0) {
1261
+           m_VideoEncoder->SetVBVBufferAutomatic(obs_data_get_double(data, AMF_H264_VBVBUFFER_STRICTNESS) / 100.0);
1262
+       } else {
1263
+           m_VideoEncoder->SetVBVBufferSize(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_VBVBUFFER_SIZE) * 1000));
1264
+       }
1265
+       m_VideoEncoder->SetInitialVBVBufferFullness(obs_data_get_double(data, AMF_H264_VBVBUFFER_FULLNESS) / 100.0);
1266
+       m_VideoEncoder->SetFillerDataEnabled(!!obs_data_get_int(data, AMF_H264_FILLERDATA));
1267
+       m_VideoEncoder->SetFrameSkippingEnabled(!!obs_data_get_int(data, AMF_H264_FRAMESKIPPING));
1268
    } else {
1269
-       m_VideoEncoder->SetVBVBufferSize((uint32_t)obs_data_get_int(data, AMF_H264_VBVBUFFER_SIZE) * 1000);
1270
+       m_VideoEncoder->SetMinimumQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_MINIMUM)));
1271
+       m_VideoEncoder->SetMaximumQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_MAXIMUM)));
1272
+       m_VideoEncoder->SetTargetBitrate(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_BITRATE_TARGET) * 1000));
1273
+
1274
+       m_VideoEncoder->SetIFrameQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_IFRAME)));
1275
+       m_VideoEncoder->SetPFrameQP(static_cast<uint8_t>(obs_data_get_int(data, AMF_H264_QP_PFRAME)));
1276
+
1277
+       if (obs_data_get_int(data, AMF_H264_VBVBUFFER) == 0) {
1278
+           m_VideoEncoder->SetVBVBufferSize(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_BITRATE_TARGET) * 1000));
1279
+       } else {
1280
+           m_VideoEncoder->SetVBVBufferSize(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_VBVBUFFER_SIZE) * 1000));
1281
+       }
1282
    }
1283
-   m_VideoEncoder->SetInitialVBVBufferFullness(obs_data_get_double(data, AMF_H264_VBVBUFFER_FULLNESS) / 100.0);
1284
-   m_VideoEncoder->SetFillerDataEnabled(obs_data_get_int(data, AMF_H264_FILLERDATA) == 1);
1285
-   m_VideoEncoder->SetFrameSkippingEnabled(obs_data_get_int(data, AMF_H264_FRAMESKIPPING) == 1);
1286
    m_VideoEncoder->SetEnforceHRDRestrictionsEnabled(obs_data_get_int(data, AMF_H264_ENFORCEHRDCOMPATIBILITY) == 1);
1287
    #pragma endregion Rate Control
1288
 
1289
    // Key-frame Interval
1290
    double_t framerate = (double_t)m_VideoEncoder->GetFrameRate().first / (double_t)m_VideoEncoder->GetFrameRate().second;
1291
-   if (obs_data_get_int(data, AMF_H264_VIEW) == ViewMode::Master)
1292
-       m_VideoEncoder->SetIDRPeriod((uint32_t)obs_data_get_int(data, AMF_H264_IDR_PERIOD));
1293
+   if (static_cast<ViewMode>(obs_data_get_int(data, AMF_H264_VIEW)) == ViewMode::Master)
1294
+       m_VideoEncoder->SetIDRPeriod(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_IDR_PERIOD)));
1295
    else
1296
-       m_VideoEncoder->SetIDRPeriod(max((uint32_t)(obs_data_get_double(data, AMF_H264_KEYFRAME_INTERVAL) * framerate), 1));
1297
+       m_VideoEncoder->SetIDRPeriod(max(static_cast<uint32_t>(obs_data_get_double(data, AMF_H264_KEYFRAME_INTERVAL) * framerate), 1));
1298
 
1299
    #pragma region B-Frames
1300
    if (devCaps.supportsBFrames) {
1301
        try {
1302
-           m_VideoEncoder->SetBFramePattern((VCEBFramePattern)obs_data_get_int(data, AMF_H264_BFRAME_PATTERN));
1303
-           m_VideoEncoder->SetBFrameReferenceEnabled(!!obs_data_get_int(data, AMF_H264_BFRAME_REFERENCE));
1304
-       } catch (std::exception e) {} catch (...) {}
1305
-       try {
1306
-           if (m_VideoEncoder->GetBFramePattern() != VCEBFramePattern_None) {
1307
-               m_VideoEncoder->SetBFrameDeltaQP((int8_t)obs_data_get_int(data, AMF_H264_BFRAME_DELTAQP));
1308
-               if (m_VideoEncoder->IsBFrameReferenceEnabled())
1309
-                   m_VideoEncoder->SetBFrameReferenceDeltaQP((int8_t)obs_data_get_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP));
1310
-           }
1311
-       } catch (std::exception e) {} catch (...) {}
1312
+           m_VideoEncoder->SetBFramePattern(static_cast<H264BFramePattern>(obs_data_get_int(data, AMF_H264_BFRAME_PATTERN)));
1313
+           if (obs_data_get_int(data, AMF_H264_BFRAME_PATTERN) != 0)
1314
+               m_VideoEncoder->SetBFrameDeltaQP(static_cast<int8_t>(obs_data_get_int(data, AMF_H264_BFRAME_DELTAQP)));
1315
+       } catch (...) {}
1316
+
1317
+       // B-Frame Reference can't be used with anything else but Transcoding.
1318
+       if (m_VideoEncoder->GetUsage() == H264Usage::Transcoding) {
1319
+           try {
1320
+               m_VideoEncoder->SetBFrameReferenceEnabled(!!obs_data_get_int(data, AMF_H264_BFRAME_REFERENCE));
1321
+               if (!!obs_data_get_int(data, AMF_H264_BFRAME_REFERENCE))
1322
+                   m_VideoEncoder->SetBFrameReferenceDeltaQP(static_cast<int8_t>(obs_data_get_int(data, AMF_H264_BFRAME_REFERENCEDELTAQP)));
1323
+           } catch (...) {}
1324
+       }
1325
    }
1326
    #pragma endregion B-Frames
1327
 
1328
-   m_VideoEncoder->SetDeblockingFilterEnabled(!!obs_data_get_int(data, AMF_H264_DEBLOCKINGFILTER));
1329
+   if (m_VideoEncoder->GetUsage() == H264Usage::Transcoding)
1330
+       m_VideoEncoder->SetDeblockingFilterEnabled(!!obs_data_get_int(data, AMF_H264_DEBLOCKINGFILTER));
1331
 
1332
    #pragma region Motion Estimation
1333
    m_VideoEncoder->SetHalfPixelMotionEstimationEnabled(!!(obs_data_get_int(data, AMF_H264_MOTIONESTIMATION) & 1));
1334
@@ -1613,26 +1514,32 @@
1335
    #pragma endregion Motion Estimation
1336
 
1337
    #pragma region Experimental
1338
-   try { m_VideoEncoder->SetCodingType((VCECodingType)obs_data_get_int(data, AMF_H264_CODINGTYPE)); } catch (std::exception e) {} catch (...) {}
1339
-   try { m_VideoEncoder->SetWaitForTaskEnabled(!!obs_data_get_int(data, AMF_H264_WAITFORTASK)); } catch (std::exception e) {} catch (...) {}
1340
-   try { m_VideoEncoder->SetPreAnalysisPassEnabled(!!obs_data_get_int(data, AMF_H264_PREANALYSISPASS)); } catch (std::exception e) {} catch (...) {}
1341
-   try { m_VideoEncoder->SetVBAQEnabled(!!obs_data_get_int(data, AMF_H264_VBAQ)); } catch (std::exception e) {} catch (...) {}
1342
-
1343
-   try { m_VideoEncoder->SetHeaderInsertionSpacing((uint32_t)obs_data_get_int(data, AMF_H264_HEADER_INSERTION_SPACING)); } catch (std::exception e) {} catch (...) {}
1344
-   try { m_VideoEncoder->SetMaximumAccessUnitSize((uint32_t)obs_data_get_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE)); } catch (std::exception e) {} catch (...) {}
1345
-   try { m_VideoEncoder->SetMaximumReferenceFrames((uint32_t)obs_data_get_int(data, AMF_H264_MAXIMUMREFERENCEFRAMES)); } catch (std::exception e) {} catch (...) {}
1346
-
1347
-   try { m_VideoEncoder->SetGOPSize((uint32_t)obs_data_get_int(data, AMF_H264_GOPSIZE)); } catch (std::exception e) {} catch (...) {}
1348
-   try { m_VideoEncoder->SetGOPAlignmentEnabled(!!obs_data_get_int(data, AMF_H264_GOPALIGNMENT)); } catch (std::exception e) {} catch (...) {}
1349
-
1350
-   try { m_VideoEncoder->SetIntraRefreshNumberOfStripes((uint32_t)obs_data_get_int(data, AMF_H264_INTRAREFRESH_NUMBEROFSTRIPES)); } catch (std::exception e) {} catch (...) {}
1351
-   try { m_VideoEncoder->SetIntraRefreshMacroblocksPerSlot((uint32_t)obs_data_get_int(data, AMF_H264_INTRAREFRESH_MACROBLOCKSPERSLOT)); } catch (std::exception e) {} catch (...) {}
1352
-
1353
-   try { m_VideoEncoder->SetSlicesPerFrame((uint32_t)obs_data_get_int(data, AMF_H264_SLICESPERFRAME)); } catch (std::exception e) {} catch (...) {}
1354
-   try { m_VideoEncoder->SetSliceMode((VCESliceMode)obs_data_get_int(data, AMF_H264_SLICEMODE)); } catch (std::exception e) {} catch (...) {}
1355
-   try { m_VideoEncoder->SetMaximumSliceSize((uint32_t)obs_data_get_int(data, AMF_H264_MAXIMUMSLICESIZE)); } catch (std::exception e) {} catch (...) {}
1356
-   try { m_VideoEncoder->SetSliceControlMode((VCESliceControlMode)obs_data_get_int(data, AMF_H264_SLICECONTROLMODE)); } catch (std::exception e) {} catch (...) {}
1357
-   try { m_VideoEncoder->SetSliceControlSize((uint32_t)obs_data_get_int(data, AMF_H264_SLICECONTROLSIZE)); } catch (std::exception e) {} catch (...) {}
1358
+   try { m_VideoEncoder->SetCodingType(static_cast<H264CodingType>(obs_data_get_int(data, AMF_H264_CODINGTYPE))); } catch (...) {}
1359
+   try { m_VideoEncoder->SetWaitForTaskEnabled(!!obs_data_get_int(data, AMF_H264_WAITFORTASK)); } catch (...) {}
1360
+   if (m_VideoEncoder->GetUsage() == H264Usage::Transcoding || m_VideoEncoder->GetUsage() == H264Usage::Webcam) {
1361
+       try { m_VideoEncoder->SetPreAnalysisPassEnabled(!!obs_data_get_int(data, AMF_H264_PREANALYSISPASS)); } catch (...) {}
1362
+       try { m_VideoEncoder->SetVBAQEnabled(!!obs_data_get_int(data, AMF_H264_VBAQ)); } catch (...) {}
1363
+   }
1364
+
1365
+   try { m_VideoEncoder->SetHeaderInsertionSpacing(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_HEADER_INSERTION_SPACING))); } catch (...) {}
1366
+   if (m_VideoEncoder->GetUsage() == H264Usage::Transcoding || m_VideoEncoder->GetUsage() == H264Usage::Webcam) {
1367
+       try { m_VideoEncoder->SetMaximumAccessUnitSize(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_MAXIMUMACCESSUNITSIZE))); } catch (...) {}
1368
+   }
1369
+   try { m_VideoEncoder->SetMaximumReferenceFrames(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_MAXIMUMREFERENCEFRAMES))); } catch (...) {}
1370
+
1371
+   if (m_VideoEncoder->GetUsage() == H264Usage::Transcoding || m_VideoEncoder->GetUsage() == H264Usage::Webcam) {
1372
+       try { m_VideoEncoder->SetGOPSize(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_GOPSIZE))); } catch (...) {}
1373
+   }
1374
+   try { m_VideoEncoder->SetGOPAlignmentEnabled(!!obs_data_get_int(data, AMF_H264_GOPALIGNMENT)); } catch (...) {}
1375
+
1376
+   try { m_VideoEncoder->SetIntraRefreshNumberOfStripes(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_INTRAREFRESH_NUMBEROFSTRIPES))); } catch (...) {}
1377
+   try { m_VideoEncoder->SetIntraRefreshMacroblocksPerSlot(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_INTRAREFRESH_MACROBLOCKSPERSLOT))); } catch (...) {}
1378
+
1379
+   try { m_VideoEncoder->SetSlicesPerFrame(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_SLICESPERFRAME))); } catch (...) {}
1380
+   try { m_VideoEncoder->SetSliceMode(static_cast<H264SliceMode>(obs_data_get_int(data, AMF_H264_SLICEMODE))); } catch (...) {}
1381
+   try { m_VideoEncoder->SetMaximumSliceSize(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_MAXIMUMSLICESIZE))); } catch (...) {}
1382
+   try { m_VideoEncoder->SetSliceControlMode(static_cast<H264SliceControlMode>(obs_data_get_int(data, AMF_H264_SLICECONTROLMODE))); } catch (...) {}
1383
+   try { m_VideoEncoder->SetSliceControlSize(static_cast<uint32_t>(obs_data_get_int(data, AMF_H264_SLICECONTROLSIZE))); } catch (...) {}
1384
    #pragma endregion Experimental
1385
 
1386
    if (m_VideoEncoder->IsStarted()) {
1387
@@ -1643,47 +1550,50 @@
1388
            const char* t_str = obs_data_get_string(data, "rate_control");
1389
            if (strcmp(t_str, "") != 0) {
1390
                if (strcmp(t_str, "CBR") == 0) {
1391
-                   m_VideoEncoder->SetRateControlMethod(VCERateControlMethod_ConstantBitrate);
1392
+                   m_VideoEncoder->SetRateControlMethod(H264RateControlMethod::ConstantBitrate);
1393
                    m_VideoEncoder->SetFillerDataEnabled(true);
1394
                } else if (strcmp(t_str, "VBR") == 0) {
1395
-                   m_VideoEncoder->SetRateControlMethod(VCERateControlMethod_VariableBitrate_PeakConstrained);
1396
+                   m_VideoEncoder->SetRateControlMethod(H264RateControlMethod::VariableBitrate_PeakConstrained);
1397
                } else if (strcmp(t_str, "VBR_LAT") == 0) {
1398
-                   m_VideoEncoder->SetRateControlMethod(VCERateControlMethod_VariableBitrate_LatencyConstrained);
1399
+                   m_VideoEncoder->SetRateControlMethod(H264RateControlMethod::VariableBitrate_LatencyConstrained);
1400
                } else if (strcmp(t_str, "CQP") == 0) {
1401
-                   m_VideoEncoder->SetRateControlMethod(VCERateControlMethod_ConstantQP);
1402
+                   m_VideoEncoder->SetRateControlMethod(H264RateControlMethod::ConstantQP);
1403
                }
1404
 
1405
-               obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, m_VideoEncoder->GetRateControlMethod());
1406
+               obs_data_set_int(data, AMF_H264_RATECONTROLMETHOD, (int32_t)m_VideoEncoder->GetRateControlMethod());
1407
            } else {
1408
-               switch (m_VideoEncoder->GetRateControlMethod()) {
1409
-                   case VCERateControlMethod_ConstantBitrate:
1410
-                       obs_data_set_string(data, "rate_control", "CBR");
1411
-                       break;
1412
-                   case VCERateControlMethod_VariableBitrate_PeakConstrained:
1413
-                       obs_data_set_string(data, "rate_control", "VBR");
1414
-                       break;
1415
-                   case VCERateControlMethod_VariableBitrate_LatencyConstrained:
1416
-                       obs_data_set_string(data, "rate_control", "VBR_LAT");
1417
-                       break;
1418
-                   case VCERateControlMethod_ConstantQP:
1419
-                       obs_data_set_string(data, "rate_control", "CQP");
1420
-                       break;
1421
-               }
1422
+               if (m_VideoEncoder->GetUsage() != H264Usage::UltraLowLatency)
1423
+                   switch (m_VideoEncoder->GetRateControlMethod()) {
1424
+                       case H264RateControlMethod::ConstantBitrate:
1425
+                           obs_data_set_string(data, "rate_control", "CBR");
1426
+                           break;
1427
+                       case H264RateControlMethod::VariableBitrate_PeakConstrained:
1428
+                           obs_data_set_string(data, "rate_control", "VBR");
1429
+                           break;
1430
+                       case H264RateControlMethod::VariableBitrate_LatencyConstrained:
1431
+                           obs_data_set_string(data, "rate_control", "VBR_LAT");
1432
+                           break;
1433
+                       case H264RateControlMethod::ConstantQP:
1434
+                           obs_data_set_string(data, "rate_control", "CQP");
1435
+                           break;
1436
+                   }
1437
            }
1438
 
1439
            // Bitrate
1440
            uint64_t bitrateOvr = obs_data_get_int(data, "bitrate") * 1000;
1441
            if (bitrateOvr != -1) {
1442
                if (m_VideoEncoder->GetTargetBitrate() > bitrateOvr)
1443
-                   m_VideoEncoder->SetTargetBitrate((uint32_t)bitrateOvr);
1444
+                   m_VideoEncoder->SetTargetBitrate(static_cast<uint32_t>(bitrateOvr));
1445
 
1446
-               if (m_VideoEncoder->GetPeakBitrate() > bitrateOvr)
1447
-                   m_VideoEncoder->SetPeakBitrate((uint32_t)bitrateOvr);
1448
+               if (m_VideoEncoder->GetUsage() != H264Usage::UltraLowLatency)
1449
+                   if (m_VideoEncoder->GetPeakBitrate() > bitrateOvr)
1450
+                       m_VideoEncoder->SetPeakBitrate(static_cast<uint32_t>(bitrateOvr));
1451
 
1452
                obs_data_set_int(data, "bitrate", m_VideoEncoder->GetTargetBitrate() / 1000);
1453
 
1454
                obs_data_set_int(data, AMF_H264_BITRATE_TARGET, m_VideoEncoder->GetTargetBitrate() / 1000);
1455
-               obs_data_set_int(data, AMF_H264_BITRATE_PEAK, m_VideoEncoder->GetPeakBitrate() / 1000);
1456
+               if (m_VideoEncoder->GetUsage() != H264Usage::UltraLowLatency)
1457
+                   obs_data_set_int(data, AMF_H264_BITRATE_PEAK, m_VideoEncoder->GetPeakBitrate() / 1000);
1458
            } else {
1459
                obs_data_set_int(data, "bitrate", m_VideoEncoder->GetTargetBitrate() / 1000);
1460
            }
1461
@@ -1692,19 +1602,19 @@
1462
            uint32_t fpsNum = m_VideoEncoder->GetFrameRate().first;
1463
            uint32_t fpsDen = m_VideoEncoder->GetFrameRate().second;
1464
            if (obs_data_get_int(data, "keyint_sec") != -1) {
1465
-               m_VideoEncoder->SetIDRPeriod((uint32_t)(obs_data_get_int(data, "keyint_sec") * ((double_t)fpsNum / (double_t)fpsDen)));
1466
+               m_VideoEncoder->SetIDRPeriod(static_cast<uint32_t>(obs_data_get_int(data, "keyint_sec") * (static_cast<double_t>(fpsNum) / static_cast<double_t>(fpsDen))));
1467
 
1468
-               obs_data_set_double(data, AMF_H264_KEYFRAME_INTERVAL, (double_t)obs_data_get_int(data, "keyint_sec"));
1469
-               obs_data_set_int(data, AMF_H264_IDR_PERIOD, (uint32_t)(obs_data_get_int(data, "keyint_sec") * ((double_t)fpsNum / (double_t)fpsDen)));
1470
+               obs_data_set_double(data, AMF_H264_KEYFRAME_INTERVAL, static_cast<double_t>(obs_data_get_int(data, "keyint_sec")));
1471
+               obs_data_set_int(data, AMF_H264_IDR_PERIOD, static_cast<uint32_t>(obs_data_get_int(data, "keyint_sec") *  (static_cast<double_t>(fpsNum) / static_cast<double_t>(fpsDen))));
1472
            } else {
1473
-               obs_data_set_int(data, "keyint_sec", (uint64_t)(m_VideoEncoder->GetIDRPeriod() / ((double_t)fpsNum / (double_t)fpsDen)));
1474
+               obs_data_set_int(data, "keyint_sec", static_cast<uint64_t>(m_VideoEncoder->GetIDRPeriod() / (static_cast<double_t>(fpsNum) / static_cast<double_t>(fpsDen))));
1475
            }
1476
        }
1477
        #pragma endregion OBS Enforce Streaming Service Settings
1478
 
1479
        // Verify
1480
        m_VideoEncoder->LogProperties();
1481
-       if (obs_data_get_int(data, AMF_H264_VIEW) >= ViewMode::Master)
1482
+       if (static_cast<ViewMode>(obs_data_get_int(data, AMF_H264_VIEW)) >= ViewMode::Master)
1483
            AMF_LOG_ERROR("View Mode 'Master' is active, avoid giving anything but basic support. Error is most likely caused by user settings themselves.");
1484
    }
1485
 
1486
obs-studio-0.17.0.tar.xz/plugins/enc-amf/Source/misc-util.cpp -> obs-studio-17.0.1.tar.xz/plugins/enc-amf/Source/misc-util.cpp Changed
295
 
1
@@ -40,35 +40,35 @@
2
 
3
 namespace Plugin {
4
    namespace Utility {
5
-       VCEProfileLevel inline GetMinimumProfileLevel(std::pair<uint32_t, uint32_t> frameSize, std::pair<uint32_t, uint32_t> frameRate) {
6
+       H264ProfileLevel inline GetMinimumProfileLevel(std::pair<uint32_t, uint32_t> frameSize, std::pair<uint32_t, uint32_t> frameRate) {
7
            typedef std::pair<uint32_t, uint32_t> levelRestriction;
8
-           typedef std::pair<VCEProfileLevel, levelRestriction> level;
9
+           typedef std::pair<H264ProfileLevel, levelRestriction> level;
10
 
11
            static const level profileLevelLimit[] = { // [Level, [Samples, Samples_Per_Sec]]
12
-               level(VCEProfileLevel_10, levelRestriction(25344, 380160)),
13
-               level(VCEProfileLevel_11, levelRestriction(101376, 768000)),
14
-               level(VCEProfileLevel_12, levelRestriction(101376, 1536000)),
15
-               level(VCEProfileLevel_13, levelRestriction(101376, 3041280)),
16
-               level(VCEProfileLevel_20, levelRestriction(101376, 3041280)),
17
-               level(VCEProfileLevel_21, levelRestriction(202752, 5068800)),
18
-               level(VCEProfileLevel_22, levelRestriction(414720, 5184000)),
19
-               level(VCEProfileLevel_30, levelRestriction(414720, 10368000)),
20
-               level(VCEProfileLevel_31, levelRestriction(921600, 27648000)),
21
-               level(VCEProfileLevel_32, levelRestriction(1310720, 55296000)),
22
-               //level(VCEProfileLevel_40, levelRestriction(2097152, 62914560)), // Technically identical to 4.1, but backwards compatible.
23
-               level(VCEProfileLevel_41, levelRestriction(2097152, 62914560)),
24
-               level(VCEProfileLevel_42, levelRestriction(2228224, 133693440)),
25
-               level(VCEProfileLevel_50, levelRestriction(5652480, 150994944)),
26
-               level(VCEProfileLevel_51, levelRestriction(9437184, 251658240)),
27
-               level(VCEProfileLevel_52, levelRestriction(9437184, 530841600)),
28
-               level((VCEProfileLevel)-1, levelRestriction(0, 0))
29
+               level(H264ProfileLevel::L10, levelRestriction(25344, 380160)),
30
+               level(H264ProfileLevel::L11, levelRestriction(101376, 768000)),
31
+               level(H264ProfileLevel::L12, levelRestriction(101376, 1536000)),
32
+               level(H264ProfileLevel::L13, levelRestriction(101376, 3041280)),
33
+               level(H264ProfileLevel::L20, levelRestriction(101376, 3041280)),
34
+               level(H264ProfileLevel::L21, levelRestriction(202752, 5068800)),
35
+               level(H264ProfileLevel::L22, levelRestriction(414720, 5184000)),
36
+               level(H264ProfileLevel::L30, levelRestriction(414720, 10368000)),
37
+               level(H264ProfileLevel::L31, levelRestriction(921600, 27648000)),
38
+               level(H264ProfileLevel::L32, levelRestriction(1310720, 55296000)),
39
+               //level(H264ProfileLevel::40, levelRestriction(2097152, 62914560)), // Technically identical to 4.1, but backwards compatible.
40
+               level(H264ProfileLevel::L41, levelRestriction(2097152, 62914560)),
41
+               level(H264ProfileLevel::L42, levelRestriction(2228224, 133693440)),
42
+               level(H264ProfileLevel::L50, levelRestriction(5652480, 150994944)),
43
+               level(H264ProfileLevel::L51, levelRestriction(9437184, 251658240)),
44
+               level(H264ProfileLevel::L52, levelRestriction(9437184, 530841600)),
45
+               level((H264ProfileLevel)-1, levelRestriction(0, 0))
46
            };
47
 
48
            uint32_t samples = frameSize.first * frameSize.second;
49
            uint32_t samples_sec = (uint32_t)ceil((double_t)samples * ((double_t)frameRate.first / (double_t)frameRate.second));
50
 
51
            level curLevel = profileLevelLimit[0];
52
-           for (uint32_t index = 0; curLevel.first != -1; index++) {
53
+           for (uint32_t index = 0; (int32_t)curLevel.first != -1; index++) {
54
                curLevel = profileLevelLimit[index];
55
 
56
                if (samples > curLevel.second.first)
57
@@ -79,49 +79,49 @@
58
 
59
                return curLevel.first;
60
            }
61
-           return VCEProfileLevel_52;
62
+           return H264ProfileLevel::L52;
63
        }
64
 
65
        #pragma region VCEEncoderType
66
-       inline const char* VCEEncoderTypeAsString(VCEEncoderType type) {
67
+       inline const char* VCEEncoderTypeAsString(H264EncoderType type) {
68
            const char* types[] = {
69
                "AVC",
70
                "SVC",
71
                "HEVC"
72
            };
73
-           return types[type];
74
+           return types[(uint8_t)type];
75
        }
76
-       inline const wchar_t* VCEEncoderTypeAsAMF(VCEEncoderType type) {
77
+       inline const wchar_t* VCEEncoderTypeAsAMF(H264EncoderType type) {
78
            const wchar_t* types[] = {
79
                AMFVideoEncoderVCE_AVC,
80
                AMFVideoEncoderVCE_SVC,
81
                L"AMFVideoEncoderHW_HEVC"
82
            };
83
-           return types[type];
84
+           return types[(uint8_t)type];
85
        }
86
        #pragma endregion VCEEncoderType
87
        #pragma region VCEMemoryType
88
-       inline const char* MemoryTypeAsString(VCEMemoryType memoryType) {
89
+       inline const char* MemoryTypeAsString(H264MemoryType memoryType) {
90
            static const char* memoryTypeToString[] = {
91
                "Host",
92
                "DirectX9",
93
                "DirectX11",
94
                "OpenGL"
95
            };
96
-           return memoryTypeToString[memoryType];
97
+           return memoryTypeToString[(uint8_t)memoryType];
98
        }
99
-       inline amf::AMF_MEMORY_TYPE MemoryTypeAsAMF(VCEMemoryType memoryType) {
100
+       inline amf::AMF_MEMORY_TYPE MemoryTypeAsAMF(H264MemoryType memoryType) {
101
            static amf::AMF_MEMORY_TYPE memoryTypeToAMF[] = {
102
                amf::AMF_MEMORY_HOST,
103
                amf::AMF_MEMORY_DX9,
104
                amf::AMF_MEMORY_DX11,
105
                amf::AMF_MEMORY_OPENGL,
106
            };
107
-           return memoryTypeToAMF[memoryType];
108
+           return memoryTypeToAMF[(uint8_t)memoryType];
109
        }
110
        #pragma endregion VCEMemoryType
111
        #pragma region VCESurfaceFormat
112
-       inline const char* SurfaceFormatAsString(VCEColorFormat surfaceFormat) {
113
+       inline const char* SurfaceFormatAsString(H264ColorFormat surfaceFormat) {
114
            static const char* surfaceFormatToString[] = {
115
                "NV12",
116
                "I420",
117
@@ -130,9 +130,9 @@
118
                "RGBA",
119
                "GRAY",
120
            };
121
-           return surfaceFormatToString[surfaceFormat];
122
+           return surfaceFormatToString[(uint8_t)surfaceFormat];
123
        }
124
-       inline amf::AMF_SURFACE_FORMAT SurfaceFormatAsAMF(VCEColorFormat surfaceFormat) {
125
+       inline amf::AMF_SURFACE_FORMAT SurfaceFormatAsAMF(H264ColorFormat surfaceFormat) {
126
            static amf::AMF_SURFACE_FORMAT surfaceFormatToAMF[] = {
127
                // 4:2:0 Formats
128
                amf::AMF_SURFACE_NV12,
129
@@ -145,60 +145,60 @@
130
                // Other
131
                amf::AMF_SURFACE_GRAY8,
132
            };
133
-           return surfaceFormatToAMF[surfaceFormat];
134
+           return surfaceFormatToAMF[(uint8_t)surfaceFormat];
135
        }
136
        #pragma endregion VCESurfaceFormat
137
        #pragma region VCEUsage
138
-       inline const char* UsageAsString(VCEUsage usage) {
139
+       inline const char* UsageAsString(H264Usage usage) {
140
            static const char* usageToString[] = {
141
                "Transcoding",
142
                "Ultra Low Latency",
143
                "Low Latency",
144
                "Webcam"
145
            };
146
-           return usageToString[usage];
147
+           return usageToString[(uint8_t)usage];
148
        }
149
-       inline AMF_VIDEO_ENCODER_USAGE_ENUM UsageAsAMF(VCEUsage usage) {
150
+       inline AMF_VIDEO_ENCODER_USAGE_ENUM UsageAsAMF(H264Usage usage) {
151
            static AMF_VIDEO_ENCODER_USAGE_ENUM usageToAMF[] = {
152
                AMF_VIDEO_ENCODER_USAGE_TRANSCONDING,
153
                AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY,
154
                AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY,
155
                AMF_VIDEO_ENCODER_USAGE_WEBCAM,
156
            };
157
-           return usageToAMF[usage];
158
+           return usageToAMF[(uint8_t)usage];
159
        }
160
-       inline VCEUsage UsageFromAMF(uint32_t usage) {
161
-           static VCEUsage usageFromAMF[] = {
162
-               VCEUsage_Transcoding,
163
-               VCEUsage_UltraLowLatency,
164
-               VCEUsage_LowLatency,
165
-               VCEUsage_Webcam,
166
+       inline H264Usage UsageFromAMF(uint32_t usage) {
167
+           static H264Usage usageFromAMF[] = {
168
+               H264Usage::Transcoding,
169
+               H264Usage::UltraLowLatency,
170
+               H264Usage::LowLatency,
171
+               H264Usage::Webcam,
172
            };
173
-           return usageFromAMF[usage];
174
+           return usageFromAMF[(uint8_t)usage];
175
        }
176
        #pragma endregion VCEUsage
177
        #pragma region VCEQualityPreset
178
-       inline const char* QualityPresetAsString(VCEQualityPreset preset) {
179
+       inline const char* QualityPresetAsString(H264QualityPreset preset) {
180
            static const char* qualityPresetToString[] = {
181
                "Speed",
182
                "Balanced",
183
                "Quality"
184
            };
185
-           return qualityPresetToString[preset];
186
+           return qualityPresetToString[(uint8_t)preset];
187
        }
188
        #pragma endregion VCEQualityPreset
189
        #pragma region VCEProfile
190
-       inline const char* ProfileAsString(VCEProfile profile) {
191
+       inline const char* ProfileAsString(H264Profile profile) {
192
            switch (profile) {
193
-               case VCEProfile_Baseline:
194
+               case H264Profile::Baseline:
195
                    return "Baseline";
196
-               case VCEProfile_Main:
197
+               case H264Profile::Main:
198
                    return "Main";
199
-               case VCEProfile_High:
200
+               case H264Profile::High:
201
                    return "High";
202
-               case VCEProfile_ConstrainedBaseline:
203
+               case H264Profile::ConstrainedBaseline:
204
                    return "Constrained Baseline";
205
-               case VCEProfile_ConstrainedHigh:
206
+               case H264Profile::ConstrainedHigh:
207
                    return "Constrained High";
208
            }
209
 
210
@@ -206,62 +206,62 @@
211
        }
212
        #pragma endregion VCEProfile
213
        #pragma region VCERateControlMethod
214
-       inline const char* RateControlMethodAsString(VCERateControlMethod method) {
215
+       inline const char* RateControlMethodAsString(H264RateControlMethod method) {
216
            static const char* rateControlMethodToString[] = {
217
                "Constant Quantization Parameter (CQP)",
218
                "Constant Bitrate (CBR)",
219
                "Peak Constrained Variable Bitrate (VBR)",
220
                "Latency Constrained Variable Bitrate (VBR_LAT)"
221
            };
222
-           return rateControlMethodToString[method];
223
+           return rateControlMethodToString[(uint8_t)method];
224
        }
225
-       inline AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM RateControlMethodAsAMF(VCERateControlMethod method) {
226
+       inline AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM RateControlMethodAsAMF(H264RateControlMethod method) {
227
            static AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM CustomToAMF[] = {
228
                AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP,
229
                AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR,
230
                AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
231
                AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR,
232
            };
233
-           return CustomToAMF[method];
234
+           return CustomToAMF[(uint8_t)method];
235
        }
236
-       inline VCERateControlMethod RateControlMethodFromAMF(uint32_t method) {
237
-           static VCERateControlMethod AMFToCustom[] = {
238
-               VCERateControlMethod_ConstantQP,
239
-               VCERateControlMethod_ConstantBitrate,
240
-               VCERateControlMethod_VariableBitrate_PeakConstrained,
241
-               VCERateControlMethod_VariableBitrate_LatencyConstrained,
242
+       inline H264RateControlMethod RateControlMethodFromAMF(uint32_t method) {
243
+           static H264RateControlMethod AMFToCustom[] = {
244
+               H264RateControlMethod::ConstantQP,
245
+               H264RateControlMethod::ConstantBitrate,
246
+               H264RateControlMethod::VariableBitrate_PeakConstrained,
247
+               H264RateControlMethod::VariableBitrate_LatencyConstrained,
248
            };
249
-           return AMFToCustom[method];
250
+           return AMFToCustom[(uint8_t)method];
251
        }
252
        #pragma endregion VCERateControlMethod
253
 
254
-       inline const char* CodingTypeAsString(VCECodingType type) {
255
+       inline const char* CodingTypeAsString(H264CodingType type) {
256
            switch (type) {
257
-               case VCECodingType_CABAC:
258
+               case H264CodingType::CABAC:
259
                    return "CABAC";
260
-               case VCECodingType_CALVC:
261
+               case H264CodingType::CALVC:
262
                    return "CALVC";
263
-               case VCECodingType_Default:
264
+               case H264CodingType::Default:
265
                    return "Default";
266
            }
267
            return "MEMORY CORRUPTION";
268
        }
269
-       inline const char* SliceModeAsString(VCESliceMode mode) {
270
+       inline const char* SliceModeAsString(H264SliceMode mode) {
271
            switch (mode) {
272
-               case VCESliceMode_Horizontal:
273
+               case H264SliceMode::Horizontal:
274
                    return "Horizontal";
275
-               case VCESliceMode_Vertical:
276
+               case H264SliceMode::Vertical:
277
                    return "Vertical";
278
            }
279
            return "MEMORY CORRUPTION";
280
        }
281
-       inline const char* SliceControlModeAsString(VCESliceControlMode mode) {
282
+       inline const char* SliceControlModeAsString(H264SliceControlMode mode) {
283
            switch (mode) {
284
-               case VCESliceControlMode_Off:
285
+               case H264SliceControlMode::Off:
286
                    return "Off";
287
-               case VCESliceControlMode_Macroblock:
288
+               case H264SliceControlMode::Macroblock:
289
                    return "Macroblock";
290
-               case VCESliceControlMode_Macroblock_Row:
291
+               case H264SliceControlMode::Macroblock_Row:
292
                    return "Macroblock Row";
293
            }
294
            return "MEMORY CORRUPTION";
295
obs-studio-0.17.0.tar.xz/plugins/image-source/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/image-source/data/locale/tr-TR.ini Changed
9
 
1
@@ -6,6 +6,7 @@
2
 SlideShow.TransitionSpeed="Geçiş Hızı (milisaniye)"
3
 SlideShow.SlideTime="Slaytlar Arası Süre (milisaniye)"
4
 SlideShow.Files="Görüntü Dosyaları"
5
+SlideShow.Randomize="Rastgele Gösterim"
6
 SlideShow.Transition="Geçiş"
7
 SlideShow.Transition.Cut="Cut"
8
 SlideShow.Transition.Fade="Fade"
9
obs-studio-0.17.0.tar.xz/plugins/linux-capture/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/linux-capture/data/locale/tr-TR.ini Changed
7
 
1
@@ -12,4 +12,5 @@
2
 SwapRedBlue="Kırmızı ve maviyi değiştir"
3
 LockX="Yakalama sırasında X sunucusunu kilitle"
4
 IncludeXBorder="X Çerçevesini Dahil Et"
5
+ExcludeAlpha="Alpha kanalı olmayan doku biçimi kullan (Mesa geçici çözüm)"
6
 
7
obs-studio-0.17.0.tar.xz/plugins/mac-capture/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/mac-capture/data/locale/hu-HU.ini Changed
8
 
1
@@ -1,5 +1,5 @@
2
 CoreAudio.InputCapture="Bemeneti hangrögzítés"
3
-CoreAudio.OutputCapture="Kimeneti hangrögzítés"
4
+CoreAudio.OutputCapture="Kimeneti hangrögzítő"
5
 CoreAudio.Device="Eszköz"
6
 CoreAudio.Device.Default="Alapértelmezett"
7
 DisplayCapture="Kijelző felvétel"
8
obs-studio-0.17.0.tar.xz/plugins/mac-vth264/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/mac-vth264/data/locale/hu-HU.ini Changed
16
 
1
@@ -1,10 +1,10 @@
2
 VTH264EncHW="Apple VT H264 hardveres kódoló"
3
 VTH264EncSW="Apple VT H264 szoftveres kódoló"
4
 VTEncoder="VideoToolbox H264 kódoló"
5
-Bitrate="Bitráta"
6
-UseMaxBitrate="Bitráta limit"
7
-MaxBitrate="Maximális bitráta"
8
-MaxBitrateWindow="Maximális bitrátaablak (másodperc)"
9
+Bitrate="Bitsebesség"
10
+UseMaxBitrate="Bitsebesség limit"
11
+MaxBitrate="Maximális bitsebesség"
12
+MaxBitrateWindow="Maximális bitsebességablak (másodperc)"
13
 KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)"
14
 Profile="Profil"
15
 None="(Nincs)"
16
obs-studio-0.17.0.tar.xz/plugins/mac-vth264/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/mac-vth264/data/locale/tr-TR.ini Changed
14
 
1
@@ -2,10 +2,12 @@
2
 VTH264EncSW="Apple VT H264 Yazılım Kodlayıcı"
3
 VTEncoder="VideoToolbox Kodlayıcı"
4
 Bitrate="Bithızı"
5
+UseMaxBitrate="Bit hızını sınırla"
6
 MaxBitrate="Maks bit hızı"
7
 KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)"
8
 Profile="Profil"
9
 None="(Yok)"
10
 DefaultEncoder="(Varsayılan Kodlayıcı)"
11
+UseBFrames="B-Frame kullan"
12
 
13
 
14
obs-studio-0.17.0.tar.xz/plugins/obs-browser/CMakeLists.txt -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/CMakeLists.txt Changed
171
 
1
@@ -46,7 +46,8 @@
2
    obs-browser/main.cpp
3
    obs-browser/main-source.cpp
4
    shared/browser-source.cpp
5
-   shared/base64.cpp)
6
+   shared/base64.cpp
7
+   shared/util.cpp)
8
 
9
 set(obs-browser_HEADERS
10
    shared/browser-manager.hpp
11
@@ -56,7 +57,8 @@
12
    shared/browser-types.h
13
    shared/base64.hpp
14
    shared/browser-types.h
15
-   shared/browser-version.h)
16
+   shared/browser-version.h
17
+   shared/util.hpp)
18
 
19
 if (APPLE)
20
    list(APPEND obs-browser_SOURCES
21
@@ -94,7 +96,9 @@
22
        obs-browser/browser-render-handler.cpp
23
        obs-browser/browser-source-base.cpp
24
        obs-browser/browser-load-handler.cpp
25
-       shared/browser-scheme.cpp)
26
+       obs-browser/browser-obs-bridge-base.cpp
27
+       shared/browser-scheme.cpp
28
+       fmt/format.cc)
29
 
30
    list(APPEND obs-browser_HEADERS
31
        shared/browser-client.hpp
32
@@ -105,13 +109,15 @@
33
        obs-browser/browser-render-handler.hpp
34
        obs-browser/browser-source-base.hpp
35
        obs-browser/browser-load-handler.hpp
36
-       shared/browser-scheme.hpp)
37
+       obs-browser/browser-obs-bridge-base.hpp
38
+       shared/browser-scheme.hpp
39
+       fmt/format.h)
40
 
41
 endif(APPLE)
42
 
43
 set(obs-browser_LIBRARIES
44
-   libobs
45
-   obs-frontend-api)
46
+   obs-frontend-api
47
+   ${OBS_JANSSON_IMPORT})
48
 
49
 if (APPLE)
50
    list(APPEND obs-browser_LIBRARIES
51
@@ -128,13 +134,17 @@
52
    "obs-browser" 
53
    "shared")
54
 
55
+target_include_directories(obs-browser PUBLIC
56
+   ${OBS_JANSSON_INCLUDE_DIRS})
57
+
58
 if (APPLE)
59
    target_include_directories(obs-browser PUBLIC 
60
        "shared-apple")
61
-else(APPLE)
62
-   target_include_directories_system(obs-browser PUBLIC ${CEF_INCLUDE_DIR})
63
+else (APPLE)
64
+   target_include_directories_system(obs-browser PUBLIC ${CEF_ROOT_DIR})
65
 endif(APPLE)
66
 
67
+
68
 if (APPLE)
69
    set_xcode_property(obs-browser CLANG_CXX_LIBRARY "libc++")
70
 endif(APPLE)
71
@@ -160,6 +170,7 @@
72
    set(cef-isolation_SOURCES
73
        cef-isolation/main.mm
74
        cef-isolation/cef-isolated-client.mm
75
+       cef-isolation/browser-obs-bridge-mac.mm
76
        cef-isolation/browser-handle.mm
77
        cef-isolation/browser-render-handler.mm
78
        cef-isolation/browser-texture-mac.mm
79
@@ -169,7 +180,8 @@
80
        shared/browser-app.cpp
81
        shared/browser-scheme.cpp
82
        shared/base64.cpp
83
-       obs-browser/browser-load-handler.cpp)
84
+       obs-browser/browser-load-handler.cpp
85
+       fmt/format.cc)
86
 
87
    set(cef-isolation_HEADERS
88
        shared-apple/cef-logging.h
89
@@ -179,6 +191,7 @@
90
        cef-isolation/browser-render-handler.hpp
91
        cef-isolation/browser-texture-mac.h
92
        cef-isolation/service-connection-delegate.h
93
+       cef-isolation/browser-obs-bridge-mac.hpp
94
        shared/browser-texture.hpp
95
        shared/browser-client.hpp
96
        shared/browser-task.hpp
97
@@ -187,6 +200,7 @@
98
        obs-browser/browser-load-handler.hpp
99
        shared/browser-scheme.hpp
100
        shared/browser-types.h
101
+       shared/browser-obs-bridge.hpp
102
        shared-apple/browser-bridges.h)
103
 
104
    add_executable(cef-isolation
105
@@ -205,10 +219,14 @@
106
        "shared"
107
        "shared-apple")
108
    
109
-   target_include_directories_system(cef-isolation PUBLIC ${CEF_INCLUDE_DIR})
110
+   target_include_directories_system(cef-isolation
111
+       PUBLIC
112
+           ${CEF_INCLUDE_DIR}
113
+           ${OBS_JANSSON_INCLUDE_DIRS})
114
    
115
    target_link_libraries(cef-isolation
116
        ${CEF_LIBRARIES}
117
+       ${OBS_JANSSON_IMPORT}
118
        ${APPKIT_FRAMEWORK}
119
        ${IOSURFACE_FRAMEWORK})
120
 
121
@@ -216,10 +234,12 @@
122
 
123
 set(cef-bootstrap_SOURCES
124
    cef-bootstrap/main.cpp
125
-   shared/browser-app.cpp)
126
+   shared/browser-app.cpp
127
+   fmt/format.cc)
128
 
129
 set(cef-bootstrap_HEADERS
130
-   shared/browser-app.hpp)
131
+   shared/browser-app.hpp
132
+   fmt/format.h)
133
 
134
 add_executable(cef-bootstrap 
135
    ${cef-bootstrap_SOURCES} 
136
@@ -239,10 +259,14 @@
137
 endif(APPLE AND XCODE)
138
 
139
 target_include_directories(cef-bootstrap PRIVATE "shared")
140
-target_include_directories_system(cef-bootstrap PUBLIC ${CEF_INCLUDE_DIR})
141
+target_include_directories_system(cef-bootstrap
142
+   PUBLIC
143
+       ${CEF_ROOT_DIR}
144
+       ${OBS_JANSSON_INCLUDE_DIRS})
145
 
146
 target_link_libraries(cef-bootstrap
147
-   ${CEF_LIBRARIES})
148
+   ${CEF_LIBRARIES}
149
+   ${OBS_JANSSON_IMPORT})
150
 
151
 if (APPLE)
152
 
153
@@ -250,7 +274,7 @@
154
        OUTPUT_NAME "CEF"
155
        MACOSX_BUNDLE TRUE
156
        BUILD_WITH_INSTALL_RPATH TRUE
157
-       INSTALL_RPATH "@loader_path/../Frameworks"
158
+       INSTALL_RPATH "@executable_path/.."
159
        MACOSX_BUNDLE_BUNDLE_NAME "CEF Helper"
160
        MACOSX_BUNDLE_GUI_IDENTIFIER "org.catchexception.cef.cef-isolation")
161
 
162
@@ -258,7 +282,7 @@
163
        OUTPUT_NAME "CEF Helper"
164
        MACOSX_BUNDLE TRUE
165
        BUILD_WITH_INSTALL_RPATH TRUE
166
-       INSTALL_RPATH "@loader_path/../../../"
167
+       INSTALL_RPATH "@executable_path/../../../.."
168
        MACOSX_BUNDLE_BUNDLE_NAME "CEF Helper"
169
        MACOSX_BUNDLE_GUI_IDENTIFIER "org.catchexception.cef.cef-bootstrap")
170
 
171
obs-studio-0.17.0.tar.xz/plugins/obs-browser/FindCEF.cmake -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/FindCEF.cmake Changed
10
 
1
@@ -11,7 +11,7 @@
2
 
3
 find_library(CEFWRAPPER_LIBRARY
4
    NAMES cef_dll_wrapper libcef_dll_wrapper
5
-   PATHS ${CEF_ROOT_DIR}/build/libcef_dll)
6
+   PATHS ${CEF_ROOT_DIR}/build/libcef_dll ${CEF_ROOT_DIR}/build/libcef_dll_wrapper)
7
 
8
 if (NOT CEF_LIBRARY)
9
    message(FATAL_ERROR "Could not find the CEF shared library" )
10
obs-studio-0.17.0.tar.xz/plugins/obs-browser/README.md -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/README.md Changed
52
 
1
@@ -26,14 +26,24 @@
2
 
3
 ### Register for scene change callbacks
4
 ```
5
-/**
6
- * onSceneChange gets callbacks when the scene is changed
7
- *
8
- * @param {string} sceneName - The name of the scene that was changed to.
9
- */
10
-window.obsstudio.onSceneChange = function(sceneName) {
11
-   
12
-};
13
+window.addEventListener('obsSceneChanged', function(evt) {
14
+   var t = document.createTextNode(evt.detail.name);
15
+    document.body.appendChild(t);
16
+});
17
+```
18
+#### Other events that are available
19
+* obsStreamingStarting
20
+* obsStreamingStarted
21
+* obsStreamingStopping
22
+* obsStreamingStopped
23
+* obsRecordingStarting
24
+* obsRecordingStarted
25
+* obsRecordingStopping
26
+* obsRecordingStopped
27
+
28
+### Get the current scene
29
+```
30
+window.obsstudio.getCurrentScene(function(data) {console.log(data);});
31
 ```
32
 
33
 ## Building on OSX
34
@@ -41,7 +51,7 @@
35
 ### Building CEF
36
 #### Getting
37
 *  Download CEF Mac 64 from [https://cefbuilds.com/](https://cefbuilds.com/)
38
-  *  At the time of writing this I used build 2704
39
+  *  At the time of writing this I used build 2883
40
 *  Extract and cd into the folder
41
 
42
 #### Setting Up Project
43
@@ -70,7 +80,7 @@
44
 echo "add_subdirectory(obs-browser)" >> ./plugins/CMakeLists.txt
45
 mkdir build
46
 cd ./build
47
-cmake -D CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake -D CEF_ROOT_DIR=/Users/username/Development/cef_binary_3.2704.1434.gec3e9ed_macosx64 -G Xcode ..
48
+cmake -D CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake -D CEF_ROOT_DIR=/Users/username/Development/cef_binary_3.2883.1540.gedbfb20_macosx64 -D BUILD_BROWSER=yes -G Xcode ..
49
 open obs-studio.xcodeproj/
50
 ```
51
 
52
obs-studio-17.0.1.tar.xz/plugins/obs-browser/cef-isolation/browser-obs-bridge-mac.hpp Added
17
 
1
@@ -0,0 +1,15 @@
2
+#pragma once
3
+
4
+#include "cef-isolation.h"
5
+#include "browser-obs-bridge.hpp"
6
+
7
+class BrowserOBSBridgeMac : public BrowserOBSBridge
8
+{
9
+public:
10
+   BrowserOBSBridgeMac(id<CEFIsolationService> cefIsolationService);
11
+
12
+    const char* GetCurrentSceneJSONData() override;
13
+
14
+private:
15
+   id<CEFIsolationService> cefIsolationService;    
16
+};
17
obs-studio-17.0.1.tar.xz/plugins/obs-browser/cef-isolation/browser-obs-bridge-mac.mm Added
12
 
1
@@ -0,0 +1,10 @@
2
+#include "browser-obs-bridge-mac.hpp"
3
+
4
+BrowserOBSBridgeMac::BrowserOBSBridgeMac(id<CEFIsolationService> cefIsolationService)
5
+: cefIsolationService(cefIsolationService)
6
+{}
7
+
8
+const char* BrowserOBSBridgeMac::GetCurrentSceneJSONData()
9
+{
10
+   return [cefIsolationService getCurrentSceneJSONData];
11
+}
12
obs-studio-0.17.0.tar.xz/plugins/obs-browser/cef-isolation/browser-render-handler.hpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/cef-isolation/browser-render-handler.hpp Changed
9
 
1
@@ -27,7 +27,6 @@
2
 
3
    BrowserRenderHandler(std::shared_ptr<BrowserHandle> &browserHandle);
4
 
5
-
6
 public: /* CefRenderHandler overrides */
7
 
8
    virtual bool GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
9
obs-studio-0.17.0.tar.xz/plugins/obs-browser/cef-isolation/cef-isolated-client.mm -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/cef-isolation/cef-isolated-client.mm Changed
72
 
1
@@ -16,6 +16,7 @@
2
  ******************************************************************************/
3
 
4
 #import <Cocoa/Cocoa.h>
5
+#import <Foundation/Foundation.h>
6
 
7
 #include <include/cef_app.h>
8
 #include <include/cef_browser.h>
9
@@ -35,6 +36,8 @@
10
 
11
 #import "cef-isolated-client.h"
12
 
13
+#import "browser-obs-bridge-mac.hpp"
14
+
15
 @implementation CEFIsolatedClient
16
 
17
 - (id)init
18
@@ -73,6 +76,8 @@
19
        new BrowserHandle(browserSettings.width,
20
            browserSettings.height, _server));
21
 
22
+   BrowserOBSBridge *browserOBSBridge = new BrowserOBSBridgeMac(_server);
23
+
24
    sync_on_cef_ui(^{
25
 
26
        CefRefPtr<BrowserRenderHandler> browserRenderHandler =
27
@@ -82,7 +87,7 @@
28
                new BrowserLoadHandler(std::string([browserSettings.css UTF8String]));
29
 
30
        CefRefPtr<BrowserClient> browserClient =
31
-               new BrowserClient(browserRenderHandler.get(),loadHandler);
32
+               new BrowserClient(browserRenderHandler.get(),loadHandler, browserOBSBridge);
33
 
34
        CefWindowInfo windowInfo;
35
        windowInfo.view = nullptr;
36
@@ -286,13 +291,7 @@
37
                return;
38
            }
39
 
40
-           host->HandleKeyEventBeforeTextInputClient(nsEvent);
41
-
42
-           NSTextInputContext *inputContext =
43
-                   host->GetNSTextInputContext();
44
-           [inputContext handleEvent:nsEvent];
45
-
46
-           host->HandleKeyEventAfterTextInputClient(nsEvent);
47
+           host->SendKeyEvent(keyEvent);
48
        }
49
     }];
50
 }
51
@@ -335,7 +334,20 @@
52
      }];
53
 }
54
 
55
+-(void)dispatchJSEvent:(const char *)eventName data:(const char *)jsonString
56
+{
57
+   [self sendEventToAllBrowsers:^(SharedBrowserHandle browserHandle)
58
+   {
59
+       CefRefPtr<CefBrowser> browser = browserHandle->GetBrowser();
60
+
61
+       CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("DispatchJSEvent");
62
+       CefRefPtr<CefListValue> args = msg->GetArgumentList();
63
+       args->SetString(0, eventName);
64
+       args->SetString(1, jsonString);
65
 
66
+       browser->SendProcessMessage(PID_RENDERER, msg);
67
+   }];
68
+}
69
 
70
 - (void)destroyBrowser:(const int)browserIdentifier {
71
    if (map.count(browserIdentifier) == 1) {
72
obs-studio-17.0.1.tar.xz/plugins/obs-browser/fmt Added
2
 
1
+(directory)
2
obs-studio-17.0.1.tar.xz/plugins/obs-browser/fmt/format.cc Added
937
 
1
@@ -0,0 +1,935 @@
2
+/*
3
+ Formatting library for C++
4
+
5
+ Copyright (c) 2012 - 2016, Victor Zverovich
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are met:
10
+
11
+ 1. Redistributions of source code must retain the above copyright notice, this
12
+    list of conditions and the following disclaimer.
13
+ 2. Redistributions in binary form must reproduce the above copyright notice,
14
+    this list of conditions and the following disclaimer in the documentation
15
+    and/or other materials provided with the distribution.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+#include "format.h"
30
+
31
+#include <string.h>
32
+
33
+#include <cctype>
34
+#include <cerrno>
35
+#include <climits>
36
+#include <cmath>
37
+#include <cstdarg>
38
+#include <cstddef>  // for std::ptrdiff_t
39
+
40
+#if defined(_WIN32) && defined(__MINGW32__)
41
+# include <cstring>
42
+#endif
43
+
44
+#if FMT_USE_WINDOWS_H
45
+# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
46
+#  include <windows.h>
47
+# else
48
+#  define NOMINMAX
49
+#  include <windows.h>
50
+#  undef NOMINMAX
51
+# endif
52
+#endif
53
+
54
+using fmt::internal::Arg;
55
+
56
+#if FMT_EXCEPTIONS
57
+# define FMT_TRY try
58
+# define FMT_CATCH(x) catch (x)
59
+#else
60
+# define FMT_TRY if (true)
61
+# define FMT_CATCH(x) if (false)
62
+#endif
63
+
64
+#ifdef _MSC_VER
65
+# pragma warning(push)
66
+# pragma warning(disable: 4127)  // conditional expression is constant
67
+# pragma warning(disable: 4702)  // unreachable code
68
+// Disable deprecation warning for strerror. The latter is not called but
69
+// MSVC fails to detect it.
70
+# pragma warning(disable: 4996)
71
+#endif
72
+
73
+// Dummy implementations of strerror_r and strerror_s called if corresponding
74
+// system functions are not available.
75
+static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
76
+  return fmt::internal::Null<>();
77
+}
78
+static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
79
+  return fmt::internal::Null<>();
80
+}
81
+
82
+namespace fmt {
83
+namespace {
84
+
85
+#ifndef _MSC_VER
86
+# define FMT_SNPRINTF snprintf
87
+#else  // _MSC_VER
88
+inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
89
+  va_list args;
90
+  va_start(args, format);
91
+  int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
92
+  va_end(args);
93
+  return result;
94
+}
95
+# define FMT_SNPRINTF fmt_snprintf
96
+#endif  // _MSC_VER
97
+
98
+#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
99
+# define FMT_SWPRINTF snwprintf
100
+#else
101
+# define FMT_SWPRINTF swprintf
102
+#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
103
+
104
+// Checks if a value fits in int - used to avoid warnings about comparing
105
+// signed and unsigned integers.
106
+template <bool IsSigned>
107
+struct IntChecker {
108
+  template <typename T>
109
+  static bool fits_in_int(T value) {
110
+    unsigned max = INT_MAX;
111
+    return value <= max;
112
+  }
113
+  static bool fits_in_int(bool) { return true; }
114
+};
115
+
116
+template <>
117
+struct IntChecker<true> {
118
+  template <typename T>
119
+  static bool fits_in_int(T value) {
120
+    return value >= INT_MIN && value <= INT_MAX;
121
+  }
122
+  static bool fits_in_int(int) { return true; }
123
+};
124
+
125
+const char RESET_COLOR[] = "\x1b[0m";
126
+
127
+typedef void (*FormatFunc)(Writer &, int, StringRef);
128
+
129
+// Portable thread-safe version of strerror.
130
+// Sets buffer to point to a string describing the error code.
131
+// This can be either a pointer to a string stored in buffer,
132
+// or a pointer to some static immutable string.
133
+// Returns one of the following values:
134
+//   0      - success
135
+//   ERANGE - buffer is not large enough to store the error message
136
+//   other  - failure
137
+// Buffer should be at least of size 1.
138
+int safe_strerror(
139
+    int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
140
+  FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
141
+
142
+  class StrError {
143
+   private:
144
+    int error_code_;
145
+    char *&buffer_;
146
+    std::size_t buffer_size_;
147
+
148
+    // A noop assignment operator to avoid bogus warnings.
149
+    void operator=(const StrError &) {}
150
+
151
+    // Handle the result of XSI-compliant version of strerror_r.
152
+    int handle(int result) {
153
+      // glibc versions before 2.13 return result in errno.
154
+      return result == -1 ? errno : result;
155
+    }
156
+
157
+    // Handle the result of GNU-specific version of strerror_r.
158
+    int handle(char *message) {
159
+      // If the buffer is full then the message is probably truncated.
160
+      if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
161
+        return ERANGE;
162
+      buffer_ = message;
163
+      return 0;
164
+    }
165
+
166
+    // Handle the case when strerror_r is not available.
167
+    int handle(internal::Null<>) {
168
+      return fallback(strerror_s(buffer_, buffer_size_, error_code_));
169
+    }
170
+
171
+    // Fallback to strerror_s when strerror_r is not available.
172
+    int fallback(int result) {
173
+      // If the buffer is full then the message is probably truncated.
174
+      return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
175
+            ERANGE : result;
176
+    }
177
+
178
+    // Fallback to strerror if strerror_r and strerror_s are not available.
179
+    int fallback(internal::Null<>) {
180
+      errno = 0;
181
+      buffer_ = strerror(error_code_);
182
+      return errno;
183
+    }
184
+
185
+   public:
186
+    StrError(int err_code, char *&buf, std::size_t buf_size)
187
+      : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
188
+
189
+    int run() {
190
+      strerror_r(0, 0, "");  // Suppress a warning about unused strerror_r.
191
+      return handle(strerror_r(error_code_, buffer_, buffer_size_));
192
+    }
193
+  };
194
+  return StrError(error_code, buffer, buffer_size).run();
195
+}
196
+
197
+void format_error_code(Writer &out, int error_code,
198
+                       StringRef message) FMT_NOEXCEPT {
199
+  // Report error code making sure that the output fits into
200
+  // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
201
+  // bad_alloc.
202
+  out.clear();
203
+  static const char SEP[] = ": ";
204
+  static const char ERROR_STR[] = "error ";
205
+  // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
206
+  std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
207
+  typedef internal::IntTraits<int>::MainType MainType;
208
+  MainType abs_value = static_cast<MainType>(error_code);
209
+  if (internal::is_negative(error_code)) {
210
+    abs_value = 0 - abs_value;
211
+    ++error_code_size;
212
+  }
213
+  error_code_size += internal::count_digits(abs_value);
214
+  if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
215
+    out << message << SEP;
216
+  out << ERROR_STR << error_code;
217
+  assert(out.size() <= internal::INLINE_BUFFER_SIZE);
218
+}
219
+
220
+void report_error(FormatFunc func, int error_code,
221
+                  StringRef message) FMT_NOEXCEPT {
222
+  MemoryWriter full_message;
223
+  func(full_message, error_code, message);
224
+  // Use Writer::data instead of Writer::c_str to avoid potential memory
225
+  // allocation.
226
+  std::fwrite(full_message.data(), full_message.size(), 1, stderr);
227
+  std::fputc('\n', stderr);
228
+}
229
+
230
+// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
231
+class IsZeroInt : public ArgVisitor<IsZeroInt, bool> {
232
+ public:
233
+  template <typename T>
234
+  bool visit_any_int(T value) { return value == 0; }
235
+};
236
+
237
+// Checks if an argument is a valid printf width specifier and sets
238
+// left alignment if it is negative.
239
+class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
240
+ private:
241
+  FormatSpec &spec_;
242
+
243
+  FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
244
+
245
+ public:
246
+  explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
247
+
248
+  void report_unhandled_arg() {
249
+    FMT_THROW(FormatError("width is not integer"));
250
+  }
251
+
252
+  template <typename T>
253
+  unsigned visit_any_int(T value) {
254
+    typedef typename internal::IntTraits<T>::MainType UnsignedType;
255
+    UnsignedType width = static_cast<UnsignedType>(value);
256
+    if (internal::is_negative(value)) {
257
+      spec_.align_ = ALIGN_LEFT;
258
+      width = 0 - width;
259
+    }
260
+    if (width > INT_MAX)
261
+      FMT_THROW(FormatError("number is too big"));
262
+    return static_cast<unsigned>(width);
263
+  }
264
+};
265
+
266
+class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> {
267
+ public:
268
+  void report_unhandled_arg() {
269
+    FMT_THROW(FormatError("precision is not integer"));
270
+  }
271
+
272
+  template <typename T>
273
+  int visit_any_int(T value) {
274
+    if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
275
+      FMT_THROW(FormatError("number is too big"));
276
+    return static_cast<int>(value);
277
+  }
278
+};
279
+
280
+template <typename T, typename U>
281
+struct is_same {
282
+  enum { value = 0 };
283
+};
284
+
285
+template <typename T>
286
+struct is_same<T, T> {
287
+  enum { value = 1 };
288
+};
289
+
290
+// An argument visitor that converts an integer argument to T for printf,
291
+// if T is an integral type. If T is void, the argument is converted to
292
+// corresponding signed or unsigned type depending on the type specifier:
293
+// 'd' and 'i' - signed, other - unsigned)
294
+template <typename T = void>
295
+class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
296
+ private:
297
+  internal::Arg &arg_;
298
+  wchar_t type_;
299
+
300
+  FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
301
+
302
+ public:
303
+  ArgConverter(internal::Arg &arg, wchar_t type)
304
+    : arg_(arg), type_(type) {}
305
+
306
+  void visit_bool(bool value) {
307
+    if (type_ != 's')
308
+      visit_any_int(value);
309
+  }
310
+
311
+  template <typename U>
312
+  void visit_any_int(U value) {
313
+    bool is_signed = type_ == 'd' || type_ == 'i';
314
+    using internal::Arg;
315
+    typedef typename internal::Conditional<
316
+        is_same<T, void>::value, U, T>::type TargetType;
317
+    if (sizeof(TargetType) <= sizeof(int)) {
318
+      // Extra casts are used to silence warnings.
319
+      if (is_signed) {
320
+        arg_.type = Arg::INT;
321
+        arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
322
+      } else {
323
+        arg_.type = Arg::UINT;
324
+        typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
325
+        arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
326
+      }
327
+    } else {
328
+      if (is_signed) {
329
+        arg_.type = Arg::LONG_LONG;
330
+        // glibc's printf doesn't sign extend arguments of smaller types:
331
+        //   std::printf("%lld", -42);  // prints "4294967254"
332
+        // but we don't have to do the same because it's a UB.
333
+        arg_.long_long_value = static_cast<LongLong>(value);
334
+      } else {
335
+        arg_.type = Arg::ULONG_LONG;
336
+        arg_.ulong_long_value =
337
+            static_cast<typename internal::MakeUnsigned<U>::Type>(value);
338
+      }
339
+    }
340
+  }
341
+};
342
+
343
+// Converts an integer argument to char for printf.
344
+class CharConverter : public ArgVisitor<CharConverter, void> {
345
+ private:
346
+  internal::Arg &arg_;
347
+
348
+  FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
349
+
350
+ public:
351
+  explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
352
+
353
+  template <typename T>
354
+  void visit_any_int(T value) {
355
+    arg_.type = internal::Arg::CHAR;
356
+    arg_.int_value = static_cast<char>(value);
357
+  }
358
+};
359
+}  // namespace
360
+
361
+namespace internal {
362
+
363
+template <typename Char>
364
+class PrintfArgFormatter :
365
+    public ArgFormatterBase<PrintfArgFormatter<Char>, Char> {
366
+
367
+  void write_null_pointer() {
368
+    this->spec().type_ = 0;
369
+    this->write("(nil)");
370
+  }
371
+
372
+  typedef ArgFormatterBase<PrintfArgFormatter<Char>, Char> Base;
373
+
374
+ public:
375
+  PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
376
+  : ArgFormatterBase<PrintfArgFormatter<Char>, Char>(w, s) {}
377
+
378
+  void visit_bool(bool value) {
379
+    FormatSpec &fmt_spec = this->spec();
380
+    if (fmt_spec.type_ != 's')
381
+      return this->visit_any_int(value);
382
+    fmt_spec.type_ = 0;
383
+    this->write(value);
384
+  }
385
+
386
+  void visit_char(int value) {
387
+    const FormatSpec &fmt_spec = this->spec();
388
+    BasicWriter<Char> &w = this->writer();
389
+    if (fmt_spec.type_ && fmt_spec.type_ != 'c')
390
+      w.write_int(value, fmt_spec);
391
+    typedef typename BasicWriter<Char>::CharPtr CharPtr;
392
+    CharPtr out = CharPtr();
393
+    if (fmt_spec.width_ > 1) {
394
+      Char fill = ' ';
395
+      out = w.grow_buffer(fmt_spec.width_);
396
+      if (fmt_spec.align_ != ALIGN_LEFT) {
397
+        std::fill_n(out, fmt_spec.width_ - 1, fill);
398
+        out += fmt_spec.width_ - 1;
399
+      } else {
400
+        std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
401
+      }
402
+    } else {
403
+      out = w.grow_buffer(1);
404
+    }
405
+    *out = static_cast<Char>(value);
406
+  }
407
+
408
+  void visit_cstring(const char *value) {
409
+    if (value)
410
+      Base::visit_cstring(value);
411
+    else if (this->spec().type_ == 'p')
412
+      write_null_pointer();
413
+    else
414
+      this->write("(null)");
415
+  }
416
+
417
+  void visit_pointer(const void *value) {
418
+    if (value)
419
+      return Base::visit_pointer(value);
420
+    this->spec().type_ = 0;
421
+    write_null_pointer();
422
+  }
423
+
424
+  void visit_custom(Arg::CustomValue c) {
425
+    BasicFormatter<Char> formatter(ArgList(), this->writer());
426
+    const Char format_str[] = {'}', 0};
427
+    const Char *format = format_str;
428
+    c.format(&formatter, c.value, &format);
429
+  }
430
+};
431
+}  // namespace internal
432
+}  // namespace fmt
433
+
434
+FMT_FUNC void fmt::SystemError::init(
435
+    int err_code, CStringRef format_str, ArgList args) {
436
+  error_code_ = err_code;
437
+  MemoryWriter w;
438
+  internal::format_system_error(w, err_code, format(format_str, args));
439
+  std::runtime_error &base = *this;
440
+  base = std::runtime_error(w.str());
441
+}
442
+
443
+template <typename T>
444
+int fmt::internal::CharTraits<char>::format_float(
445
+    char *buffer, std::size_t size, const char *format,
446
+    unsigned width, int precision, T value) {
447
+  if (width == 0) {
448
+    return precision < 0 ?
449
+        FMT_SNPRINTF(buffer, size, format, value) :
450
+        FMT_SNPRINTF(buffer, size, format, precision, value);
451
+  }
452
+  return precision < 0 ?
453
+      FMT_SNPRINTF(buffer, size, format, width, value) :
454
+      FMT_SNPRINTF(buffer, size, format, width, precision, value);
455
+}
456
+
457
+template <typename T>
458
+int fmt::internal::CharTraits<wchar_t>::format_float(
459
+    wchar_t *buffer, std::size_t size, const wchar_t *format,
460
+    unsigned width, int precision, T value) {
461
+  if (width == 0) {
462
+    return precision < 0 ?
463
+        FMT_SWPRINTF(buffer, size, format, value) :
464
+        FMT_SWPRINTF(buffer, size, format, precision, value);
465
+  }
466
+  return precision < 0 ?
467
+      FMT_SWPRINTF(buffer, size, format, width, value) :
468
+      FMT_SWPRINTF(buffer, size, format, width, precision, value);
469
+}
470
+
471
+template <typename T>
472
+const char fmt::internal::BasicData<T>::DIGITS[] =
473
+    "0001020304050607080910111213141516171819"
474
+    "2021222324252627282930313233343536373839"
475
+    "4041424344454647484950515253545556575859"
476
+    "6061626364656667686970717273747576777879"
477
+    "8081828384858687888990919293949596979899";
478
+
479
+#define FMT_POWERS_OF_10(factor) \
480
+  factor * 10, \
481
+  factor * 100, \
482
+  factor * 1000, \
483
+  factor * 10000, \
484
+  factor * 100000, \
485
+  factor * 1000000, \
486
+  factor * 10000000, \
487
+  factor * 100000000, \
488
+  factor * 1000000000
489
+
490
+template <typename T>
491
+const uint32_t fmt::internal::BasicData<T>::POWERS_OF_10_32[] = {
492
+  0, FMT_POWERS_OF_10(1)
493
+};
494
+
495
+template <typename T>
496
+const uint64_t fmt::internal::BasicData<T>::POWERS_OF_10_64[] = {
497
+  0,
498
+  FMT_POWERS_OF_10(1),
499
+  FMT_POWERS_OF_10(fmt::ULongLong(1000000000)),
500
+  // Multiply several constants instead of using a single long long constant
501
+  // to avoid warnings about C++98 not supporting long long.
502
+  fmt::ULongLong(1000000000) * fmt::ULongLong(1000000000) * 10
503
+};
504
+
505
+FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
506
+  (void)type;
507
+  if (std::isprint(static_cast<unsigned char>(code))) {
508
+    FMT_THROW(fmt::FormatError(
509
+        fmt::format("unknown format code '{}' for {}", code, type)));
510
+  }
511
+  FMT_THROW(fmt::FormatError(
512
+      fmt::format("unknown format code '\\x{:02x}' for {}",
513
+        static_cast<unsigned>(code), type)));
514
+}
515
+
516
+#if FMT_USE_WINDOWS_H
517
+
518
+FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) {
519
+  static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
520
+  if (s.size() > INT_MAX)
521
+    FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
522
+  int s_size = static_cast<int>(s.size());
523
+  int length = MultiByteToWideChar(
524
+      CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0);
525
+  if (length == 0)
526
+    FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
527
+  buffer_.resize(length + 1);
528
+  length = MultiByteToWideChar(
529
+    CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
530
+  if (length == 0)
531
+    FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
532
+  buffer_[length] = 0;
533
+}
534
+
535
+FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
536
+  if (int error_code = convert(s)) {
537
+    FMT_THROW(WindowsError(error_code,
538
+        "cannot convert string from UTF-16 to UTF-8"));
539
+  }
540
+}
541
+
542
+FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) {
543
+  if (s.size() > INT_MAX)
544
+    return ERROR_INVALID_PARAMETER;
545
+  int s_size = static_cast<int>(s.size());
546
+  int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0);
547
+  if (length == 0)
548
+    return GetLastError();
549
+  buffer_.resize(length + 1);
550
+  length = WideCharToMultiByte(
551
+    CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0);
552
+  if (length == 0)
553
+    return GetLastError();
554
+  buffer_[length] = 0;
555
+  return 0;
556
+}
557
+
558
+FMT_FUNC void fmt::WindowsError::init(
559
+    int err_code, CStringRef format_str, ArgList args) {
560
+  error_code_ = err_code;
561
+  MemoryWriter w;
562
+  internal::format_windows_error(w, err_code, format(format_str, args));
563
+  std::runtime_error &base = *this;
564
+  base = std::runtime_error(w.str());
565
+}
566
+
567
+FMT_FUNC void fmt::internal::format_windows_error(
568
+    fmt::Writer &out, int error_code,
569
+    fmt::StringRef message) FMT_NOEXCEPT {
570
+  FMT_TRY {
571
+    MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
572
+    buffer.resize(INLINE_BUFFER_SIZE);
573
+    for (;;) {
574
+      wchar_t *system_message = &buffer[0];
575
+      int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
576
+                                  0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
577
+                                  system_message, static_cast<uint32_t>(buffer.size()), 0);
578
+      if (result != 0) {
579
+        UTF16ToUTF8 utf8_message;
580
+        if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
581
+          out << message << ": " << utf8_message;
582
+          return;
583
+        }
584
+        break;
585
+      }
586
+      if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
587
+        break;  // Can't get error message, report error code instead.
588
+      buffer.resize(buffer.size() * 2);
589
+    }
590
+  } FMT_CATCH(...) {}
591
+  fmt::format_error_code(out, error_code, message);  // 'fmt::' is for bcc32.
592
+}
593
+
594
+#endif  // FMT_USE_WINDOWS_H
595
+
596
+FMT_FUNC void fmt::internal::format_system_error(
597
+    fmt::Writer &out, int error_code,
598
+    fmt::StringRef message) FMT_NOEXCEPT {
599
+  FMT_TRY {
600
+    MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
601
+    buffer.resize(INLINE_BUFFER_SIZE);
602
+    for (;;) {
603
+      char *system_message = &buffer[0];
604
+      int result = safe_strerror(error_code, system_message, buffer.size());
605
+      if (result == 0) {
606
+        out << message << ": " << system_message;
607
+        return;
608
+      }
609
+      if (result != ERANGE)
610
+        break;  // Can't get error message, report error code instead.
611
+      buffer.resize(buffer.size() * 2);
612
+    }
613
+  } FMT_CATCH(...) {}
614
+  fmt::format_error_code(out, error_code, message);  // 'fmt::' is for bcc32.
615
+}
616
+
617
+template <typename Char>
618
+void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
619
+  if (!map_.empty())
620
+    return;
621
+  typedef internal::NamedArg<Char> NamedArg;
622
+  const NamedArg *named_arg = 0;
623
+  bool use_values =
624
+      args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
625
+  if (use_values) {
626
+    for (unsigned i = 0;/*nothing*/; ++i) {
627
+      internal::Arg::Type arg_type = args.type(i);
628
+      switch (arg_type) {
629
+      case internal::Arg::NONE:
630
+        return;
631
+      case internal::Arg::NAMED_ARG:
632
+        named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
633
+        map_.push_back(Pair(named_arg->name, *named_arg));
634
+        break;
635
+      default:
636
+        /*nothing*/;
637
+      }
638
+    }
639
+    return;
640
+  }
641
+  for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
642
+    internal::Arg::Type arg_type = args.type(i);
643
+    if (arg_type == internal::Arg::NAMED_ARG) {
644
+      named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
645
+      map_.push_back(Pair(named_arg->name, *named_arg));
646
+    }
647
+  }
648
+  for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
649
+    switch (args.args_[i].type) {
650
+    case internal::Arg::NONE:
651
+      return;
652
+    case internal::Arg::NAMED_ARG:
653
+      named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
654
+      map_.push_back(Pair(named_arg->name, *named_arg));
655
+      break;
656
+    default:
657
+      /*nothing*/;
658
+    }
659
+  }
660
+}
661
+
662
+template <typename Char>
663
+void fmt::internal::FixedBuffer<Char>::grow(std::size_t) {
664
+  FMT_THROW(std::runtime_error("buffer overflow"));
665
+}
666
+
667
+FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
668
+    unsigned arg_index, const char *&error) {
669
+  Arg arg = args_[arg_index];
670
+  switch (arg.type) {
671
+  case Arg::NONE:
672
+    error = "argument index out of range";
673
+    break;
674
+  case Arg::NAMED_ARG:
675
+    arg = *static_cast<const internal::Arg*>(arg.pointer);
676
+    break;
677
+  default:
678
+    /*nothing*/;
679
+  }
680
+  return arg;
681
+}
682
+
683
+template <typename Char>
684
+void fmt::internal::PrintfFormatter<Char>::parse_flags(
685
+    FormatSpec &spec, const Char *&s) {
686
+  for (;;) {
687
+    switch (*s++) {
688
+      case '-':
689
+        spec.align_ = ALIGN_LEFT;
690
+        break;
691
+      case '+':
692
+        spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
693
+        break;
694
+      case '0':
695
+        spec.fill_ = '0';
696
+        break;
697
+      case ' ':
698
+        spec.flags_ |= SIGN_FLAG;
699
+        break;
700
+      case '#':
701
+        spec.flags_ |= HASH_FLAG;
702
+        break;
703
+      default:
704
+        --s;
705
+        return;
706
+    }
707
+  }
708
+}
709
+
710
+template <typename Char>
711
+Arg fmt::internal::PrintfFormatter<Char>::get_arg(
712
+    const Char *s, unsigned arg_index) {
713
+  (void)s;
714
+  const char *error = 0;
715
+  Arg arg = arg_index == UINT_MAX ?
716
+    next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
717
+  if (error)
718
+    FMT_THROW(FormatError(!*s ? "invalid format string" : error));
719
+  return arg;
720
+}
721
+
722
+template <typename Char>
723
+unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
724
+  const Char *&s, FormatSpec &spec) {
725
+  unsigned arg_index = UINT_MAX;
726
+  Char c = *s;
727
+  if (c >= '0' && c <= '9') {
728
+    // Parse an argument index (if followed by '$') or a width possibly
729
+    // preceded with '0' flag(s).
730
+    unsigned value = parse_nonnegative_int(s);
731
+    if (*s == '$') {  // value is an argument index
732
+      ++s;
733
+      arg_index = value;
734
+    } else {
735
+      if (c == '0')
736
+        spec.fill_ = '0';
737
+      if (value != 0) {
738
+        // Nonzero value means that we parsed width and don't need to
739
+        // parse it or flags again, so return now.
740
+        spec.width_ = value;
741
+        return arg_index;
742
+      }
743
+    }
744
+  }
745
+  parse_flags(spec, s);
746
+  // Parse width.
747
+  if (*s >= '0' && *s <= '9') {
748
+    spec.width_ = parse_nonnegative_int(s);
749
+  } else if (*s == '*') {
750
+    ++s;
751
+    spec.width_ = WidthHandler(spec).visit(get_arg(s));
752
+  }
753
+  return arg_index;
754
+}
755
+
756
+template <typename Char>
757
+void fmt::internal::PrintfFormatter<Char>::format(
758
+    BasicWriter<Char> &writer, BasicCStringRef<Char> format_str) {
759
+  const Char *start = format_str.c_str();
760
+  const Char *s = start;
761
+  while (*s) {
762
+    Char c = *s++;
763
+    if (c != '%') continue;
764
+    if (*s == c) {
765
+      write(writer, start, s);
766
+      start = ++s;
767
+      continue;
768
+    }
769
+    write(writer, start, s - 1);
770
+
771
+    FormatSpec spec;
772
+    spec.align_ = ALIGN_RIGHT;
773
+
774
+    // Parse argument index, flags and width.
775
+    unsigned arg_index = parse_header(s, spec);
776
+
777
+    // Parse precision.
778
+    if (*s == '.') {
779
+      ++s;
780
+      if ('0' <= *s && *s <= '9') {
781
+        spec.precision_ = static_cast<int>(parse_nonnegative_int(s));
782
+      } else if (*s == '*') {
783
+        ++s;
784
+        spec.precision_ = PrecisionHandler().visit(get_arg(s));
785
+      }
786
+    }
787
+
788
+    Arg arg = get_arg(s, arg_index);
789
+    if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg))
790
+      spec.flags_ &= ~to_unsigned<int>(HASH_FLAG);
791
+    if (spec.fill_ == '0') {
792
+      if (arg.type <= Arg::LAST_NUMERIC_TYPE)
793
+        spec.align_ = ALIGN_NUMERIC;
794
+      else
795
+        spec.fill_ = ' ';  // Ignore '0' flag for non-numeric types.
796
+    }
797
+
798
+    // Parse length and convert the argument to the required type.
799
+    switch (*s++) {
800
+    case 'h':
801
+      if (*s == 'h')
802
+        ArgConverter<signed char>(arg, *++s).visit(arg);
803
+      else
804
+        ArgConverter<short>(arg, *s).visit(arg);
805
+      break;
806
+    case 'l':
807
+      if (*s == 'l')
808
+        ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
809
+      else
810
+        ArgConverter<long>(arg, *s).visit(arg);
811
+      break;
812
+    case 'j':
813
+      ArgConverter<intmax_t>(arg, *s).visit(arg);
814
+      break;
815
+    case 'z':
816
+      ArgConverter<std::size_t>(arg, *s).visit(arg);
817
+      break;
818
+    case 't':
819
+      ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
820
+      break;
821
+    case 'L':
822
+      // printf produces garbage when 'L' is omitted for long double, no
823
+      // need to do the same.
824
+      break;
825
+    default:
826
+      --s;
827
+      ArgConverter<void>(arg, *s).visit(arg);
828
+    }
829
+
830
+    // Parse type.
831
+    if (!*s)
832
+      FMT_THROW(FormatError("invalid format string"));
833
+    spec.type_ = static_cast<char>(*s++);
834
+    if (arg.type <= Arg::LAST_INTEGER_TYPE) {
835
+      // Normalize type.
836
+      switch (spec.type_) {
837
+      case 'i': case 'u':
838
+        spec.type_ = 'd';
839
+        break;
840
+      case 'c':
841
+        // TODO: handle wchar_t
842
+        CharConverter(arg).visit(arg);
843
+        break;
844
+      }
845
+    }
846
+
847
+    start = s;
848
+
849
+    // Format argument.
850
+    internal::PrintfArgFormatter<Char>(writer, spec).visit(arg);
851
+  }
852
+  write(writer, start, s);
853
+}
854
+
855
+FMT_FUNC void fmt::report_system_error(
856
+    int error_code, fmt::StringRef message) FMT_NOEXCEPT {
857
+  // 'fmt::' is for bcc32.
858
+  fmt::report_error(internal::format_system_error, error_code, message);
859
+}
860
+
861
+#if FMT_USE_WINDOWS_H
862
+FMT_FUNC void fmt::report_windows_error(
863
+    int error_code, fmt::StringRef message) FMT_NOEXCEPT {
864
+  // 'fmt::' is for bcc32.
865
+  fmt::report_error(internal::format_windows_error, error_code, message);
866
+}
867
+#endif
868
+
869
+FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) {
870
+  MemoryWriter w;
871
+  w.write(format_str, args);
872
+  std::fwrite(w.data(), 1, w.size(), f);
873
+}
874
+
875
+FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) {
876
+  print(stdout, format_str, args);
877
+}
878
+
879
+FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) {
880
+  char escape[] = "\x1b[30m";
881
+  escape[3] = static_cast<char>('0' + c);
882
+  std::fputs(escape, stdout);
883
+  print(format, args);
884
+  std::fputs(RESET_COLOR, stdout);
885
+}
886
+
887
+FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
888
+  MemoryWriter w;
889
+  printf(w, format, args);
890
+  std::size_t size = w.size();
891
+  return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
892
+}
893
+
894
+#ifndef FMT_HEADER_ONLY
895
+
896
+template struct fmt::internal::BasicData<void>;
897
+
898
+// Explicit instantiations for char.
899
+
900
+template void fmt::internal::FixedBuffer<char>::grow(std::size_t);
901
+
902
+template void fmt::internal::ArgMap<char>::init(const fmt::ArgList &args);
903
+
904
+template void fmt::internal::PrintfFormatter<char>::format(
905
+  BasicWriter<char> &writer, CStringRef format);
906
+
907
+template int fmt::internal::CharTraits<char>::format_float(
908
+    char *buffer, std::size_t size, const char *format,
909
+    unsigned width, int precision, double value);
910
+
911
+template int fmt::internal::CharTraits<char>::format_float(
912
+    char *buffer, std::size_t size, const char *format,
913
+    unsigned width, int precision, long double value);
914
+
915
+// Explicit instantiations for wchar_t.
916
+
917
+template void fmt::internal::FixedBuffer<wchar_t>::grow(std::size_t);
918
+
919
+template void fmt::internal::ArgMap<wchar_t>::init(const fmt::ArgList &args);
920
+
921
+template void fmt::internal::PrintfFormatter<wchar_t>::format(
922
+    BasicWriter<wchar_t> &writer, WCStringRef format);
923
+
924
+template int fmt::internal::CharTraits<wchar_t>::format_float(
925
+    wchar_t *buffer, std::size_t size, const wchar_t *format,
926
+    unsigned width, int precision, double value);
927
+
928
+template int fmt::internal::CharTraits<wchar_t>::format_float(
929
+    wchar_t *buffer, std::size_t size, const wchar_t *format,
930
+    unsigned width, int precision, long double value);
931
+
932
+#endif  // FMT_HEADER_ONLY
933
+
934
+#ifdef _MSC_VER
935
+# pragma warning(pop)
936
+#endif
937
obs-studio-17.0.1.tar.xz/plugins/obs-browser/fmt/format.h Added
3834
 
1
@@ -0,0 +1,3832 @@
2
+/*
3
+ Formatting library for C++
4
+
5
+ Copyright (c) 2012 - 2016, Victor Zverovich
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are met:
10
+
11
+ 1. Redistributions of source code must retain the above copyright notice, this
12
+    list of conditions and the following disclaimer.
13
+ 2. Redistributions in binary form must reproduce the above copyright notice,
14
+    this list of conditions and the following disclaimer in the documentation
15
+    and/or other materials provided with the distribution.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+#ifndef FMT_FORMAT_H_
30
+#define FMT_FORMAT_H_
31
+
32
+#include <cassert>
33
+#include <clocale>
34
+#include <cmath>
35
+#include <cstdio>
36
+#include <cstring>
37
+#include <limits>
38
+#include <memory>
39
+#include <stdexcept>
40
+#include <string>
41
+#include <vector>
42
+#include <utility>
43
+
44
+#ifdef _SECURE_SCL
45
+# define FMT_SECURE_SCL _SECURE_SCL
46
+#else
47
+# define FMT_SECURE_SCL 0
48
+#endif
49
+
50
+#if FMT_SECURE_SCL
51
+# include <iterator>
52
+#endif
53
+
54
+#if defined(_MSC_VER) && _MSC_VER <= 1500
55
+typedef unsigned __int32 uint32_t;
56
+typedef unsigned __int64 uint64_t;
57
+typedef __int64          intmax_t;
58
+#else
59
+#include <stdint.h>
60
+#endif
61
+
62
+#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
63
+# ifdef FMT_EXPORT
64
+#  define FMT_API __declspec(dllexport)
65
+# elif defined(FMT_SHARED)
66
+#  define FMT_API __declspec(dllimport)
67
+# endif
68
+#endif
69
+#ifndef FMT_API
70
+# define FMT_API
71
+#endif
72
+
73
+#ifdef __GNUC__
74
+# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
75
+# define FMT_GCC_EXTENSION __extension__
76
+# if FMT_GCC_VERSION >= 406
77
+#  pragma GCC diagnostic push
78
+// Disable the warning about "long long" which is sometimes reported even
79
+// when using __extension__.
80
+#  pragma GCC diagnostic ignored "-Wlong-long"
81
+// Disable the warning about declaration shadowing because it affects too
82
+// many valid cases.
83
+#  pragma GCC diagnostic ignored "-Wshadow"
84
+// Disable the warning about implicit conversions that may change the sign of
85
+// an integer; silencing it otherwise would require many explicit casts.
86
+#  pragma GCC diagnostic ignored "-Wsign-conversion"
87
+# endif
88
+# if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__
89
+#  define FMT_HAS_GXX_CXX11 1
90
+# endif
91
+#else
92
+# define FMT_GCC_EXTENSION
93
+#endif
94
+
95
+#if defined(__INTEL_COMPILER)
96
+# define FMT_ICC_VERSION __INTEL_COMPILER
97
+#elif defined(__ICL)
98
+# define FMT_ICC_VERSION __ICL
99
+#endif
100
+
101
+#if defined(__clang__) && !defined(FMT_ICC_VERSION)
102
+# pragma clang diagnostic push
103
+# pragma clang diagnostic ignored "-Wdocumentation"
104
+#endif
105
+
106
+#ifdef __GNUC_LIBSTD__
107
+# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
108
+#endif
109
+
110
+#ifdef __has_feature
111
+# define FMT_HAS_FEATURE(x) __has_feature(x)
112
+#else
113
+# define FMT_HAS_FEATURE(x) 0
114
+#endif
115
+
116
+#ifdef __has_builtin
117
+# define FMT_HAS_BUILTIN(x) __has_builtin(x)
118
+#else
119
+# define FMT_HAS_BUILTIN(x) 0
120
+#endif
121
+
122
+#ifdef __has_cpp_attribute
123
+# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
124
+#else
125
+# define FMT_HAS_CPP_ATTRIBUTE(x) 0
126
+#endif
127
+
128
+#ifndef FMT_USE_VARIADIC_TEMPLATES
129
+// Variadic templates are available in GCC since version 4.4
130
+// (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
131
+// since version 2013.
132
+# define FMT_USE_VARIADIC_TEMPLATES \
133
+   (FMT_HAS_FEATURE(cxx_variadic_templates) || \
134
+       (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800)
135
+#endif
136
+
137
+#ifndef FMT_USE_RVALUE_REFERENCES
138
+// Don't use rvalue references when compiling with clang and an old libstdc++
139
+// as the latter doesn't provide std::move.
140
+# if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402
141
+#  define FMT_USE_RVALUE_REFERENCES 0
142
+# else
143
+#  define FMT_USE_RVALUE_REFERENCES \
144
+    (FMT_HAS_FEATURE(cxx_rvalue_references) || \
145
+        (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600)
146
+# endif
147
+#endif
148
+
149
+#if FMT_USE_RVALUE_REFERENCES
150
+# include <utility>  // for std::move
151
+#endif
152
+
153
+// Check if exceptions are disabled.
154
+#if defined(__GNUC__) && !defined(__EXCEPTIONS)
155
+# define FMT_EXCEPTIONS 0
156
+#endif
157
+#if defined(_MSC_VER) && !_HAS_EXCEPTIONS
158
+# define FMT_EXCEPTIONS 0
159
+#endif
160
+#ifndef FMT_EXCEPTIONS
161
+# define FMT_EXCEPTIONS 1
162
+#endif
163
+
164
+#ifndef FMT_THROW
165
+# if FMT_EXCEPTIONS
166
+#  define FMT_THROW(x) throw x
167
+# else
168
+#  define FMT_THROW(x) assert(false)
169
+# endif
170
+#endif
171
+
172
+// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
173
+#ifndef FMT_USE_NOEXCEPT
174
+# define FMT_USE_NOEXCEPT 0
175
+#endif
176
+
177
+#ifndef FMT_NOEXCEPT
178
+# if FMT_EXCEPTIONS
179
+#  if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
180
+    (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \
181
+    _MSC_VER >= 1900
182
+#   define FMT_NOEXCEPT noexcept
183
+#  else
184
+#   define FMT_NOEXCEPT throw()
185
+#  endif
186
+# else
187
+#  define FMT_NOEXCEPT
188
+# endif
189
+#endif
190
+
191
+// A macro to disallow the copy constructor and operator= functions
192
+// This should be used in the private: declarations for a class
193
+#ifndef FMT_USE_DELETED_FUNCTIONS
194
+# define FMT_USE_DELETED_FUNCTIONS 0
195
+#endif
196
+
197
+#if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \
198
+  (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800
199
+# define FMT_DELETED_OR_UNDEFINED  = delete
200
+# define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
201
+    TypeName(const TypeName&) = delete; \
202
+    TypeName& operator=(const TypeName&) = delete
203
+#else
204
+# define FMT_DELETED_OR_UNDEFINED
205
+# define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
206
+    TypeName(const TypeName&); \
207
+    TypeName& operator=(const TypeName&)
208
+#endif
209
+
210
+#ifndef FMT_USE_USER_DEFINED_LITERALS
211
+// All compilers which support UDLs also support variadic templates. This
212
+// makes the fmt::literals implementation easier. However, an explicit check
213
+// for variadic templates is added here just in case.
214
+// For Intel's compiler both it and the system gcc/msc must support UDLs.
215
+# define FMT_USE_USER_DEFINED_LITERALS \
216
+   FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \
217
+   (FMT_HAS_FEATURE(cxx_user_literals) || \
218
+       (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) && \
219
+   (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
220
+#endif
221
+
222
+#ifndef FMT_ASSERT
223
+# define FMT_ASSERT(condition, message) assert((condition) && message)
224
+#endif
225
+
226
+
227
+#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
228
+# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
229
+#endif
230
+
231
+#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
232
+# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
233
+#endif
234
+
235
+// Some compilers masquerade as both MSVC and GCC-likes or 
236
+// otherwise support __builtin_clz and __builtin_clzll, so
237
+// only define FMT_BUILTIN_CLZ using the MSVC intrinsics
238
+// if the clz and clzll builtins are not available.
239
+#if defined(_MSC_VER) && !defined(FMT_BUILTIN_CLZLL)
240
+# include <intrin.h>  // _BitScanReverse, _BitScanReverse64
241
+
242
+namespace fmt {
243
+namespace internal {
244
+# pragma intrinsic(_BitScanReverse)
245
+inline uint32_t clz(uint32_t x) {
246
+  unsigned long r = 0;
247
+  _BitScanReverse(&r, x);
248
+
249
+  assert(x != 0);
250
+  // Static analysis complains about using uninitialized data
251
+  // "r", but the only way that can happen is if "x" is 0, 
252
+  // which the callers guarantee to not happen.
253
+# pragma warning(suppress: 6102)
254
+  return 31 - r;
255
+}
256
+# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
257
+
258
+# ifdef _WIN64
259
+#  pragma intrinsic(_BitScanReverse64)
260
+# endif
261
+
262
+inline uint32_t clzll(uint64_t x) {
263
+  unsigned long r = 0;
264
+# ifdef _WIN64
265
+  _BitScanReverse64(&r, x);
266
+# else
267
+  // Scan the high 32 bits.
268
+  if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
269
+    return 63 - (r + 32);
270
+
271
+  // Scan the low 32 bits.
272
+  _BitScanReverse(&r, static_cast<uint32_t>(x));
273
+# endif
274
+
275
+  assert(x != 0);
276
+  // Static analysis complains about using uninitialized data
277
+  // "r", but the only way that can happen is if "x" is 0, 
278
+  // which the callers guarantee to not happen.
279
+# pragma warning(suppress: 6102)
280
+  return 63 - r;
281
+}
282
+# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
283
+}
284
+}
285
+#endif
286
+
287
+namespace fmt {
288
+namespace internal {
289
+struct DummyInt {
290
+  int data[2];
291
+  operator int() const { return 0; }
292
+};
293
+typedef std::numeric_limits<fmt::internal::DummyInt> FPUtil;
294
+
295
+// Dummy implementations of system functions such as signbit and ecvt called
296
+// if the latter are not available.
297
+inline DummyInt signbit(...) { return DummyInt(); }
298
+inline DummyInt _ecvt_s(...) { return DummyInt(); }
299
+inline DummyInt isinf(...) { return DummyInt(); }
300
+inline DummyInt _finite(...) { return DummyInt(); }
301
+inline DummyInt isnan(...) { return DummyInt(); }
302
+inline DummyInt _isnan(...) { return DummyInt(); }
303
+
304
+// A helper function to suppress bogus "conditional expression is constant"
305
+// warnings.
306
+template <typename T>
307
+inline T check(T value) { return value; }
308
+}
309
+}  // namespace fmt
310
+
311
+namespace std {
312
+// Standard permits specialization of std::numeric_limits. This specialization
313
+// is used to resolve ambiguity between isinf and std::isinf in glibc:
314
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
315
+// and the same for isnan and signbit.
316
+template <>
317
+class numeric_limits<fmt::internal::DummyInt> :
318
+    public std::numeric_limits<int> {
319
+ public:
320
+  // Portable version of isinf.
321
+  template <typename T>
322
+  static bool isinfinity(T x) {
323
+    using namespace fmt::internal;
324
+    // The resolution "priority" is:
325
+    // isinf macro > std::isinf > ::isinf > fmt::internal::isinf
326
+    if (check(sizeof(isinf(x)) == sizeof(bool) ||
327
+              sizeof(isinf(x)) == sizeof(int))) {
328
+      return isinf(x) != 0;
329
+    }
330
+    return !_finite(static_cast<double>(x));
331
+  }
332
+
333
+  // Portable version of isnan.
334
+  template <typename T>
335
+  static bool isnotanumber(T x) {
336
+    using namespace fmt::internal;
337
+    if (check(sizeof(isnan(x)) == sizeof(bool) ||
338
+              sizeof(isnan(x)) == sizeof(int))) {
339
+      return isnan(x) != 0;
340
+    }
341
+    return _isnan(static_cast<double>(x)) != 0;
342
+  }
343
+
344
+  // Portable version of signbit.
345
+  static bool isnegative(double x) {
346
+    using namespace fmt::internal;
347
+    if (check(sizeof(signbit(x)) == sizeof(int)))
348
+      return signbit(x) != 0;
349
+    if (x < 0) return true;
350
+    if (!isnotanumber(x)) return false;
351
+    int dec = 0, sign = 0;
352
+    char buffer[2];  // The buffer size must be >= 2 or _ecvt_s will fail.
353
+    _ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign);
354
+    return sign != 0;
355
+  }
356
+};
357
+}  // namespace std
358
+
359
+namespace fmt {
360
+
361
+// Fix the warning about long long on older versions of GCC
362
+// that don't support the diagnostic pragma.
363
+FMT_GCC_EXTENSION typedef long long LongLong;
364
+FMT_GCC_EXTENSION typedef unsigned long long ULongLong;
365
+
366
+#if FMT_USE_RVALUE_REFERENCES
367
+using std::move;
368
+#endif
369
+
370
+template <typename Char>
371
+class BasicWriter;
372
+
373
+typedef BasicWriter<char> Writer;
374
+typedef BasicWriter<wchar_t> WWriter;
375
+
376
+template <typename Char>
377
+class ArgFormatter;
378
+
379
+template <typename CharType,
380
+          typename ArgFormatter = fmt::ArgFormatter<CharType> >
381
+class BasicFormatter;
382
+
383
+/**
384
+  \rst
385
+  A string reference. It can be constructed from a C string or ``std::string``.
386
+
387
+  You can use one of the following typedefs for common character types:
388
+
389
+  +------------+-------------------------+
390
+  | Type       | Definition              |
391
+  +============+=========================+
392
+  | StringRef  | BasicStringRef<char>    |
393
+  +------------+-------------------------+
394
+  | WStringRef | BasicStringRef<wchar_t> |
395
+  +------------+-------------------------+
396
+
397
+  This class is most useful as a parameter type to allow passing
398
+  different types of strings to a function, for example::
399
+
400
+    template <typename... Args>
401
+    std::string format(StringRef format_str, const Args & ... args);
402
+
403
+    format("{}", 42);
404
+    format(std::string("{}"), 42);
405
+  \endrst
406
+ */
407
+template <typename Char>
408
+class BasicStringRef {
409
+ private:
410
+  const Char *data_;
411
+  std::size_t size_;
412
+
413
+ public:
414
+  /** Constructs a string reference object from a C string and a size. */
415
+  BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {}
416
+
417
+  /**
418
+    \rst
419
+    Constructs a string reference object from a C string computing
420
+    the size with ``std::char_traits<Char>::length``.
421
+    \endrst
422
+   */
423
+  BasicStringRef(const Char *s)
424
+    : data_(s), size_(std::char_traits<Char>::length(s)) {}
425
+
426
+  /**
427
+    \rst
428
+    Constructs a string reference from an ``std::string`` object.
429
+    \endrst
430
+   */
431
+  BasicStringRef(const std::basic_string<Char> &s)
432
+  : data_(s.c_str()), size_(s.size()) {}
433
+
434
+  /**
435
+    \rst
436
+    Converts a string reference to an ``std::string`` object.
437
+    \endrst
438
+   */
439
+  std::basic_string<Char> to_string() const {
440
+    return std::basic_string<Char>(data_, size_);
441
+  }
442
+
443
+  /** Returns a pointer to the string data. */
444
+  const Char *data() const { return data_; }
445
+
446
+  /** Returns the string size. */
447
+  std::size_t size() const { return size_; }
448
+
449
+  // Lexicographically compare this string reference to other.
450
+  int compare(BasicStringRef other) const {
451
+    std::size_t size = size_ < other.size_ ? size_ : other.size_;
452
+    int result = std::char_traits<Char>::compare(data_, other.data_, size);
453
+    if (result == 0)
454
+      result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
455
+    return result;
456
+  }
457
+
458
+  friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) {
459
+    return lhs.compare(rhs) == 0;
460
+  }
461
+  friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) {
462
+    return lhs.compare(rhs) != 0;
463
+  }
464
+  friend bool operator<(BasicStringRef lhs, BasicStringRef rhs) {
465
+    return lhs.compare(rhs) < 0;
466
+  }
467
+  friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs) {
468
+    return lhs.compare(rhs) <= 0;
469
+  }
470
+  friend bool operator>(BasicStringRef lhs, BasicStringRef rhs) {
471
+    return lhs.compare(rhs) > 0;
472
+  }
473
+  friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs) {
474
+    return lhs.compare(rhs) >= 0;
475
+  }
476
+};
477
+
478
+typedef BasicStringRef<char> StringRef;
479
+typedef BasicStringRef<wchar_t> WStringRef;
480
+
481
+/**
482
+  \rst
483
+  A reference to a null terminated string. It can be constructed from a C
484
+  string or ``std::string``.
485
+
486
+  You can use one of the following typedefs for common character types:
487
+
488
+  +-------------+--------------------------+
489
+  | Type        | Definition               |
490
+  +=============+==========================+
491
+  | CStringRef  | BasicCStringRef<char>    |
492
+  +-------------+--------------------------+
493
+  | WCStringRef | BasicCStringRef<wchar_t> |
494
+  +-------------+--------------------------+
495
+
496
+  This class is most useful as a parameter type to allow passing
497
+  different types of strings to a function, for example::
498
+
499
+    template <typename... Args>
500
+    std::string format(CStringRef format_str, const Args & ... args);
501
+
502
+    format("{}", 42);
503
+    format(std::string("{}"), 42);
504
+  \endrst
505
+ */
506
+template <typename Char>
507
+class BasicCStringRef {
508
+ private:
509
+  const Char *data_;
510
+
511
+ public:
512
+  /** Constructs a string reference object from a C string. */
513
+  BasicCStringRef(const Char *s) : data_(s) {}
514
+
515
+  /**
516
+    \rst
517
+    Constructs a string reference from an ``std::string`` object.
518
+    \endrst
519
+   */
520
+  BasicCStringRef(const std::basic_string<Char> &s) : data_(s.c_str()) {}
521
+
522
+  /** Returns the pointer to a C string. */
523
+  const Char *c_str() const { return data_; }
524
+};
525
+
526
+typedef BasicCStringRef<char> CStringRef;
527
+typedef BasicCStringRef<wchar_t> WCStringRef;
528
+
529
+/**
530
+  A formatting error such as invalid format string.
531
+*/
532
+class FormatError : public std::runtime_error {
533
+ public:
534
+  explicit FormatError(CStringRef message)
535
+  : std::runtime_error(message.c_str()) {}
536
+};
537
+
538
+namespace internal {
539
+
540
+// MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
541
+template <typename T>
542
+struct MakeUnsigned { typedef T Type; };
543
+
544
+#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
545
+  template <> \
546
+  struct MakeUnsigned<T> { typedef U Type; }
547
+
548
+FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
549
+FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
550
+FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
551
+FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
552
+FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
553
+FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
554
+
555
+// Casts nonnegative integer to unsigned.
556
+template <typename Int>
557
+inline typename MakeUnsigned<Int>::Type to_unsigned(Int value) {
558
+  FMT_ASSERT(value >= 0, "negative value");
559
+  return static_cast<typename MakeUnsigned<Int>::Type>(value);
560
+}
561
+
562
+// The number of characters to store in the MemoryBuffer object itself
563
+// to avoid dynamic memory allocation.
564
+enum { INLINE_BUFFER_SIZE = 500 };
565
+
566
+#if FMT_SECURE_SCL
567
+// Use checked iterator to avoid warnings on MSVC.
568
+template <typename T>
569
+inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) {
570
+  return stdext::checked_array_iterator<T*>(ptr, size);
571
+}
572
+#else
573
+template <typename T>
574
+inline T *make_ptr(T *ptr, std::size_t) { return ptr; }
575
+#endif
576
+}  // namespace internal
577
+
578
+/**
579
+  \rst
580
+  A buffer supporting a subset of ``std::vector``'s operations.
581
+  \endrst
582
+ */
583
+template <typename T>
584
+class Buffer {
585
+ private:
586
+  FMT_DISALLOW_COPY_AND_ASSIGN(Buffer);
587
+
588
+ protected:
589
+  T *ptr_;
590
+  std::size_t size_;
591
+  std::size_t capacity_;
592
+
593
+  Buffer(T *ptr = 0, std::size_t capacity = 0)
594
+    : ptr_(ptr), size_(0), capacity_(capacity) {}
595
+
596
+  /**
597
+    \rst
598
+    Increases the buffer capacity to hold at least *size* elements updating
599
+    ``ptr_`` and ``capacity_``.
600
+    \endrst
601
+   */
602
+  virtual void grow(std::size_t size) = 0;
603
+
604
+ public:
605
+  virtual ~Buffer() {}
606
+
607
+  /** Returns the size of this buffer. */
608
+  std::size_t size() const { return size_; }
609
+
610
+  /** Returns the capacity of this buffer. */
611
+  std::size_t capacity() const { return capacity_; }
612
+
613
+  /**
614
+    Resizes the buffer. If T is a POD type new elements may not be initialized.
615
+   */
616
+  void resize(std::size_t new_size) {
617
+    if (new_size > capacity_)
618
+      grow(new_size);
619
+    size_ = new_size;
620
+  }
621
+
622
+  /**
623
+    \rst
624
+    Reserves space to store at least *capacity* elements.
625
+    \endrst
626
+   */
627
+  void reserve(std::size_t capacity) {
628
+    if (capacity > capacity_)
629
+      grow(capacity);
630
+  }
631
+
632
+  void clear() FMT_NOEXCEPT { size_ = 0; }
633
+
634
+  void push_back(const T &value) {
635
+    if (size_ == capacity_)
636
+      grow(size_ + 1);
637
+    ptr_[size_++] = value;
638
+  }
639
+
640
+  /** Appends data to the end of the buffer. */
641
+  template <typename U>
642
+  void append(const U *begin, const U *end);
643
+
644
+  T &operator[](std::size_t index) { return ptr_[index]; }
645
+  const T &operator[](std::size_t index) const { return ptr_[index]; }
646
+};
647
+
648
+template <typename T>
649
+template <typename U>
650
+void Buffer<T>::append(const U *begin, const U *end) {
651
+  std::size_t new_size = size_ + internal::to_unsigned(end - begin);
652
+  if (new_size > capacity_)
653
+    grow(new_size);
654
+  std::uninitialized_copy(begin, end,
655
+                          internal::make_ptr(ptr_, capacity_) + size_);
656
+  size_ = new_size;
657
+}
658
+
659
+namespace internal {
660
+
661
+// A memory buffer for trivially copyable/constructible types with the first SIZE
662
+// elements stored in the object itself.
663
+template <typename T, std::size_t SIZE, typename Allocator = std::allocator<T> >
664
+class MemoryBuffer : private Allocator, public Buffer<T> {
665
+ private:
666
+  T data_[SIZE];
667
+
668
+  // Deallocate memory allocated by the buffer.
669
+  void deallocate() {
670
+    if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_);
671
+  }
672
+
673
+ protected:
674
+  void grow(std::size_t size);
675
+
676
+ public:
677
+  explicit MemoryBuffer(const Allocator &alloc = Allocator())
678
+      : Allocator(alloc), Buffer<T>(data_, SIZE) {}
679
+  ~MemoryBuffer() { deallocate(); }
680
+
681
+#if FMT_USE_RVALUE_REFERENCES
682
+ private:
683
+  // Move data from other to this buffer.
684
+  void move(MemoryBuffer &other) {
685
+    Allocator &this_alloc = *this, &other_alloc = other;
686
+    this_alloc = std::move(other_alloc);
687
+    this->size_ = other.size_;
688
+    this->capacity_ = other.capacity_;
689
+    if (other.ptr_ == other.data_) {
690
+      this->ptr_ = data_;
691
+      std::uninitialized_copy(other.data_, other.data_ + this->size_,
692
+                              make_ptr(data_, this->capacity_));
693
+    } else {
694
+      this->ptr_ = other.ptr_;
695
+      // Set pointer to the inline array so that delete is not called
696
+      // when deallocating.
697
+      other.ptr_ = other.data_;
698
+    }
699
+  }
700
+
701
+ public:
702
+  MemoryBuffer(MemoryBuffer &&other) {
703
+    move(other);
704
+  }
705
+
706
+  MemoryBuffer &operator=(MemoryBuffer &&other) {
707
+    assert(this != &other);
708
+    deallocate();
709
+    move(other);
710
+    return *this;
711
+  }
712
+#endif
713
+
714
+  // Returns a copy of the allocator associated with this buffer.
715
+  Allocator get_allocator() const { return *this; }
716
+};
717
+
718
+template <typename T, std::size_t SIZE, typename Allocator>
719
+void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
720
+  std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
721
+  if (size > new_capacity)
722
+      new_capacity = size;
723
+  T *new_ptr = this->allocate(new_capacity);
724
+  // The following code doesn't throw, so the raw pointer above doesn't leak.
725
+  std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
726
+                          make_ptr(new_ptr, new_capacity));
727
+  std::size_t old_capacity = this->capacity_;
728
+  T *old_ptr = this->ptr_;
729
+  this->capacity_ = new_capacity;
730
+  this->ptr_ = new_ptr;
731
+  // deallocate may throw (at least in principle), but it doesn't matter since
732
+  // the buffer already uses the new storage and will deallocate it in case
733
+  // of exception.
734
+  if (old_ptr != data_)
735
+    Allocator::deallocate(old_ptr, old_capacity);
736
+}
737
+
738
+// A fixed-size buffer.
739
+template <typename Char>
740
+class FixedBuffer : public fmt::Buffer<Char> {
741
+ public:
742
+  FixedBuffer(Char *array, std::size_t size) : fmt::Buffer<Char>(array, size) {}
743
+
744
+ protected:
745
+  FMT_API void grow(std::size_t size);
746
+};
747
+
748
+template <typename Char>
749
+class BasicCharTraits {
750
+ public:
751
+#if FMT_SECURE_SCL
752
+  typedef stdext::checked_array_iterator<Char*> CharPtr;
753
+#else
754
+  typedef Char *CharPtr;
755
+#endif
756
+  static Char cast(int value) { return static_cast<Char>(value); }
757
+};
758
+
759
+template <typename Char>
760
+class CharTraits;
761
+
762
+template <>
763
+class CharTraits<char> : public BasicCharTraits<char> {
764
+ private:
765
+  // Conversion from wchar_t to char is not allowed.
766
+  static char convert(wchar_t);
767
+
768
+ public:
769
+  static char convert(char value) { return value; }
770
+
771
+  // Formats a floating-point number.
772
+  template <typename T>
773
+  FMT_API static int format_float(char *buffer, std::size_t size,
774
+      const char *format, unsigned width, int precision, T value);
775
+};
776
+
777
+template <>
778
+class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
779
+ public:
780
+  static wchar_t convert(char value) { return value; }
781
+  static wchar_t convert(wchar_t value) { return value; }
782
+
783
+  template <typename T>
784
+  FMT_API static int format_float(wchar_t *buffer, std::size_t size,
785
+      const wchar_t *format, unsigned width, int precision, T value);
786
+};
787
+
788
+// Checks if a number is negative - used to avoid warnings.
789
+template <bool IsSigned>
790
+struct SignChecker {
791
+  template <typename T>
792
+  static bool is_negative(T value) { return value < 0; }
793
+};
794
+
795
+template <>
796
+struct SignChecker<false> {
797
+  template <typename T>
798
+  static bool is_negative(T) { return false; }
799
+};
800
+
801
+// Returns true if value is negative, false otherwise.
802
+// Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
803
+template <typename T>
804
+inline bool is_negative(T value) {
805
+  return SignChecker<std::numeric_limits<T>::is_signed>::is_negative(value);
806
+}
807
+
808
+// Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
809
+template <bool FitsIn32Bits>
810
+struct TypeSelector { typedef uint32_t Type; };
811
+
812
+template <>
813
+struct TypeSelector<false> { typedef uint64_t Type; };
814
+
815
+template <typename T>
816
+struct IntTraits {
817
+  // Smallest of uint32_t and uint64_t that is large enough to represent
818
+  // all values of T.
819
+  typedef typename
820
+    TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
821
+};
822
+
823
+FMT_API void report_unknown_type(char code, const char *type);
824
+
825
+// Static data is placed in this class template to allow header-only
826
+// configuration.
827
+template <typename T = void>
828
+struct FMT_API BasicData {
829
+  static const uint32_t POWERS_OF_10_32[];
830
+  static const uint64_t POWERS_OF_10_64[];
831
+  static const char DIGITS[];
832
+};
833
+
834
+typedef BasicData<> Data;
835
+
836
+#ifdef FMT_BUILTIN_CLZLL
837
+// Returns the number of decimal digits in n. Leading zeros are not counted
838
+// except for n == 0 in which case count_digits returns 1.
839
+inline unsigned count_digits(uint64_t n) {
840
+  // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
841
+  // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
842
+  int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12;
843
+  return to_unsigned(t) - (n < Data::POWERS_OF_10_64[t]) + 1;
844
+}
845
+#else
846
+// Fallback version of count_digits used when __builtin_clz is not available.
847
+inline unsigned count_digits(uint64_t n) {
848
+  unsigned count = 1;
849
+  for (;;) {
850
+    // Integer division is slow so do it for a group of four digits instead
851
+    // of for every digit. The idea comes from the talk by Alexandrescu
852
+    // "Three Optimization Tips for C++". See speed-test for a comparison.
853
+    if (n < 10) return count;
854
+    if (n < 100) return count + 1;
855
+    if (n < 1000) return count + 2;
856
+    if (n < 10000) return count + 3;
857
+    n /= 10000u;
858
+    count += 4;
859
+  }
860
+}
861
+#endif
862
+
863
+#ifdef FMT_BUILTIN_CLZ
864
+// Optional version of count_digits for better performance on 32-bit platforms.
865
+inline unsigned count_digits(uint32_t n) {
866
+  int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12;
867
+  return to_unsigned(t) - (n < Data::POWERS_OF_10_32[t]) + 1;
868
+}
869
+#endif
870
+
871
+// A functor that doesn't add a thousands separator.
872
+struct NoThousandsSep {
873
+  template <typename Char>
874
+  void operator()(Char *) {}
875
+};
876
+
877
+// A functor that adds a thousands separator.
878
+class ThousandsSep {
879
+ private:
880
+  fmt::StringRef sep_;
881
+
882
+  // Index of a decimal digit with the least significant digit having index 0.
883
+  unsigned digit_index_;
884
+
885
+ public:
886
+  explicit ThousandsSep(fmt::StringRef sep) : sep_(sep), digit_index_(0) {}
887
+
888
+  template <typename Char>
889
+  void operator()(Char *&buffer) {
890
+    if (++digit_index_ % 3 != 0)
891
+      return;
892
+    buffer -= sep_.size();
893
+    std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(),
894
+                            internal::make_ptr(buffer, sep_.size()));
895
+  }
896
+};
897
+
898
+// Formats a decimal unsigned integer value writing into buffer.
899
+// thousands_sep is a functor that is called after writing each char to
900
+// add a thousands separator if necessary.
901
+template <typename UInt, typename Char, typename ThousandsSep>
902
+inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
903
+                           ThousandsSep thousands_sep) {
904
+  buffer += num_digits;
905
+  while (value >= 100) {
906
+    // Integer division is slow so do it for a group of two digits instead
907
+    // of for every digit. The idea comes from the talk by Alexandrescu
908
+    // "Three Optimization Tips for C++". See speed-test for a comparison.
909
+    unsigned index = static_cast<unsigned>((value % 100) * 2);
910
+    value /= 100;
911
+    *--buffer = Data::DIGITS[index + 1];
912
+    thousands_sep(buffer);
913
+    *--buffer = Data::DIGITS[index];
914
+    thousands_sep(buffer);
915
+  }
916
+  if (value < 10) {
917
+    *--buffer = static_cast<char>('0' + value);
918
+    return;
919
+  }
920
+  unsigned index = static_cast<unsigned>(value * 2);
921
+  *--buffer = Data::DIGITS[index + 1];
922
+  *--buffer = Data::DIGITS[index];
923
+}
924
+
925
+template <typename UInt, typename Char>
926
+inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
927
+  return format_decimal(buffer, value, num_digits, NoThousandsSep());
928
+}
929
+
930
+#ifndef _WIN32
931
+# define FMT_USE_WINDOWS_H 0
932
+#elif !defined(FMT_USE_WINDOWS_H)
933
+# define FMT_USE_WINDOWS_H 1
934
+#endif
935
+
936
+// Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h.
937
+// All the functionality that relies on it will be disabled too.
938
+#if FMT_USE_WINDOWS_H
939
+// A converter from UTF-8 to UTF-16.
940
+// It is only provided for Windows since other systems support UTF-8 natively.
941
+class UTF8ToUTF16 {
942
+ private:
943
+  MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer_;
944
+
945
+ public:
946
+  FMT_API explicit UTF8ToUTF16(StringRef s);
947
+  operator WStringRef() const { return WStringRef(&buffer_[0], size()); }
948
+  size_t size() const { return buffer_.size() - 1; }
949
+  const wchar_t *c_str() const { return &buffer_[0]; }
950
+  std::wstring str() const { return std::wstring(&buffer_[0], size()); }
951
+};
952
+
953
+// A converter from UTF-16 to UTF-8.
954
+// It is only provided for Windows since other systems support UTF-8 natively.
955
+class UTF16ToUTF8 {
956
+ private:
957
+  MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer_;
958
+
959
+ public:
960
+  UTF16ToUTF8() {}
961
+  FMT_API explicit UTF16ToUTF8(WStringRef s);
962
+  operator StringRef() const { return StringRef(&buffer_[0], size()); }
963
+  size_t size() const { return buffer_.size() - 1; }
964
+  const char *c_str() const { return &buffer_[0]; }
965
+  std::string str() const { return std::string(&buffer_[0], size()); }
966
+
967
+  // Performs conversion returning a system error code instead of
968
+  // throwing exception on conversion error. This method may still throw
969
+  // in case of memory allocation error.
970
+  FMT_API int convert(WStringRef s);
971
+};
972
+
973
+FMT_API void format_windows_error(fmt::Writer &out, int error_code,
974
+                                  fmt::StringRef message) FMT_NOEXCEPT;
975
+#endif
976
+
977
+FMT_API void format_system_error(fmt::Writer &out, int error_code,
978
+                                 fmt::StringRef message) FMT_NOEXCEPT;
979
+
980
+// A formatting argument value.
981
+struct Value {
982
+  template <typename Char>
983
+  struct StringValue {
984
+    const Char *value;
985
+    std::size_t size;
986
+  };
987
+
988
+  typedef void (*FormatFunc)(
989
+      void *formatter, const void *arg, void *format_str_ptr);
990
+
991
+  struct CustomValue {
992
+    const void *value;
993
+    FormatFunc format;
994
+  };
995
+
996
+  union {
997
+    int int_value;
998
+    unsigned uint_value;
999
+    LongLong long_long_value;
1000
+    ULongLong ulong_long_value;
1001
+    double double_value;
1002
+    long double long_double_value;
1003
+    const void *pointer;
1004
+    StringValue<char> string;
1005
+    StringValue<signed char> sstring;
1006
+    StringValue<unsigned char> ustring;
1007
+    StringValue<wchar_t> wstring;
1008
+    CustomValue custom;
1009
+  };
1010
+
1011
+  enum Type {
1012
+    NONE, NAMED_ARG,
1013
+    // Integer types should go first,
1014
+    INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR,
1015
+    // followed by floating-point types.
1016
+    DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
1017
+    CSTRING, STRING, WSTRING, POINTER, CUSTOM
1018
+  };
1019
+};
1020
+
1021
+// A formatting argument. It is a trivially copyable/constructible type to
1022
+// allow storage in internal::MemoryBuffer.
1023
+struct Arg : Value {
1024
+  Type type;
1025
+};
1026
+
1027
+template <typename Char>
1028
+struct NamedArg;
1029
+
1030
+template <typename T = void>
1031
+struct Null {};
1032
+
1033
+// A helper class template to enable or disable overloads taking wide
1034
+// characters and strings in MakeValue.
1035
+template <typename T, typename Char>
1036
+struct WCharHelper {
1037
+  typedef Null<T> Supported;
1038
+  typedef T Unsupported;
1039
+};
1040
+
1041
+template <typename T>
1042
+struct WCharHelper<T, wchar_t> {
1043
+  typedef T Supported;
1044
+  typedef Null<T> Unsupported;
1045
+};
1046
+
1047
+typedef char Yes[1];
1048
+typedef char No[2];
1049
+
1050
+template <typename T>
1051
+T &get();
1052
+
1053
+// These are non-members to workaround an overload resolution bug in bcc32.
1054
+Yes &convert(fmt::ULongLong);
1055
+No &convert(...);
1056
+
1057
+template<typename T, bool ENABLE_CONVERSION>
1058
+struct ConvertToIntImpl {
1059
+  enum { value = ENABLE_CONVERSION };
1060
+};
1061
+
1062
+template<typename T, bool ENABLE_CONVERSION>
1063
+struct ConvertToIntImpl2 {
1064
+  enum { value = false };
1065
+};
1066
+
1067
+template<typename T>
1068
+struct ConvertToIntImpl2<T, true> {
1069
+  enum {
1070
+    // Don't convert numeric types.
1071
+    value = ConvertToIntImpl<T, !std::numeric_limits<T>::is_specialized>::value
1072
+  };
1073
+};
1074
+
1075
+template<typename T>
1076
+struct ConvertToInt {
1077
+  enum { enable_conversion = sizeof(convert(get<T>())) == sizeof(Yes) };
1078
+  enum { value = ConvertToIntImpl2<T, enable_conversion>::value };
1079
+};
1080
+
1081
+#define FMT_DISABLE_CONVERSION_TO_INT(Type) \
1082
+  template <> \
1083
+  struct ConvertToInt<Type> {  enum { value = 0 }; }
1084
+
1085
+// Silence warnings about convering float to int.
1086
+FMT_DISABLE_CONVERSION_TO_INT(float);
1087
+FMT_DISABLE_CONVERSION_TO_INT(double);
1088
+FMT_DISABLE_CONVERSION_TO_INT(long double);
1089
+
1090
+template<bool B, class T = void>
1091
+struct EnableIf {};
1092
+
1093
+template<class T>
1094
+struct EnableIf<true, T> { typedef T type; };
1095
+
1096
+template<bool B, class T, class F>
1097
+struct Conditional { typedef T type; };
1098
+
1099
+template<class T, class F>
1100
+struct Conditional<false, T, F> { typedef F type; };
1101
+
1102
+// For bcc32 which doesn't understand ! in template arguments.
1103
+template<bool>
1104
+struct Not { enum { value = 0 }; };
1105
+
1106
+template<>
1107
+struct Not<false> { enum { value = 1 }; };
1108
+
1109
+// Makes an Arg object from any type.
1110
+template <typename Formatter>
1111
+class MakeValue : public Arg {
1112
+ public:
1113
+  typedef typename Formatter::Char Char;
1114
+
1115
+ private:
1116
+  // The following two methods are private to disallow formatting of
1117
+  // arbitrary pointers. If you want to output a pointer cast it to
1118
+  // "void *" or "const void *". In particular, this forbids formatting
1119
+  // of "[const] volatile char *" which is printed as bool by iostreams.
1120
+  // Do not implement!
1121
+  template <typename T>
1122
+  MakeValue(const T *value);
1123
+  template <typename T>
1124
+  MakeValue(T *value);
1125
+
1126
+  // The following methods are private to disallow formatting of wide
1127
+  // characters and strings into narrow strings as in
1128
+  //   fmt::format("{}", L"test");
1129
+  // To fix this, use a wide format string: fmt::format(L"{}", L"test").
1130
+#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
1131
+  MakeValue(typename WCharHelper<wchar_t, Char>::Unsupported);
1132
+#endif
1133
+  MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported);
1134
+  MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported);
1135
+  MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported);
1136
+  MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);
1137
+
1138
+  void set_string(StringRef str) {
1139
+    string.value = str.data();
1140
+    string.size = str.size();
1141
+  }
1142
+
1143
+  void set_string(WStringRef str) {
1144
+    wstring.value = str.data();
1145
+    wstring.size = str.size();
1146
+  }
1147
+
1148
+  // Formats an argument of a custom type, such as a user-defined class.
1149
+  template <typename T>
1150
+  static void format_custom_arg(
1151
+      void *formatter, const void *arg, void *format_str_ptr) {
1152
+    format(*static_cast<Formatter*>(formatter),
1153
+           *static_cast<const Char**>(format_str_ptr),
1154
+           *static_cast<const T*>(arg));
1155
+  }
1156
+
1157
+ public:
1158
+  MakeValue() {}
1159
+
1160
+#define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \
1161
+  MakeValue(Type value) { field = rhs; } \
1162
+  static uint64_t type(Type) { return Arg::TYPE; }
1163
+
1164
+#define FMT_MAKE_VALUE(Type, field, TYPE) \
1165
+  FMT_MAKE_VALUE_(Type, field, TYPE, value)
1166
+
1167
+  FMT_MAKE_VALUE(bool, int_value, BOOL)
1168
+  FMT_MAKE_VALUE(short, int_value, INT)
1169
+  FMT_MAKE_VALUE(unsigned short, uint_value, UINT)
1170
+  FMT_MAKE_VALUE(int, int_value, INT)
1171
+  FMT_MAKE_VALUE(unsigned, uint_value, UINT)
1172
+
1173
+  MakeValue(long value) {
1174
+    // To minimize the number of types we need to deal with, long is
1175
+    // translated either to int or to long long depending on its size.
1176
+    if (check(sizeof(long) == sizeof(int)))
1177
+      int_value = static_cast<int>(value);
1178
+    else
1179
+      long_long_value = value;
1180
+  }
1181
+  static uint64_t type(long) {
1182
+    return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG;
1183
+  }
1184
+
1185
+  MakeValue(unsigned long value) {
1186
+    if (check(sizeof(unsigned long) == sizeof(unsigned)))
1187
+      uint_value = static_cast<unsigned>(value);
1188
+    else
1189
+      ulong_long_value = value;
1190
+  }
1191
+  static uint64_t type(unsigned long) {
1192
+    return sizeof(unsigned long) == sizeof(unsigned) ?
1193
+          Arg::UINT : Arg::ULONG_LONG;
1194
+  }
1195
+
1196
+  FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG)
1197
+  FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG)
1198
+  FMT_MAKE_VALUE(float, double_value, DOUBLE)
1199
+  FMT_MAKE_VALUE(double, double_value, DOUBLE)
1200
+  FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE)
1201
+  FMT_MAKE_VALUE(signed char, int_value, INT)
1202
+  FMT_MAKE_VALUE(unsigned char, uint_value, UINT)
1203
+  FMT_MAKE_VALUE(char, int_value, CHAR)
1204
+
1205
+#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
1206
+  MakeValue(typename WCharHelper<wchar_t, Char>::Supported value) {
1207
+    int_value = value;
1208
+  }
1209
+  static uint64_t type(wchar_t) { return Arg::CHAR; }
1210
+#endif
1211
+
1212
+#define FMT_MAKE_STR_VALUE(Type, TYPE) \
1213
+  MakeValue(Type value) { set_string(value); } \
1214
+  static uint64_t type(Type) { return Arg::TYPE; }
1215
+
1216
+  FMT_MAKE_VALUE(char *, string.value, CSTRING)
1217
+  FMT_MAKE_VALUE(const char *, string.value, CSTRING)
1218
+  FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING)
1219
+  FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING)
1220
+  FMT_MAKE_STR_VALUE(const std::string &, STRING)
1221
+  FMT_MAKE_STR_VALUE(StringRef, STRING)
1222
+  FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str())
1223
+
1224
+#define FMT_MAKE_WSTR_VALUE(Type, TYPE) \
1225
+  MakeValue(typename WCharHelper<Type, Char>::Supported value) { \
1226
+    set_string(value); \
1227
+  } \
1228
+  static uint64_t type(Type) { return Arg::TYPE; }
1229
+
1230
+  FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING)
1231
+  FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING)
1232
+  FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING)
1233
+  FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING)
1234
+
1235
+  FMT_MAKE_VALUE(void *, pointer, POINTER)
1236
+  FMT_MAKE_VALUE(const void *, pointer, POINTER)
1237
+
1238
+  template <typename T>
1239
+  MakeValue(const T &value,
1240
+            typename EnableIf<Not<
1241
+              ConvertToInt<T>::value>::value, int>::type = 0) {
1242
+    custom.value = &value;
1243
+    custom.format = &format_custom_arg<T>;
1244
+  }
1245
+
1246
+  template <typename T>
1247
+  MakeValue(const T &value,
1248
+            typename EnableIf<ConvertToInt<T>::value, int>::type = 0) {
1249
+    int_value = value;
1250
+  }
1251
+
1252
+  template <typename T>
1253
+  static uint64_t type(const T &) {
1254
+    return ConvertToInt<T>::value ? Arg::INT : Arg::CUSTOM;
1255
+  }
1256
+
1257
+  // Additional template param `Char_` is needed here because make_type always
1258
+  // uses char.
1259
+  template <typename Char_>
1260
+  MakeValue(const NamedArg<Char_> &value) { pointer = &value; }
1261
+
1262
+  template <typename Char_>
1263
+  static uint64_t type(const NamedArg<Char_> &) { return Arg::NAMED_ARG; }
1264
+};
1265
+
1266
+template <typename Formatter>
1267
+class MakeArg : public Arg {
1268
+public:
1269
+  MakeArg() {
1270
+    type = Arg::NONE;
1271
+  }
1272
+  
1273
+  template <typename T>
1274
+  MakeArg(const T &value)
1275
+  : Arg(MakeValue<Formatter>(value)) {
1276
+    type = static_cast<Arg::Type>(MakeValue<Formatter>::type(value));
1277
+  }
1278
+};
1279
+
1280
+template <typename Char>
1281
+struct NamedArg : Arg {
1282
+  BasicStringRef<Char> name;
1283
+
1284
+  template <typename T>
1285
+  NamedArg(BasicStringRef<Char> argname, const T &value)
1286
+  : Arg(MakeArg< BasicFormatter<Char> >(value)), name(argname) {}
1287
+};
1288
+
1289
+class RuntimeError : public std::runtime_error {
1290
+ protected:
1291
+  RuntimeError() : std::runtime_error("") {}
1292
+};
1293
+
1294
+template <typename Char>
1295
+class PrintfArgFormatter;
1296
+
1297
+template <typename Char>
1298
+class ArgMap;
1299
+}  // namespace internal
1300
+
1301
+/** An argument list. */
1302
+class ArgList {
1303
+ private:
1304
+  // To reduce compiled code size per formatting function call, types of first
1305
+  // MAX_PACKED_ARGS arguments are passed in the types_ field.
1306
+  uint64_t types_;
1307
+  union {
1308
+    // If the number of arguments is less than MAX_PACKED_ARGS, the argument
1309
+    // values are stored in values_, otherwise they are stored in args_.
1310
+    // This is done to reduce compiled code size as storing larger objects
1311
+    // may require more code (at least on x86-64) even if the same amount of
1312
+    // data is actually copied to stack. It saves ~10% on the bloat test.
1313
+    const internal::Value *values_;
1314
+    const internal::Arg *args_;
1315
+  };
1316
+
1317
+  internal::Arg::Type type(unsigned index) const {
1318
+    unsigned shift = index * 4;
1319
+    uint64_t mask = 0xf;
1320
+    return static_cast<internal::Arg::Type>(
1321
+          (types_ & (mask << shift)) >> shift);
1322
+  }
1323
+
1324
+  template <typename Char>
1325
+  friend class internal::ArgMap;
1326
+
1327
+ public:
1328
+  // Maximum number of arguments with packed types.
1329
+  enum { MAX_PACKED_ARGS = 16 };
1330
+
1331
+  ArgList() : types_(0) {}
1332
+
1333
+  ArgList(ULongLong types, const internal::Value *values)
1334
+  : types_(types), values_(values) {}
1335
+  ArgList(ULongLong types, const internal::Arg *args)
1336
+  : types_(types), args_(args) {}
1337
+
1338
+  /** Returns the argument at specified index. */
1339
+  internal::Arg operator[](unsigned index) const {
1340
+    using internal::Arg;
1341
+    Arg arg;
1342
+    bool use_values = type(MAX_PACKED_ARGS - 1) == Arg::NONE;
1343
+    if (index < MAX_PACKED_ARGS) {
1344
+      Arg::Type arg_type = type(index);
1345
+      internal::Value &val = arg;
1346
+      if (arg_type != Arg::NONE)
1347
+        val = use_values ? values_[index] : args_[index];
1348
+      arg.type = arg_type;
1349
+      return arg;
1350
+    }
1351
+    if (use_values) {
1352
+      // The index is greater than the number of arguments that can be stored
1353
+      // in values, so return a "none" argument.
1354
+      arg.type = Arg::NONE;
1355
+      return arg;
1356
+    }
1357
+    for (unsigned i = MAX_PACKED_ARGS; i <= index; ++i) {
1358
+      if (args_[i].type == Arg::NONE)
1359
+        return args_[i];
1360
+    }
1361
+    return args_[index];
1362
+  }
1363
+};
1364
+
1365
+#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
1366
+
1367
+/**
1368
+  \rst
1369
+  An argument visitor based on the `curiously recurring template pattern
1370
+  <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
1371
+
1372
+  To use `~fmt::ArgVisitor` define a subclass that implements some or all of the
1373
+  visit methods with the same signatures as the methods in `~fmt::ArgVisitor`,
1374
+  for example, `~fmt::ArgVisitor::visit_int()`.
1375
+  Pass the subclass as the *Impl* template parameter. Then calling
1376
+  `~fmt::ArgVisitor::visit` for some argument will dispatch to a visit method
1377
+  specific to the argument type. For example, if the argument type is
1378
+  ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
1379
+  will be called. If the subclass doesn't contain a method with this signature,
1380
+  then a corresponding method of `~fmt::ArgVisitor` will be called.
1381
+
1382
+  **Example**::
1383
+
1384
+    class MyArgVisitor : public fmt::ArgVisitor<MyArgVisitor, void> {
1385
+     public:
1386
+      void visit_int(int value) { fmt::print("{}", value); }
1387
+      void visit_double(double value) { fmt::print("{}", value ); }
1388
+    };
1389
+  \endrst
1390
+ */
1391
+template <typename Impl, typename Result>
1392
+class ArgVisitor {
1393
+ private:
1394
+  typedef internal::Arg Arg;
1395
+
1396
+ public:
1397
+  void report_unhandled_arg() {}
1398
+
1399
+  Result visit_unhandled_arg() {
1400
+    FMT_DISPATCH(report_unhandled_arg());
1401
+    return Result();
1402
+  }
1403
+
1404
+  /** Visits an ``int`` argument. **/
1405
+  Result visit_int(int value) {
1406
+    return FMT_DISPATCH(visit_any_int(value));
1407
+  }
1408
+
1409
+  /** Visits a ``long long`` argument. **/
1410
+  Result visit_long_long(LongLong value) {
1411
+    return FMT_DISPATCH(visit_any_int(value));
1412
+  }
1413
+
1414
+  /** Visits an ``unsigned`` argument. **/
1415
+  Result visit_uint(unsigned value) {
1416
+    return FMT_DISPATCH(visit_any_int(value));
1417
+  }
1418
+
1419
+  /** Visits an ``unsigned long long`` argument. **/
1420
+  Result visit_ulong_long(ULongLong value) {
1421
+    return FMT_DISPATCH(visit_any_int(value));
1422
+  }
1423
+
1424
+  /** Visits a ``bool`` argument. **/
1425
+  Result visit_bool(bool value) {
1426
+    return FMT_DISPATCH(visit_any_int(value));
1427
+  }
1428
+
1429
+  /** Visits a ``char`` or ``wchar_t`` argument. **/
1430
+  Result visit_char(int value) {
1431
+    return FMT_DISPATCH(visit_any_int(value));
1432
+  }
1433
+
1434
+  /** Visits an argument of any integral type. **/
1435
+  template <typename T>
1436
+  Result visit_any_int(T) {
1437
+    return FMT_DISPATCH(visit_unhandled_arg());
1438
+  }
1439
+
1440
+  /** Visits a ``double`` argument. **/
1441
+  Result visit_double(double value) {
1442
+    return FMT_DISPATCH(visit_any_double(value));
1443
+  }
1444
+
1445
+  /** Visits a ``long double`` argument. **/
1446
+  Result visit_long_double(long double value) {
1447
+    return FMT_DISPATCH(visit_any_double(value));
1448
+  }
1449
+
1450
+  /** Visits a ``double`` or ``long double`` argument. **/
1451
+  template <typename T>
1452
+  Result visit_any_double(T) {
1453
+    return FMT_DISPATCH(visit_unhandled_arg());
1454
+  }
1455
+
1456
+  /** Visits a null-terminated C string (``const char *``) argument. **/
1457
+  Result visit_cstring(const char *) {
1458
+    return FMT_DISPATCH(visit_unhandled_arg());
1459
+  }
1460
+
1461
+  /** Visits a string argument. **/
1462
+  Result visit_string(Arg::StringValue<char>) {
1463
+    return FMT_DISPATCH(visit_unhandled_arg());
1464
+  }
1465
+
1466
+  /** Visits a wide string argument. **/
1467
+  Result visit_wstring(Arg::StringValue<wchar_t>) {
1468
+    return FMT_DISPATCH(visit_unhandled_arg());
1469
+  }
1470
+
1471
+  /** Visits a pointer argument. **/
1472
+  Result visit_pointer(const void *) {
1473
+    return FMT_DISPATCH(visit_unhandled_arg());
1474
+  }
1475
+
1476
+  /** Visits an argument of a custom (user-defined) type. **/
1477
+  Result visit_custom(Arg::CustomValue) {
1478
+    return FMT_DISPATCH(visit_unhandled_arg());
1479
+  }
1480
+
1481
+  /**
1482
+    \rst
1483
+    Visits an argument dispatching to the appropriate visit method based on
1484
+    the argument type. For example, if the argument type is ``double`` then
1485
+    the `~fmt::ArgVisitor::visit_double()` method of the *Impl* class will be
1486
+    called.
1487
+    \endrst
1488
+   */
1489
+  Result visit(const Arg &arg) {
1490
+    switch (arg.type) {
1491
+    default:
1492
+      FMT_ASSERT(false, "invalid argument type");
1493
+      return Result();
1494
+    case Arg::INT:
1495
+      return FMT_DISPATCH(visit_int(arg.int_value));
1496
+    case Arg::UINT:
1497
+      return FMT_DISPATCH(visit_uint(arg.uint_value));
1498
+    case Arg::LONG_LONG:
1499
+      return FMT_DISPATCH(visit_long_long(arg.long_long_value));
1500
+    case Arg::ULONG_LONG:
1501
+      return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value));
1502
+    case Arg::BOOL:
1503
+      return FMT_DISPATCH(visit_bool(arg.int_value != 0));
1504
+    case Arg::CHAR:
1505
+      return FMT_DISPATCH(visit_char(arg.int_value));
1506
+    case Arg::DOUBLE:
1507
+      return FMT_DISPATCH(visit_double(arg.double_value));
1508
+    case Arg::LONG_DOUBLE:
1509
+      return FMT_DISPATCH(visit_long_double(arg.long_double_value));
1510
+    case Arg::CSTRING:
1511
+      return FMT_DISPATCH(visit_cstring(arg.string.value));
1512
+    case Arg::STRING:
1513
+      return FMT_DISPATCH(visit_string(arg.string));
1514
+    case Arg::WSTRING:
1515
+      return FMT_DISPATCH(visit_wstring(arg.wstring));
1516
+    case Arg::POINTER:
1517
+      return FMT_DISPATCH(visit_pointer(arg.pointer));
1518
+    case Arg::CUSTOM:
1519
+      return FMT_DISPATCH(visit_custom(arg.custom));
1520
+    }
1521
+  }
1522
+};
1523
+
1524
+enum Alignment {
1525
+  ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
1526
+};
1527
+
1528
+// Flags.
1529
+enum {
1530
+  SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8,
1531
+  CHAR_FLAG = 0x10  // Argument has char type - used in error reporting.
1532
+};
1533
+
1534
+// An empty format specifier.
1535
+struct EmptySpec {};
1536
+
1537
+// A type specifier.
1538
+template <char TYPE>
1539
+struct TypeSpec : EmptySpec {
1540
+  Alignment align() const { return ALIGN_DEFAULT; }
1541
+  unsigned width() const { return 0; }
1542
+  int precision() const { return -1; }
1543
+  bool flag(unsigned) const { return false; }
1544
+  char type() const { return TYPE; }
1545
+  char fill() const { return ' '; }
1546
+};
1547
+
1548
+// A width specifier.
1549
+struct WidthSpec {
1550
+  unsigned width_;
1551
+  // Fill is always wchar_t and cast to char if necessary to avoid having
1552
+  // two specialization of WidthSpec and its subclasses.
1553
+  wchar_t fill_;
1554
+
1555
+  WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {}
1556
+
1557
+  unsigned width() const { return width_; }
1558
+  wchar_t fill() const { return fill_; }
1559
+};
1560
+
1561
+// An alignment specifier.
1562
+struct AlignSpec : WidthSpec {
1563
+  Alignment align_;
1564
+
1565
+  AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT)
1566
+  : WidthSpec(width, fill), align_(align) {}
1567
+
1568
+  Alignment align() const { return align_; }
1569
+
1570
+  int precision() const { return -1; }
1571
+};
1572
+
1573
+// An alignment and type specifier.
1574
+template <char TYPE>
1575
+struct AlignTypeSpec : AlignSpec {
1576
+  AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {}
1577
+
1578
+  bool flag(unsigned) const { return false; }
1579
+  char type() const { return TYPE; }
1580
+};
1581
+
1582
+// A full format specifier.
1583
+struct FormatSpec : AlignSpec {
1584
+  unsigned flags_;
1585
+  int precision_;
1586
+  char type_;
1587
+
1588
+  FormatSpec(
1589
+    unsigned width = 0, char type = 0, wchar_t fill = ' ')
1590
+  : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
1591
+
1592
+  bool flag(unsigned f) const { return (flags_ & f) != 0; }
1593
+  int precision() const { return precision_; }
1594
+  char type() const { return type_; }
1595
+};
1596
+
1597
+// An integer format specifier.
1598
+template <typename T, typename SpecT = TypeSpec<0>, typename Char = char>
1599
+class IntFormatSpec : public SpecT {
1600
+ private:
1601
+  T value_;
1602
+
1603
+ public:
1604
+  IntFormatSpec(T val, const SpecT &spec = SpecT())
1605
+  : SpecT(spec), value_(val) {}
1606
+
1607
+  T value() const { return value_; }
1608
+};
1609
+
1610
+// A string format specifier.
1611
+template <typename Char>
1612
+class StrFormatSpec : public AlignSpec {
1613
+ private:
1614
+  const Char *str_;
1615
+
1616
+ public:
1617
+  template <typename FillChar>
1618
+  StrFormatSpec(const Char *str, unsigned width, FillChar fill)
1619
+  : AlignSpec(width, fill), str_(str) {
1620
+    internal::CharTraits<Char>::convert(FillChar());
1621
+  }
1622
+
1623
+  const Char *str() const { return str_; }
1624
+};
1625
+
1626
+/**
1627
+  Returns an integer format specifier to format the value in base 2.
1628
+ */
1629
+IntFormatSpec<int, TypeSpec<'b'> > bin(int value);
1630
+
1631
+/**
1632
+  Returns an integer format specifier to format the value in base 8.
1633
+ */
1634
+IntFormatSpec<int, TypeSpec<'o'> > oct(int value);
1635
+
1636
+/**
1637
+  Returns an integer format specifier to format the value in base 16 using
1638
+  lower-case letters for the digits above 9.
1639
+ */
1640
+IntFormatSpec<int, TypeSpec<'x'> > hex(int value);
1641
+
1642
+/**
1643
+  Returns an integer formatter format specifier to format in base 16 using
1644
+  upper-case letters for the digits above 9.
1645
+ */
1646
+IntFormatSpec<int, TypeSpec<'X'> > hexu(int value);
1647
+
1648
+/**
1649
+  \rst
1650
+  Returns an integer format specifier to pad the formatted argument with the
1651
+  fill character to the specified width using the default (right) numeric
1652
+  alignment.
1653
+
1654
+  **Example**::
1655
+
1656
+    MemoryWriter out;
1657
+    out << pad(hex(0xcafe), 8, '0');
1658
+    // out.str() == "0000cafe"
1659
+
1660
+  \endrst
1661
+ */
1662
+template <char TYPE_CODE, typename Char>
1663
+IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad(
1664
+    int value, unsigned width, Char fill = ' ');
1665
+
1666
+#define FMT_DEFINE_INT_FORMATTERS(TYPE) \
1667
+inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
1668
+  return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
1669
+} \
1670
+ \
1671
+inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
1672
+  return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
1673
+} \
1674
+ \
1675
+inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \
1676
+  return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \
1677
+} \
1678
+ \
1679
+inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \
1680
+  return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \
1681
+} \
1682
+ \
1683
+template <char TYPE_CODE> \
1684
+inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \
1685
+    IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \
1686
+  return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \
1687
+      f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \
1688
+} \
1689
+ \
1690
+/* For compatibility with older compilers we provide two overloads for pad, */ \
1691
+/* one that takes a fill character and one that doesn't. In the future this */ \
1692
+/* can be replaced with one overload making the template argument Char      */ \
1693
+/* default to char (C++11). */ \
1694
+template <char TYPE_CODE, typename Char> \
1695
+inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \
1696
+    IntFormatSpec<TYPE, TypeSpec<TYPE_CODE>, Char> f, \
1697
+    unsigned width, Char fill) { \
1698
+  return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \
1699
+      f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \
1700
+} \
1701
+ \
1702
+inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \
1703
+    TYPE value, unsigned width) { \
1704
+  return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \
1705
+      value, AlignTypeSpec<0>(width, ' ')); \
1706
+} \
1707
+ \
1708
+template <typename Char> \
1709
+inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \
1710
+   TYPE value, unsigned width, Char fill) { \
1711
+ return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \
1712
+     value, AlignTypeSpec<0>(width, fill)); \
1713
+}
1714
+
1715
+FMT_DEFINE_INT_FORMATTERS(int)
1716
+FMT_DEFINE_INT_FORMATTERS(long)
1717
+FMT_DEFINE_INT_FORMATTERS(unsigned)
1718
+FMT_DEFINE_INT_FORMATTERS(unsigned long)
1719
+FMT_DEFINE_INT_FORMATTERS(LongLong)
1720
+FMT_DEFINE_INT_FORMATTERS(ULongLong)
1721
+
1722
+/**
1723
+  \rst
1724
+  Returns a string formatter that pads the formatted argument with the fill
1725
+  character to the specified width using the default (left) string alignment.
1726
+
1727
+  **Example**::
1728
+
1729
+    std::string s = str(MemoryWriter() << pad("abc", 8));
1730
+    // s == "abc     "
1731
+
1732
+  \endrst
1733
+ */
1734
+template <typename Char>
1735
+inline StrFormatSpec<Char> pad(
1736
+    const Char *str, unsigned width, Char fill = ' ') {
1737
+  return StrFormatSpec<Char>(str, width, fill);
1738
+}
1739
+
1740
+inline StrFormatSpec<wchar_t> pad(
1741
+    const wchar_t *str, unsigned width, char fill = ' ') {
1742
+  return StrFormatSpec<wchar_t>(str, width, fill);
1743
+}
1744
+
1745
+namespace internal {
1746
+
1747
+template <typename Char>
1748
+class ArgMap {
1749
+ private:
1750
+  typedef std::vector<
1751
+    std::pair<fmt::BasicStringRef<Char>, internal::Arg> > MapType;
1752
+  typedef typename MapType::value_type Pair;
1753
+
1754
+  MapType map_;
1755
+
1756
+ public:
1757
+  FMT_API void init(const ArgList &args);
1758
+
1759
+  const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const {
1760
+    // The list is unsorted, so just return the first matching name.
1761
+    for (typename MapType::const_iterator it = map_.begin(), end = map_.end();
1762
+         it != end; ++it) {
1763
+      if (it->first == name)
1764
+        return &it->second;
1765
+    }
1766
+    return 0;
1767
+  }
1768
+};
1769
+
1770
+template <typename Impl, typename Char>
1771
+class ArgFormatterBase : public ArgVisitor<Impl, void> {
1772
+ private:
1773
+  BasicWriter<Char> &writer_;
1774
+  FormatSpec &spec_;
1775
+
1776
+  FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase);
1777
+
1778
+  void write_pointer(const void *p) {
1779
+    spec_.flags_ = HASH_FLAG;
1780
+    spec_.type_ = 'x';
1781
+    writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
1782
+  }
1783
+
1784
+ protected:
1785
+  BasicWriter<Char> &writer() { return writer_; }
1786
+  FormatSpec &spec() { return spec_; }
1787
+
1788
+  void write(bool value) {
1789
+    const char *str_value = value ? "true" : "false";
1790
+    Arg::StringValue<char> str = { str_value, std::strlen(str_value) };
1791
+    writer_.write_str(str, spec_);
1792
+  }
1793
+
1794
+  void write(const char *value) {
1795
+    Arg::StringValue<char> str = {value, value != 0 ? std::strlen(value) : 0};
1796
+    writer_.write_str(str, spec_);
1797
+  }
1798
+
1799
+ public:
1800
+  ArgFormatterBase(BasicWriter<Char> &w, FormatSpec &s)
1801
+  : writer_(w), spec_(s) {}
1802
+
1803
+  template <typename T>
1804
+  void visit_any_int(T value) { writer_.write_int(value, spec_); }
1805
+
1806
+  template <typename T>
1807
+  void visit_any_double(T value) { writer_.write_double(value, spec_); }
1808
+
1809
+  void visit_bool(bool value) {
1810
+    if (spec_.type_)
1811
+      return visit_any_int(value);
1812
+    write(value);
1813
+  }
1814
+
1815
+  void visit_char(int value) {
1816
+    if (spec_.type_ && spec_.type_ != 'c') {
1817
+      spec_.flags_ |= CHAR_FLAG;
1818
+      writer_.write_int(value, spec_);
1819
+      return;
1820
+    }
1821
+    if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
1822
+      FMT_THROW(FormatError("invalid format specifier for char"));
1823
+    typedef typename BasicWriter<Char>::CharPtr CharPtr;
1824
+    Char fill = internal::CharTraits<Char>::cast(spec_.fill());
1825
+    CharPtr out = CharPtr();
1826
+    const unsigned CHAR_WIDTH = 1;
1827
+    if (spec_.width_ > CHAR_WIDTH) {
1828
+      out = writer_.grow_buffer(spec_.width_);
1829
+      if (spec_.align_ == ALIGN_RIGHT) {
1830
+        std::uninitialized_fill_n(out, spec_.width_ - CHAR_WIDTH, fill);
1831
+        out += spec_.width_ - CHAR_WIDTH;
1832
+      } else if (spec_.align_ == ALIGN_CENTER) {
1833
+        out = writer_.fill_padding(out, spec_.width_,
1834
+                                   internal::check(CHAR_WIDTH), fill);
1835
+      } else {
1836
+        std::uninitialized_fill_n(out + CHAR_WIDTH,
1837
+                                  spec_.width_ - CHAR_WIDTH, fill);
1838
+      }
1839
+    } else {
1840
+      out = writer_.grow_buffer(CHAR_WIDTH);
1841
+    }
1842
+    *out = internal::CharTraits<Char>::cast(value);
1843
+  }
1844
+
1845
+  void visit_cstring(const char *value) {
1846
+    if (spec_.type_ == 'p')
1847
+      return write_pointer(value);
1848
+    write(value);
1849
+  }
1850
+
1851
+  void visit_string(Arg::StringValue<char> value) {
1852
+    writer_.write_str(value, spec_);
1853
+  }
1854
+
1855
+  using ArgVisitor<Impl, void>::visit_wstring;
1856
+
1857
+  void visit_wstring(Arg::StringValue<Char> value) {
1858
+    writer_.write_str(value, spec_);
1859
+  }
1860
+
1861
+  void visit_pointer(const void *value) {
1862
+    if (spec_.type_ && spec_.type_ != 'p')
1863
+      report_unknown_type(spec_.type_, "pointer");
1864
+    write_pointer(value);
1865
+  }
1866
+};
1867
+
1868
+class FormatterBase {
1869
+ private:
1870
+  ArgList args_;
1871
+  int next_arg_index_;
1872
+
1873
+  // Returns the argument with specified index.
1874
+  FMT_API Arg do_get_arg(unsigned arg_index, const char *&error);
1875
+
1876
+ protected:
1877
+  const ArgList &args() const { return args_; }
1878
+
1879
+  explicit FormatterBase(const ArgList &args) {
1880
+    args_ = args;
1881
+    next_arg_index_ = 0;
1882
+  }
1883
+
1884
+  // Returns the next argument.
1885
+  Arg next_arg(const char *&error) {
1886
+    if (next_arg_index_ >= 0)
1887
+      return do_get_arg(internal::to_unsigned(next_arg_index_++), error);
1888
+    error = "cannot switch from manual to automatic argument indexing";
1889
+    return Arg();
1890
+  }
1891
+
1892
+  // Checks if manual indexing is used and returns the argument with
1893
+  // specified index.
1894
+  Arg get_arg(unsigned arg_index, const char *&error) {
1895
+    return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg();
1896
+  }
1897
+
1898
+  bool check_no_auto_index(const char *&error) {
1899
+    if (next_arg_index_ > 0) {
1900
+      error = "cannot switch from automatic to manual argument indexing";
1901
+      return false;
1902
+    }
1903
+    next_arg_index_ = -1;
1904
+    return true;
1905
+  }
1906
+
1907
+  template <typename Char>
1908
+  void write(BasicWriter<Char> &w, const Char *start, const Char *end) {
1909
+    if (start != end)
1910
+      w << BasicStringRef<Char>(start, internal::to_unsigned(end - start));
1911
+  }
1912
+};
1913
+
1914
+// A printf formatter.
1915
+template <typename Char>
1916
+class PrintfFormatter : private FormatterBase {
1917
+ private:
1918
+  void parse_flags(FormatSpec &spec, const Char *&s);
1919
+
1920
+  // Returns the argument with specified index or, if arg_index is equal
1921
+  // to the maximum unsigned value, the next argument.
1922
+  Arg get_arg(const Char *s,
1923
+      unsigned arg_index = (std::numeric_limits<unsigned>::max)());
1924
+
1925
+  // Parses argument index, flags and width and returns the argument index.
1926
+  unsigned parse_header(const Char *&s, FormatSpec &spec);
1927
+
1928
+ public:
1929
+  explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {}
1930
+  FMT_API void format(BasicWriter<Char> &writer,
1931
+                      BasicCStringRef<Char> format_str);
1932
+};
1933
+}  // namespace internal
1934
+
1935
+/**
1936
+  \rst
1937
+  An argument formatter based on the `curiously recurring template pattern
1938
+  <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
1939
+
1940
+  To use `~fmt::BasicArgFormatter` define a subclass that implements some or
1941
+  all of the visit methods with the same signatures as the methods in
1942
+  `~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
1943
+  Pass the subclass as the *Impl* template parameter. When a formatting
1944
+  function processes an argument, it will dispatch to a visit method
1945
+  specific to the argument type. For example, if the argument type is
1946
+  ``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
1947
+  will be called. If the subclass doesn't contain a method with this signature,
1948
+  then a corresponding method of `~fmt::BasicArgFormatter` or its superclass
1949
+  will be called.
1950
+  \endrst
1951
+ */
1952
+template <typename Impl, typename Char>
1953
+class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
1954
+ private:
1955
+  BasicFormatter<Char, Impl> &formatter_;
1956
+  const Char *format_;
1957
+
1958
+ public:
1959
+  /**
1960
+    \rst
1961
+    Constructs an argument formatter object.
1962
+    *formatter* is a reference to the main formatter object, *spec* contains
1963
+    format specifier information for standard argument types, and *fmt* points
1964
+    to the part of the format string being parsed for custom argument types.
1965
+    \endrst
1966
+   */
1967
+  BasicArgFormatter(BasicFormatter<Char, Impl> &formatter,
1968
+                    FormatSpec &spec, const Char *fmt)
1969
+  : internal::ArgFormatterBase<Impl, Char>(formatter.writer(), spec),
1970
+    formatter_(formatter), format_(fmt) {}
1971
+
1972
+  /** Formats argument of a custom (user-defined) type. */
1973
+  void visit_custom(internal::Arg::CustomValue c) {
1974
+    c.format(&formatter_, c.value, &format_);
1975
+  }
1976
+};
1977
+
1978
+/** The default argument formatter. */
1979
+template <typename Char>
1980
+class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
1981
+ public:
1982
+  /** Constructs an argument formatter object. */
1983
+  ArgFormatter(BasicFormatter<Char> &formatter,
1984
+               FormatSpec &spec, const Char *fmt)
1985
+  : BasicArgFormatter<ArgFormatter<Char>, Char>(formatter, spec, fmt) {}
1986
+};
1987
+
1988
+/** This template formats data and writes the output to a writer. */
1989
+template <typename CharType, typename ArgFormatter>
1990
+class BasicFormatter : private internal::FormatterBase {
1991
+ public:
1992
+  /** The character type for the output. */
1993
+  typedef CharType Char;
1994
+
1995
+ private:
1996
+  BasicWriter<Char> &writer_;
1997
+  internal::ArgMap<Char> map_;
1998
+
1999
+  FMT_DISALLOW_COPY_AND_ASSIGN(BasicFormatter);
2000
+
2001
+  using internal::FormatterBase::get_arg;
2002
+
2003
+  // Checks if manual indexing is used and returns the argument with
2004
+  // specified name.
2005
+  internal::Arg get_arg(BasicStringRef<Char> arg_name, const char *&error);
2006
+
2007
+  // Parses argument index and returns corresponding argument.
2008
+  internal::Arg parse_arg_index(const Char *&s);
2009
+
2010
+  // Parses argument name and returns corresponding argument.
2011
+  internal::Arg parse_arg_name(const Char *&s);
2012
+
2013
+ public:
2014
+  /**
2015
+   \rst
2016
+   Constructs a ``BasicFormatter`` object. References to the arguments and
2017
+   the writer are stored in the formatter object so make sure they have
2018
+   appropriate lifetimes.
2019
+   \endrst
2020
+   */
2021
+  BasicFormatter(const ArgList &args, BasicWriter<Char> &w)
2022
+    : internal::FormatterBase(args), writer_(w) {}
2023
+
2024
+  /** Returns a reference to the writer associated with this formatter. */
2025
+  BasicWriter<Char> &writer() { return writer_; }
2026
+
2027
+  /** Formats stored arguments and writes the output to the writer. */
2028
+  void format(BasicCStringRef<Char> format_str);
2029
+
2030
+  // Formats a single argument and advances format_str, a format string pointer.
2031
+  const Char *format(const Char *&format_str, const internal::Arg &arg);
2032
+};
2033
+
2034
+// Generates a comma-separated list with results of applying f to
2035
+// numbers 0..n-1.
2036
+# define FMT_GEN(n, f) FMT_GEN##n(f)
2037
+# define FMT_GEN1(f)  f(0)
2038
+# define FMT_GEN2(f)  FMT_GEN1(f),  f(1)
2039
+# define FMT_GEN3(f)  FMT_GEN2(f),  f(2)
2040
+# define FMT_GEN4(f)  FMT_GEN3(f),  f(3)
2041
+# define FMT_GEN5(f)  FMT_GEN4(f),  f(4)
2042
+# define FMT_GEN6(f)  FMT_GEN5(f),  f(5)
2043
+# define FMT_GEN7(f)  FMT_GEN6(f),  f(6)
2044
+# define FMT_GEN8(f)  FMT_GEN7(f),  f(7)
2045
+# define FMT_GEN9(f)  FMT_GEN8(f),  f(8)
2046
+# define FMT_GEN10(f) FMT_GEN9(f),  f(9)
2047
+# define FMT_GEN11(f) FMT_GEN10(f), f(10)
2048
+# define FMT_GEN12(f) FMT_GEN11(f), f(11)
2049
+# define FMT_GEN13(f) FMT_GEN12(f), f(12)
2050
+# define FMT_GEN14(f) FMT_GEN13(f), f(13)
2051
+# define FMT_GEN15(f) FMT_GEN14(f), f(14)
2052
+
2053
+namespace internal {
2054
+inline uint64_t make_type() { return 0; }
2055
+
2056
+template <typename T>
2057
+inline uint64_t make_type(const T &arg) {
2058
+  return MakeValue< BasicFormatter<char> >::type(arg);
2059
+}
2060
+
2061
+template <unsigned N, bool/*IsPacked*/= (N < ArgList::MAX_PACKED_ARGS)>
2062
+struct ArgArray;
2063
+
2064
+template <unsigned N>
2065
+struct ArgArray<N, true/*IsPacked*/> {
2066
+  typedef Value Type[N > 0 ? N : 1];
2067
+  
2068
+  template <typename Formatter, typename T>
2069
+  static Value make(const T &value) {
2070
+#ifdef __clang__
2071
+    Value result = MakeValue<Formatter>(value);
2072
+    // Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang:
2073
+    // https://github.com/fmtlib/fmt/issues/276
2074
+    (void)result.custom.format;
2075
+    return result;
2076
+#else
2077
+    return MakeValue<Formatter>(value);
2078
+#endif
2079
+  }
2080
+};
2081
+
2082
+template <unsigned N>
2083
+struct ArgArray<N, false/*IsPacked*/> {
2084
+  typedef Arg Type[N + 1]; // +1 for the list end Arg::NONE
2085
+
2086
+  template <typename Formatter, typename T>
2087
+  static Arg make(const T &value) { return MakeArg<Formatter>(value); }
2088
+};
2089
+
2090
+#if FMT_USE_VARIADIC_TEMPLATES
2091
+template <typename Arg, typename... Args>
2092
+inline uint64_t make_type(const Arg &first, const Args & ... tail) {
2093
+  return make_type(first) | (make_type(tail...) << 4);
2094
+}
2095
+
2096
+#else
2097
+
2098
+struct ArgType {
2099
+  uint64_t type;
2100
+
2101
+  ArgType() : type(0) {}
2102
+
2103
+  template <typename T>
2104
+  ArgType(const T &arg) : type(make_type(arg)) {}
2105
+};
2106
+
2107
+# define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType()
2108
+
2109
+inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) {
2110
+  return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) |
2111
+      (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) |
2112
+      (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) |
2113
+      (t12.type << 48) | (t13.type << 52) | (t14.type << 56);
2114
+}
2115
+#endif
2116
+}  // namespace internal
2117
+
2118
+# define FMT_MAKE_TEMPLATE_ARG(n) typename T##n
2119
+# define FMT_MAKE_ARG_TYPE(n) T##n
2120
+# define FMT_MAKE_ARG(n) const T##n &v##n
2121
+# define FMT_ASSIGN_char(n) \
2122
+  arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<char> >(v##n)
2123
+# define FMT_ASSIGN_wchar_t(n) \
2124
+  arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<wchar_t> >(v##n)
2125
+
2126
+#if FMT_USE_VARIADIC_TEMPLATES
2127
+// Defines a variadic function returning void.
2128
+# define FMT_VARIADIC_VOID(func, arg_type) \
2129
+  template <typename... Args> \
2130
+  void func(arg_type arg0, const Args & ... args) { \
2131
+    typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
2132
+    typename ArgArray::Type array{ \
2133
+      ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
2134
+    func(arg0, fmt::ArgList(fmt::internal::make_type(args...), array)); \
2135
+  }
2136
+
2137
+// Defines a variadic constructor.
2138
+# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
2139
+  template <typename... Args> \
2140
+  ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
2141
+    typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
2142
+    typename ArgArray::Type array{ \
2143
+      ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
2144
+    func(arg0, arg1, fmt::ArgList(fmt::internal::make_type(args...), array)); \
2145
+  }
2146
+
2147
+#else
2148
+
2149
+# define FMT_MAKE_REF(n) \
2150
+  fmt::internal::MakeValue< fmt::BasicFormatter<Char> >(v##n)
2151
+# define FMT_MAKE_REF2(n) v##n
2152
+
2153
+// Defines a wrapper for a function taking one argument of type arg_type
2154
+// and n additional arguments of arbitrary types.
2155
+# define FMT_WRAP1(func, arg_type, n) \
2156
+  template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
2157
+  inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
2158
+    const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \
2159
+    func(arg1, fmt::ArgList( \
2160
+      fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \
2161
+  }
2162
+
2163
+// Emulates a variadic function returning void on a pre-C++11 compiler.
2164
+# define FMT_VARIADIC_VOID(func, arg_type) \
2165
+  inline void func(arg_type arg) { func(arg, fmt::ArgList()); } \
2166
+  FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \
2167
+  FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \
2168
+  FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \
2169
+  FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \
2170
+  FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10)
2171
+
2172
+# define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
2173
+  template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
2174
+  ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
2175
+    const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \
2176
+    func(arg0, arg1, fmt::ArgList( \
2177
+      fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \
2178
+  }
2179
+
2180
+// Emulates a variadic constructor on a pre-C++11 compiler.
2181
+# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
2182
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \
2183
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \
2184
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \
2185
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \
2186
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \
2187
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \
2188
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \
2189
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \
2190
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \
2191
+  FMT_CTOR(ctor, func, arg0_type, arg1_type, 10)
2192
+#endif
2193
+
2194
+// Generates a comma-separated list with results of applying f to pairs
2195
+// (argument, index).
2196
+#define FMT_FOR_EACH1(f, x0) f(x0, 0)
2197
+#define FMT_FOR_EACH2(f, x0, x1) \
2198
+  FMT_FOR_EACH1(f, x0), f(x1, 1)
2199
+#define FMT_FOR_EACH3(f, x0, x1, x2) \
2200
+  FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2)
2201
+#define FMT_FOR_EACH4(f, x0, x1, x2, x3) \
2202
+  FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3)
2203
+#define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \
2204
+  FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4)
2205
+#define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \
2206
+  FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5)
2207
+#define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \
2208
+  FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6)
2209
+#define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \
2210
+  FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7)
2211
+#define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \
2212
+  FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8)
2213
+#define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \
2214
+  FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
2215
+
2216
+/**
2217
+ An error returned by an operating system or a language runtime,
2218
+ for example a file opening error.
2219
+*/
2220
+class SystemError : public internal::RuntimeError {
2221
+ private:
2222
+  void init(int err_code, CStringRef format_str, ArgList args);
2223
+
2224
+ protected:
2225
+  int error_code_;
2226
+
2227
+  typedef char Char;  // For FMT_VARIADIC_CTOR.
2228
+
2229
+  SystemError() {}
2230
+
2231
+ public:
2232
+  /**
2233
+   \rst
2234
+   Constructs a :class:`fmt::SystemError` object with the description
2235
+   of the form
2236
+
2237
+   .. parsed-literal::
2238
+     *<message>*: *<system-message>*
2239
+
2240
+   where *<message>* is the formatted message and *<system-message>* is
2241
+   the system message corresponding to the error code.
2242
+   *error_code* is a system error code as given by ``errno``.
2243
+   If *error_code* is not a valid error code such as -1, the system message
2244
+   may look like "Unknown error -1" and is platform-dependent.
2245
+
2246
+   **Example**::
2247
+
2248
+     // This throws a SystemError with the description
2249
+     //   cannot open file 'madeup': No such file or directory
2250
+     // or similar (system message may vary).
2251
+     const char *filename = "madeup";
2252
+     std::FILE *file = std::fopen(filename, "r");
2253
+     if (!file)
2254
+       throw fmt::SystemError(errno, "cannot open file '{}'", filename);
2255
+   \endrst
2256
+  */
2257
+  SystemError(int error_code, CStringRef message) {
2258
+    init(error_code, message, ArgList());
2259
+  }
2260
+  FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef)
2261
+
2262
+  int error_code() const { return error_code_; }
2263
+};
2264
+
2265
+/**
2266
+  \rst
2267
+  This template provides operations for formatting and writing data into
2268
+  a character stream. The output is stored in a buffer provided by a subclass
2269
+  such as :class:`fmt::BasicMemoryWriter`.
2270
+
2271
+  You can use one of the following typedefs for common character types:
2272
+
2273
+  +---------+----------------------+
2274
+  | Type    | Definition           |
2275
+  +=========+======================+
2276
+  | Writer  | BasicWriter<char>    |
2277
+  +---------+----------------------+
2278
+  | WWriter | BasicWriter<wchar_t> |
2279
+  +---------+----------------------+
2280
+
2281
+  \endrst
2282
+ */
2283
+template <typename Char>
2284
+class BasicWriter {
2285
+ private:
2286
+  // Output buffer.
2287
+  Buffer<Char> &buffer_;
2288
+
2289
+  FMT_DISALLOW_COPY_AND_ASSIGN(BasicWriter);
2290
+
2291
+  typedef typename internal::CharTraits<Char>::CharPtr CharPtr;
2292
+
2293
+#if FMT_SECURE_SCL
2294
+  // Returns pointer value.
2295
+  static Char *get(CharPtr p) { return p.base(); }
2296
+#else
2297
+  static Char *get(Char *p) { return p; }
2298
+#endif
2299
+
2300
+  // Fills the padding around the content and returns the pointer to the
2301
+  // content area.
2302
+  static CharPtr fill_padding(CharPtr buffer,
2303
+      unsigned total_size, std::size_t content_size, wchar_t fill);
2304
+
2305
+  // Grows the buffer by n characters and returns a pointer to the newly
2306
+  // allocated area.
2307
+  CharPtr grow_buffer(std::size_t n) {
2308
+    std::size_t size = buffer_.size();
2309
+    buffer_.resize(size + n);
2310
+    return internal::make_ptr(&buffer_[size], n);
2311
+  }
2312
+
2313
+  // Writes an unsigned decimal integer.
2314
+  template <typename UInt>
2315
+  Char *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) {
2316
+    unsigned num_digits = internal::count_digits(value);
2317
+    Char *ptr = get(grow_buffer(prefix_size + num_digits));
2318
+    internal::format_decimal(ptr + prefix_size, value, num_digits);
2319
+    return ptr;
2320
+  }
2321
+
2322
+  // Writes a decimal integer.
2323
+  template <typename Int>
2324
+  void write_decimal(Int value) {
2325
+    typedef typename internal::IntTraits<Int>::MainType MainType;
2326
+    MainType abs_value = static_cast<MainType>(value);
2327
+    if (internal::is_negative(value)) {
2328
+      abs_value = 0 - abs_value;
2329
+      *write_unsigned_decimal(abs_value, 1) = '-';
2330
+    } else {
2331
+      write_unsigned_decimal(abs_value, 0);
2332
+    }
2333
+  }
2334
+
2335
+  // Prepare a buffer for integer formatting.
2336
+  CharPtr prepare_int_buffer(unsigned num_digits,
2337
+      const EmptySpec &, const char *prefix, unsigned prefix_size) {
2338
+    unsigned size = prefix_size + num_digits;
2339
+    CharPtr p = grow_buffer(size);
2340
+    std::uninitialized_copy(prefix, prefix + prefix_size, p);
2341
+    return p + size - 1;
2342
+  }
2343
+
2344
+  template <typename Spec>
2345
+  CharPtr prepare_int_buffer(unsigned num_digits,
2346
+    const Spec &spec, const char *prefix, unsigned prefix_size);
2347
+
2348
+  // Formats an integer.
2349
+  template <typename T, typename Spec>
2350
+  void write_int(T value, Spec spec);
2351
+
2352
+  // Formats a floating-point number (double or long double).
2353
+  template <typename T>
2354
+  void write_double(T value, const FormatSpec &spec);
2355
+
2356
+  // Writes a formatted string.
2357
+  template <typename StrChar>
2358
+  CharPtr write_str(const StrChar *s, std::size_t size, const AlignSpec &spec);
2359
+
2360
+  template <typename StrChar>
2361
+  void write_str(const internal::Arg::StringValue<StrChar> &str,
2362
+                 const FormatSpec &spec);
2363
+
2364
+  // This following methods are private to disallow writing wide characters
2365
+  // and strings to a char stream. If you want to print a wide string as a
2366
+  // pointer as std::ostream does, cast it to const void*.
2367
+  // Do not implement!
2368
+  void operator<<(typename internal::WCharHelper<wchar_t, Char>::Unsupported);
2369
+  void operator<<(
2370
+      typename internal::WCharHelper<const wchar_t *, Char>::Unsupported);
2371
+
2372
+  // Appends floating-point length specifier to the format string.
2373
+  // The second argument is only used for overload resolution.
2374
+  void append_float_length(Char *&format_ptr, long double) {
2375
+    *format_ptr++ = 'L';
2376
+  }
2377
+
2378
+  template<typename T>
2379
+  void append_float_length(Char *&, T) {}
2380
+
2381
+  template <typename Impl, typename Char_>
2382
+  friend class internal::ArgFormatterBase;
2383
+
2384
+  friend class internal::PrintfArgFormatter<Char>;
2385
+
2386
+ protected:
2387
+  /**
2388
+    Constructs a ``BasicWriter`` object.
2389
+   */
2390
+  explicit BasicWriter(Buffer<Char> &b) : buffer_(b) {}
2391
+
2392
+ public:
2393
+  /**
2394
+    \rst
2395
+    Destroys a ``BasicWriter`` object.
2396
+    \endrst
2397
+   */
2398
+  virtual ~BasicWriter() {}
2399
+
2400
+  /**
2401
+    Returns the total number of characters written.
2402
+   */
2403
+  std::size_t size() const { return buffer_.size(); }
2404
+
2405
+  /**
2406
+    Returns a pointer to the output buffer content. No terminating null
2407
+    character is appended.
2408
+   */
2409
+  const Char *data() const FMT_NOEXCEPT { return &buffer_[0]; }
2410
+
2411
+  /**
2412
+    Returns a pointer to the output buffer content with terminating null
2413
+    character appended.
2414
+   */
2415
+  const Char *c_str() const {
2416
+    std::size_t size = buffer_.size();
2417
+    buffer_.reserve(size + 1);
2418
+    buffer_[size] = '\0';
2419
+    return &buffer_[0];
2420
+  }
2421
+
2422
+  /**
2423
+    \rst
2424
+    Returns the content of the output buffer as an `std::string`.
2425
+    \endrst
2426
+   */
2427
+  std::basic_string<Char> str() const {
2428
+    return std::basic_string<Char>(&buffer_[0], buffer_.size());
2429
+  }
2430
+
2431
+  /**
2432
+    \rst
2433
+    Writes formatted data.
2434
+
2435
+    *args* is an argument list representing arbitrary arguments.
2436
+
2437
+    **Example**::
2438
+
2439
+       MemoryWriter out;
2440
+       out.write("Current point:\n");
2441
+       out.write("({:+f}, {:+f})", -3.14, 3.14);
2442
+
2443
+    This will write the following output to the ``out`` object:
2444
+
2445
+    .. code-block:: none
2446
+
2447
+       Current point:
2448
+       (-3.140000, +3.140000)
2449
+
2450
+    The output can be accessed using :func:`data()`, :func:`c_str` or
2451
+    :func:`str` methods.
2452
+
2453
+    See also :ref:`syntax`.
2454
+    \endrst
2455
+   */
2456
+  void write(BasicCStringRef<Char> format, ArgList args) {
2457
+    BasicFormatter<Char>(args, *this).format(format);
2458
+  }
2459
+  FMT_VARIADIC_VOID(write, BasicCStringRef<Char>)
2460
+
2461
+  BasicWriter &operator<<(int value) {
2462
+    write_decimal(value);
2463
+    return *this;
2464
+  }
2465
+  BasicWriter &operator<<(unsigned value) {
2466
+    return *this << IntFormatSpec<unsigned>(value);
2467
+  }
2468
+  BasicWriter &operator<<(long value) {
2469
+    write_decimal(value);
2470
+    return *this;
2471
+  }
2472
+  BasicWriter &operator<<(unsigned long value) {
2473
+    return *this << IntFormatSpec<unsigned long>(value);
2474
+  }
2475
+  BasicWriter &operator<<(LongLong value) {
2476
+    write_decimal(value);
2477
+    return *this;
2478
+  }
2479
+
2480
+  /**
2481
+    \rst
2482
+    Formats *value* and writes it to the stream.
2483
+    \endrst
2484
+   */
2485
+  BasicWriter &operator<<(ULongLong value) {
2486
+    return *this << IntFormatSpec<ULongLong>(value);
2487
+  }
2488
+
2489
+  BasicWriter &operator<<(double value) {
2490
+    write_double(value, FormatSpec());
2491
+    return *this;
2492
+  }
2493
+
2494
+  /**
2495
+    \rst
2496
+    Formats *value* using the general format for floating-point numbers
2497
+    (``'g'``) and writes it to the stream.
2498
+    \endrst
2499
+   */
2500
+  BasicWriter &operator<<(long double value) {
2501
+    write_double(value, FormatSpec());
2502
+    return *this;
2503
+  }
2504
+
2505
+  /**
2506
+    Writes a character to the stream.
2507
+   */
2508
+  BasicWriter &operator<<(char value) {
2509
+    buffer_.push_back(value);
2510
+    return *this;
2511
+  }
2512
+
2513
+  BasicWriter &operator<<(
2514
+      typename internal::WCharHelper<wchar_t, Char>::Supported value) {
2515
+    buffer_.push_back(value);
2516
+    return *this;
2517
+  }
2518
+
2519
+  /**
2520
+    \rst
2521
+    Writes *value* to the stream.
2522
+    \endrst
2523
+   */
2524
+  BasicWriter &operator<<(fmt::BasicStringRef<Char> value) {
2525
+    const Char *str = value.data();
2526
+    buffer_.append(str, str + value.size());
2527
+    return *this;
2528
+  }
2529
+
2530
+  BasicWriter &operator<<(
2531
+      typename internal::WCharHelper<StringRef, Char>::Supported value) {
2532
+    const char *str = value.data();
2533
+    buffer_.append(str, str + value.size());
2534
+    return *this;
2535
+  }
2536
+
2537
+  template <typename T, typename Spec, typename FillChar>
2538
+  BasicWriter &operator<<(IntFormatSpec<T, Spec, FillChar> spec) {
2539
+    internal::CharTraits<Char>::convert(FillChar());
2540
+    write_int(spec.value(), spec);
2541
+    return *this;
2542
+  }
2543
+
2544
+  template <typename StrChar>
2545
+  BasicWriter &operator<<(const StrFormatSpec<StrChar> &spec) {
2546
+    const StrChar *s = spec.str();
2547
+    write_str(s, std::char_traits<Char>::length(s), spec);
2548
+    return *this;
2549
+  }
2550
+
2551
+  void clear() FMT_NOEXCEPT { buffer_.clear(); }
2552
+
2553
+  Buffer<Char> &buffer() FMT_NOEXCEPT { return buffer_; }
2554
+};
2555
+
2556
+template <typename Char>
2557
+template <typename StrChar>
2558
+typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
2559
+      const StrChar *s, std::size_t size, const AlignSpec &spec) {
2560
+  CharPtr out = CharPtr();
2561
+  if (spec.width() > size) {
2562
+    out = grow_buffer(spec.width());
2563
+    Char fill = internal::CharTraits<Char>::cast(spec.fill());
2564
+    if (spec.align() == ALIGN_RIGHT) {
2565
+      std::uninitialized_fill_n(out, spec.width() - size, fill);
2566
+      out += spec.width() - size;
2567
+    } else if (spec.align() == ALIGN_CENTER) {
2568
+      out = fill_padding(out, spec.width(), size, fill);
2569
+    } else {
2570
+      std::uninitialized_fill_n(out + size, spec.width() - size, fill);
2571
+    }
2572
+  } else {
2573
+    out = grow_buffer(size);
2574
+  }
2575
+  std::uninitialized_copy(s, s + size, out);
2576
+  return out;
2577
+}
2578
+
2579
+template <typename Char>
2580
+template <typename StrChar>
2581
+void BasicWriter<Char>::write_str(
2582
+    const internal::Arg::StringValue<StrChar> &s, const FormatSpec &spec) {
2583
+  // Check if StrChar is convertible to Char.
2584
+  internal::CharTraits<Char>::convert(StrChar());
2585
+  if (spec.type_ && spec.type_ != 's')
2586
+    internal::report_unknown_type(spec.type_, "string");
2587
+  const StrChar *str_value = s.value;
2588
+  std::size_t str_size = s.size;
2589
+  if (str_size == 0) {
2590
+    if (!str_value) {
2591
+      FMT_THROW(FormatError("string pointer is null"));
2592
+      return;
2593
+    }
2594
+  }
2595
+  std::size_t precision = static_cast<std::size_t>(spec.precision_);
2596
+  if (spec.precision_ >= 0 && precision < str_size)
2597
+    str_size = precision;
2598
+  write_str(str_value, str_size, spec);
2599
+}
2600
+
2601
+template <typename Char>
2602
+typename BasicWriter<Char>::CharPtr
2603
+  BasicWriter<Char>::fill_padding(
2604
+    CharPtr buffer, unsigned total_size,
2605
+    std::size_t content_size, wchar_t fill) {
2606
+  std::size_t padding = total_size - content_size;
2607
+  std::size_t left_padding = padding / 2;
2608
+  Char fill_char = internal::CharTraits<Char>::cast(fill);
2609
+  std::uninitialized_fill_n(buffer, left_padding, fill_char);
2610
+  buffer += left_padding;
2611
+  CharPtr content = buffer;
2612
+  std::uninitialized_fill_n(buffer + content_size,
2613
+                            padding - left_padding, fill_char);
2614
+  return content;
2615
+}
2616
+
2617
+template <typename Char>
2618
+template <typename Spec>
2619
+typename BasicWriter<Char>::CharPtr
2620
+  BasicWriter<Char>::prepare_int_buffer(
2621
+    unsigned num_digits, const Spec &spec,
2622
+    const char *prefix, unsigned prefix_size) {
2623
+  unsigned width = spec.width();
2624
+  Alignment align = spec.align();
2625
+  Char fill = internal::CharTraits<Char>::cast(spec.fill());
2626
+  if (spec.precision() > static_cast<int>(num_digits)) {
2627
+    // Octal prefix '0' is counted as a digit, so ignore it if precision
2628
+    // is specified.
2629
+    if (prefix_size > 0 && prefix[prefix_size - 1] == '0')
2630
+      --prefix_size;
2631
+    unsigned number_size =
2632
+        prefix_size + internal::to_unsigned(spec.precision());
2633
+    AlignSpec subspec(number_size, '0', ALIGN_NUMERIC);
2634
+    if (number_size >= width)
2635
+      return prepare_int_buffer(num_digits, subspec, prefix, prefix_size);
2636
+    buffer_.reserve(width);
2637
+    unsigned fill_size = width - number_size;
2638
+    if (align != ALIGN_LEFT) {
2639
+      CharPtr p = grow_buffer(fill_size);
2640
+      std::uninitialized_fill(p, p + fill_size, fill);
2641
+    }
2642
+    CharPtr result = prepare_int_buffer(
2643
+        num_digits, subspec, prefix, prefix_size);
2644
+    if (align == ALIGN_LEFT) {
2645
+      CharPtr p = grow_buffer(fill_size);
2646
+      std::uninitialized_fill(p, p + fill_size, fill);
2647
+    }
2648
+    return result;
2649
+  }
2650
+  unsigned size = prefix_size + num_digits;
2651
+  if (width <= size) {
2652
+    CharPtr p = grow_buffer(size);
2653
+    std::uninitialized_copy(prefix, prefix + prefix_size, p);
2654
+    return p + size - 1;
2655
+  }
2656
+  CharPtr p = grow_buffer(width);
2657
+  CharPtr end = p + width;
2658
+  if (align == ALIGN_LEFT) {
2659
+    std::uninitialized_copy(prefix, prefix + prefix_size, p);
2660
+    p += size;
2661
+    std::uninitialized_fill(p, end, fill);
2662
+  } else if (align == ALIGN_CENTER) {
2663
+    p = fill_padding(p, width, size, fill);
2664
+    std::uninitialized_copy(prefix, prefix + prefix_size, p);
2665
+    p += size;
2666
+  } else {
2667
+    if (align == ALIGN_NUMERIC) {
2668
+      if (prefix_size != 0) {
2669
+        p = std::uninitialized_copy(prefix, prefix + prefix_size, p);
2670
+        size -= prefix_size;
2671
+      }
2672
+    } else {
2673
+      std::uninitialized_copy(prefix, prefix + prefix_size, end - size);
2674
+    }
2675
+    std::uninitialized_fill(p, end - size, fill);
2676
+    p = end;
2677
+  }
2678
+  return p - 1;
2679
+}
2680
+
2681
+template <typename Char>
2682
+template <typename T, typename Spec>
2683
+void BasicWriter<Char>::write_int(T value, Spec spec) {
2684
+  unsigned prefix_size = 0;
2685
+  typedef typename internal::IntTraits<T>::MainType UnsignedType;
2686
+  UnsignedType abs_value = static_cast<UnsignedType>(value);
2687
+  char prefix[4] = "";
2688
+  if (internal::is_negative(value)) {
2689
+    prefix[0] = '-';
2690
+    ++prefix_size;
2691
+    abs_value = 0 - abs_value;
2692
+  } else if (spec.flag(SIGN_FLAG)) {
2693
+    prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' ';
2694
+    ++prefix_size;
2695
+  }
2696
+  switch (spec.type()) {
2697
+  case 0: case 'd': {
2698
+    unsigned num_digits = internal::count_digits(abs_value);
2699
+    CharPtr p = prepare_int_buffer(num_digits, spec, prefix, prefix_size) + 1;
2700
+    internal::format_decimal(get(p), abs_value, 0);
2701
+    break;
2702
+  }
2703
+  case 'x': case 'X': {
2704
+    UnsignedType n = abs_value;
2705
+    if (spec.flag(HASH_FLAG)) {
2706
+      prefix[prefix_size++] = '0';
2707
+      prefix[prefix_size++] = spec.type();
2708
+    }
2709
+    unsigned num_digits = 0;
2710
+    do {
2711
+      ++num_digits;
2712
+    } while ((n >>= 4) != 0);
2713
+    Char *p = get(prepare_int_buffer(
2714
+      num_digits, spec, prefix, prefix_size));
2715
+    n = abs_value;
2716
+    const char *digits = spec.type() == 'x' ?
2717
+        "0123456789abcdef" : "0123456789ABCDEF";
2718
+    do {
2719
+      *p-- = digits[n & 0xf];
2720
+    } while ((n >>= 4) != 0);
2721
+    break;
2722
+  }
2723
+  case 'b': case 'B': {
2724
+    UnsignedType n = abs_value;
2725
+    if (spec.flag(HASH_FLAG)) {
2726
+      prefix[prefix_size++] = '0';
2727
+      prefix[prefix_size++] = spec.type();
2728
+    }
2729
+    unsigned num_digits = 0;
2730
+    do {
2731
+      ++num_digits;
2732
+    } while ((n >>= 1) != 0);
2733
+    Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2734
+    n = abs_value;
2735
+    do {
2736
+      *p-- = static_cast<Char>('0' + (n & 1));
2737
+    } while ((n >>= 1) != 0);
2738
+    break;
2739
+  }
2740
+  case 'o': {
2741
+    UnsignedType n = abs_value;
2742
+    if (spec.flag(HASH_FLAG))
2743
+      prefix[prefix_size++] = '0';
2744
+    unsigned num_digits = 0;
2745
+    do {
2746
+      ++num_digits;
2747
+    } while ((n >>= 3) != 0);
2748
+    Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
2749
+    n = abs_value;
2750
+    do {
2751
+      *p-- = static_cast<Char>('0' + (n & 7));
2752
+    } while ((n >>= 3) != 0);
2753
+    break;
2754
+  }
2755
+  case 'n': {
2756
+    unsigned num_digits = internal::count_digits(abs_value);
2757
+    fmt::StringRef sep = std::localeconv()->thousands_sep;
2758
+    unsigned size = static_cast<unsigned>(
2759
+          num_digits + sep.size() * (num_digits - 1) / 3);
2760
+    CharPtr p = prepare_int_buffer(size, spec, prefix, prefix_size) + 1;
2761
+    internal::format_decimal(get(p), abs_value, 0, internal::ThousandsSep(sep));
2762
+    break;
2763
+  }
2764
+  default:
2765
+    internal::report_unknown_type(
2766
+      spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer");
2767
+    break;
2768
+  }
2769
+}
2770
+
2771
+template <typename Char>
2772
+template <typename T>
2773
+void BasicWriter<Char>::write_double(T value, const FormatSpec &spec) {
2774
+  // Check type.
2775
+  char type = spec.type();
2776
+  bool upper = false;
2777
+  switch (type) {
2778
+  case 0:
2779
+    type = 'g';
2780
+    break;
2781
+  case 'e': case 'f': case 'g': case 'a':
2782
+    break;
2783
+  case 'F':
2784
+#ifdef _MSC_VER
2785
+    // MSVC's printf doesn't support 'F'.
2786
+    type = 'f';
2787
+#endif
2788
+    // Fall through.
2789
+  case 'E': case 'G': case 'A':
2790
+    upper = true;
2791
+    break;
2792
+  default:
2793
+    internal::report_unknown_type(type, "double");
2794
+    break;
2795
+  }
2796
+
2797
+  char sign = 0;
2798
+  // Use isnegative instead of value < 0 because the latter is always
2799
+  // false for NaN.
2800
+  if (internal::FPUtil::isnegative(static_cast<double>(value))) {
2801
+    sign = '-';
2802
+    value = -value;
2803
+  } else if (spec.flag(SIGN_FLAG)) {
2804
+    sign = spec.flag(PLUS_FLAG) ? '+' : ' ';
2805
+  }
2806
+
2807
+  if (internal::FPUtil::isnotanumber(value)) {
2808
+    // Format NaN ourselves because sprintf's output is not consistent
2809
+    // across platforms.
2810
+    std::size_t nan_size = 4;
2811
+    const char *nan = upper ? " NAN" : " nan";
2812
+    if (!sign) {
2813
+      --nan_size;
2814
+      ++nan;
2815
+    }
2816
+    CharPtr out = write_str(nan, nan_size, spec);
2817
+    if (sign)
2818
+      *out = sign;
2819
+    return;
2820
+  }
2821
+
2822
+  if (internal::FPUtil::isinfinity(value)) {
2823
+    // Format infinity ourselves because sprintf's output is not consistent
2824
+    // across platforms.
2825
+    std::size_t inf_size = 4;
2826
+    const char *inf = upper ? " INF" : " inf";
2827
+    if (!sign) {
2828
+      --inf_size;
2829
+      ++inf;
2830
+    }
2831
+    CharPtr out = write_str(inf, inf_size, spec);
2832
+    if (sign)
2833
+      *out = sign;
2834
+    return;
2835
+  }
2836
+
2837
+  std::size_t offset = buffer_.size();
2838
+  unsigned width = spec.width();
2839
+  if (sign) {
2840
+    buffer_.reserve(buffer_.size() + (width > 1u ? width : 1u));
2841
+    if (width > 0)
2842
+      --width;
2843
+    ++offset;
2844
+  }
2845
+
2846
+  // Build format string.
2847
+  enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg
2848
+  Char format[MAX_FORMAT_SIZE];
2849
+  Char *format_ptr = format;
2850
+  *format_ptr++ = '%';
2851
+  unsigned width_for_sprintf = width;
2852
+  if (spec.flag(HASH_FLAG))
2853
+    *format_ptr++ = '#';
2854
+  if (spec.align() == ALIGN_CENTER) {
2855
+    width_for_sprintf = 0;
2856
+  } else {
2857
+    if (spec.align() == ALIGN_LEFT)
2858
+      *format_ptr++ = '-';
2859
+    if (width != 0)
2860
+      *format_ptr++ = '*';
2861
+  }
2862
+  if (spec.precision() >= 0) {
2863
+    *format_ptr++ = '.';
2864
+    *format_ptr++ = '*';
2865
+  }
2866
+
2867
+  append_float_length(format_ptr, value);
2868
+  *format_ptr++ = type;
2869
+  *format_ptr = '\0';
2870
+
2871
+  // Format using snprintf.
2872
+  Char fill = internal::CharTraits<Char>::cast(spec.fill());
2873
+  unsigned n = 0;
2874
+  Char *start = 0;
2875
+  for (;;) {
2876
+    std::size_t buffer_size = buffer_.capacity() - offset;
2877
+#ifdef _MSC_VER
2878
+    // MSVC's vsnprintf_s doesn't work with zero size, so reserve
2879
+    // space for at least one extra character to make the size non-zero.
2880
+    // Note that the buffer's capacity will increase by more than 1.
2881
+    if (buffer_size == 0) {
2882
+      buffer_.reserve(offset + 1);
2883
+      buffer_size = buffer_.capacity() - offset;
2884
+    }
2885
+#endif
2886
+    start = &buffer_[offset];
2887
+    int result = internal::CharTraits<Char>::format_float(
2888
+        start, buffer_size, format, width_for_sprintf, spec.precision(), value);
2889
+    if (result >= 0) {
2890
+      n = internal::to_unsigned(result);
2891
+      if (offset + n < buffer_.capacity())
2892
+        break;  // The buffer is large enough - continue with formatting.
2893
+      buffer_.reserve(offset + n + 1);
2894
+    } else {
2895
+      // If result is negative we ask to increase the capacity by at least 1,
2896
+      // but as std::vector, the buffer grows exponentially.
2897
+      buffer_.reserve(buffer_.capacity() + 1);
2898
+    }
2899
+  }
2900
+  if (sign) {
2901
+    if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) ||
2902
+        *start != ' ') {
2903
+      *(start - 1) = sign;
2904
+      sign = 0;
2905
+    } else {
2906
+      *(start - 1) = fill;
2907
+    }
2908
+    ++n;
2909
+  }
2910
+  if (spec.align() == ALIGN_CENTER && spec.width() > n) {
2911
+    width = spec.width();
2912
+    CharPtr p = grow_buffer(width);
2913
+    std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char));
2914
+    fill_padding(p, spec.width(), n, fill);
2915
+    return;
2916
+  }
2917
+  if (spec.fill() != ' ' || sign) {
2918
+    while (*start == ' ')
2919
+      *start++ = fill;
2920
+    if (sign)
2921
+      *(start - 1) = sign;
2922
+  }
2923
+  grow_buffer(n);
2924
+}
2925
+
2926
+/**
2927
+  \rst
2928
+  This class template provides operations for formatting and writing data
2929
+  into a character stream. The output is stored in a memory buffer that grows
2930
+  dynamically.
2931
+
2932
+  You can use one of the following typedefs for common character types
2933
+  and the standard allocator:
2934
+
2935
+  +---------------+-----------------------------------------------------+
2936
+  | Type          | Definition                                          |
2937
+  +===============+=====================================================+
2938
+  | MemoryWriter  | BasicMemoryWriter<char, std::allocator<char>>       |
2939
+  +---------------+-----------------------------------------------------+
2940
+  | WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> |
2941
+  +---------------+-----------------------------------------------------+
2942
+
2943
+  **Example**::
2944
+
2945
+     MemoryWriter out;
2946
+     out << "The answer is " << 42 << "\n";
2947
+     out.write("({:+f}, {:+f})", -3.14, 3.14);
2948
+
2949
+  This will write the following output to the ``out`` object:
2950
+
2951
+  .. code-block:: none
2952
+
2953
+     The answer is 42
2954
+     (-3.140000, +3.140000)
2955
+
2956
+  The output can be converted to an ``std::string`` with ``out.str()`` or
2957
+  accessed as a C string with ``out.c_str()``.
2958
+  \endrst
2959
+ */
2960
+template <typename Char, typename Allocator = std::allocator<Char> >
2961
+class BasicMemoryWriter : public BasicWriter<Char> {
2962
+ private:
2963
+  internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE, Allocator> buffer_;
2964
+
2965
+ public:
2966
+  explicit BasicMemoryWriter(const Allocator& alloc = Allocator())
2967
+    : BasicWriter<Char>(buffer_), buffer_(alloc) {}
2968
+
2969
+#if FMT_USE_RVALUE_REFERENCES
2970
+  /**
2971
+    \rst
2972
+    Constructs a :class:`fmt::BasicMemoryWriter` object moving the content
2973
+    of the other object to it.
2974
+    \endrst
2975
+   */
2976
+  BasicMemoryWriter(BasicMemoryWriter &&other)
2977
+    : BasicWriter<Char>(buffer_), buffer_(std::move(other.buffer_)) {
2978
+  }
2979
+
2980
+  /**
2981
+    \rst
2982
+    Moves the content of the other ``BasicMemoryWriter`` object to this one.
2983
+    \endrst
2984
+   */
2985
+  BasicMemoryWriter &operator=(BasicMemoryWriter &&other) {
2986
+    buffer_ = std::move(other.buffer_);
2987
+    return *this;
2988
+  }
2989
+#endif
2990
+};
2991
+
2992
+typedef BasicMemoryWriter<char> MemoryWriter;
2993
+typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
2994
+
2995
+/**
2996
+  \rst
2997
+  This class template provides operations for formatting and writing data
2998
+  into a fixed-size array. For writing into a dynamically growing buffer
2999
+  use :class:`fmt::BasicMemoryWriter`.
3000
+
3001
+  Any write method will throw ``std::runtime_error`` if the output doesn't fit
3002
+  into the array.
3003
+
3004
+  You can use one of the following typedefs for common character types:
3005
+
3006
+  +--------------+---------------------------+
3007
+  | Type         | Definition                |
3008
+  +==============+===========================+
3009
+  | ArrayWriter  | BasicArrayWriter<char>    |
3010
+  +--------------+---------------------------+
3011
+  | WArrayWriter | BasicArrayWriter<wchar_t> |
3012
+  +--------------+---------------------------+
3013
+  \endrst
3014
+ */
3015
+template <typename Char>
3016
+class BasicArrayWriter : public BasicWriter<Char> {
3017
+ private:
3018
+  internal::FixedBuffer<Char> buffer_;
3019
+
3020
+ public:
3021
+  /**
3022
+   \rst
3023
+   Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
3024
+   given size.
3025
+   \endrst
3026
+   */
3027
+  BasicArrayWriter(Char *array, std::size_t size)
3028
+    : BasicWriter<Char>(buffer_), buffer_(array, size) {}
3029
+
3030
+  /**
3031
+   \rst
3032
+   Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
3033
+   size known at compile time.
3034
+   \endrst
3035
+   */
3036
+  template <std::size_t SIZE>
3037
+  explicit BasicArrayWriter(Char (&array)[SIZE])
3038
+    : BasicWriter<Char>(buffer_), buffer_(array, SIZE) {}
3039
+};
3040
+
3041
+typedef BasicArrayWriter<char> ArrayWriter;
3042
+typedef BasicArrayWriter<wchar_t> WArrayWriter;
3043
+
3044
+// Reports a system error without throwing an exception.
3045
+// Can be used to report errors from destructors.
3046
+FMT_API void report_system_error(int error_code,
3047
+                                 StringRef message) FMT_NOEXCEPT;
3048
+
3049
+#if FMT_USE_WINDOWS_H
3050
+
3051
+/** A Windows error. */
3052
+class WindowsError : public SystemError {
3053
+ private:
3054
+  FMT_API void init(int error_code, CStringRef format_str, ArgList args);
3055
+
3056
+ public:
3057
+  /**
3058
+   \rst
3059
+   Constructs a :class:`fmt::WindowsError` object with the description
3060
+   of the form
3061
+
3062
+   .. parsed-literal::
3063
+     *<message>*: *<system-message>*
3064
+
3065
+   where *<message>* is the formatted message and *<system-message>* is the
3066
+   system message corresponding to the error code.
3067
+   *error_code* is a Windows error code as given by ``GetLastError``.
3068
+   If *error_code* is not a valid error code such as -1, the system message
3069
+   will look like "error -1".
3070
+
3071
+   **Example**::
3072
+
3073
+     // This throws a WindowsError with the description
3074
+     //   cannot open file 'madeup': The system cannot find the file specified.
3075
+     // or similar (system message may vary).
3076
+     const char *filename = "madeup";
3077
+     LPOFSTRUCT of = LPOFSTRUCT();
3078
+     HFILE file = OpenFile(filename, &of, OF_READ);
3079
+     if (file == HFILE_ERROR) {
3080
+       throw fmt::WindowsError(GetLastError(),
3081
+                               "cannot open file '{}'", filename);
3082
+     }
3083
+   \endrst
3084
+  */
3085
+  WindowsError(int error_code, CStringRef message) {
3086
+    init(error_code, message, ArgList());
3087
+  }
3088
+  FMT_VARIADIC_CTOR(WindowsError, init, int, CStringRef)
3089
+};
3090
+
3091
+// Reports a Windows error without throwing an exception.
3092
+// Can be used to report errors from destructors.
3093
+FMT_API void report_windows_error(int error_code,
3094
+                                  StringRef message) FMT_NOEXCEPT;
3095
+
3096
+#endif
3097
+
3098
+enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
3099
+
3100
+/**
3101
+  Formats a string and prints it to stdout using ANSI escape sequences
3102
+  to specify color (experimental).
3103
+  Example:
3104
+    print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23);
3105
+ */
3106
+FMT_API void print_colored(Color c, CStringRef format, ArgList args);
3107
+
3108
+/**
3109
+  \rst
3110
+  Formats arguments and returns the result as a string.
3111
+
3112
+  **Example**::
3113
+
3114
+    std::string message = format("The answer is {}", 42);
3115
+  \endrst
3116
+*/
3117
+inline std::string format(CStringRef format_str, ArgList args) {
3118
+  MemoryWriter w;
3119
+  w.write(format_str, args);
3120
+  return w.str();
3121
+}
3122
+
3123
+inline std::wstring format(WCStringRef format_str, ArgList args) {
3124
+  WMemoryWriter w;
3125
+  w.write(format_str, args);
3126
+  return w.str();
3127
+}
3128
+
3129
+/**
3130
+  \rst
3131
+  Prints formatted data to the file *f*.
3132
+
3133
+  **Example**::
3134
+
3135
+    print(stderr, "Don't {}!", "panic");
3136
+  \endrst
3137
+ */
3138
+FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args);
3139
+
3140
+/**
3141
+  \rst
3142
+  Prints formatted data to ``stdout``.
3143
+
3144
+  **Example**::
3145
+
3146
+    print("Elapsed time: {0:.2f} seconds", 1.23);
3147
+  \endrst
3148
+ */
3149
+FMT_API void print(CStringRef format_str, ArgList args);
3150
+
3151
+template <typename Char>
3152
+void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
3153
+  internal::PrintfFormatter<Char>(args).format(w, format);
3154
+}
3155
+
3156
+/**
3157
+  \rst
3158
+  Formats arguments and returns the result as a string.
3159
+
3160
+  **Example**::
3161
+
3162
+    std::string message = fmt::sprintf("The answer is %d", 42);
3163
+  \endrst
3164
+*/
3165
+inline std::string sprintf(CStringRef format, ArgList args) {
3166
+  MemoryWriter w;
3167
+  printf(w, format, args);
3168
+  return w.str();
3169
+}
3170
+
3171
+inline std::wstring sprintf(WCStringRef format, ArgList args) {
3172
+  WMemoryWriter w;
3173
+  printf(w, format, args);
3174
+  return w.str();
3175
+}
3176
+
3177
+/**
3178
+  \rst
3179
+  Prints formatted data to the file *f*.
3180
+
3181
+  **Example**::
3182
+
3183
+    fmt::fprintf(stderr, "Don't %s!", "panic");
3184
+  \endrst
3185
+ */
3186
+FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args);
3187
+
3188
+/**
3189
+  \rst
3190
+  Prints formatted data to ``stdout``.
3191
+
3192
+  **Example**::
3193
+
3194
+    fmt::printf("Elapsed time: %.2f seconds", 1.23);
3195
+  \endrst
3196
+ */
3197
+inline int printf(CStringRef format, ArgList args) {
3198
+  return fprintf(stdout, format, args);
3199
+}
3200
+
3201
+/**
3202
+  Fast integer formatter.
3203
+ */
3204
+class FormatInt {
3205
+ private:
3206
+  // Buffer should be large enough to hold all digits (digits10 + 1),
3207
+  // a sign and a null character.
3208
+  enum {BUFFER_SIZE = std::numeric_limits<ULongLong>::digits10 + 3};
3209
+  mutable char buffer_[BUFFER_SIZE];
3210
+  char *str_;
3211
+
3212
+  // Formats value in reverse and returns the number of digits.
3213
+  char *format_decimal(ULongLong value) {
3214
+    char *buffer_end = buffer_ + BUFFER_SIZE - 1;
3215
+    while (value >= 100) {
3216
+      // Integer division is slow so do it for a group of two digits instead
3217
+      // of for every digit. The idea comes from the talk by Alexandrescu
3218
+      // "Three Optimization Tips for C++". See speed-test for a comparison.
3219
+      unsigned index = static_cast<unsigned>((value % 100) * 2);
3220
+      value /= 100;
3221
+      *--buffer_end = internal::Data::DIGITS[index + 1];
3222
+      *--buffer_end = internal::Data::DIGITS[index];
3223
+    }
3224
+    if (value < 10) {
3225
+      *--buffer_end = static_cast<char>('0' + value);
3226
+      return buffer_end;
3227
+    }
3228
+    unsigned index = static_cast<unsigned>(value * 2);
3229
+    *--buffer_end = internal::Data::DIGITS[index + 1];
3230
+    *--buffer_end = internal::Data::DIGITS[index];
3231
+    return buffer_end;
3232
+  }
3233
+
3234
+  void FormatSigned(LongLong value) {
3235
+    ULongLong abs_value = static_cast<ULongLong>(value);
3236
+    bool negative = value < 0;
3237
+    if (negative)
3238
+      abs_value = 0 - abs_value;
3239
+    str_ = format_decimal(abs_value);
3240
+    if (negative)
3241
+      *--str_ = '-';
3242
+  }
3243
+
3244
+ public:
3245
+  explicit FormatInt(int value) { FormatSigned(value); }
3246
+  explicit FormatInt(long value) { FormatSigned(value); }
3247
+  explicit FormatInt(LongLong value) { FormatSigned(value); }
3248
+  explicit FormatInt(unsigned value) : str_(format_decimal(value)) {}
3249
+  explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {}
3250
+  explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {}
3251
+
3252
+  /** Returns the number of characters written to the output buffer. */
3253
+  std::size_t size() const {
3254
+    return internal::to_unsigned(buffer_ - str_ + BUFFER_SIZE - 1);
3255
+  }
3256
+
3257
+  /**
3258
+    Returns a pointer to the output buffer content. No terminating null
3259
+    character is appended.
3260
+   */
3261
+  const char *data() const { return str_; }
3262
+
3263
+  /**
3264
+    Returns a pointer to the output buffer content with terminating null
3265
+    character appended.
3266
+   */
3267
+  const char *c_str() const {
3268
+    buffer_[BUFFER_SIZE - 1] = '\0';
3269
+    return str_;
3270
+  }
3271
+
3272
+  /**
3273
+    \rst
3274
+    Returns the content of the output buffer as an ``std::string``.
3275
+    \endrst
3276
+   */
3277
+  std::string str() const { return std::string(str_, size()); }
3278
+};
3279
+
3280
+// Formats a decimal integer value writing into buffer and returns
3281
+// a pointer to the end of the formatted string. This function doesn't
3282
+// write a terminating null character.
3283
+template <typename T>
3284
+inline void format_decimal(char *&buffer, T value) {
3285
+  typedef typename internal::IntTraits<T>::MainType MainType;
3286
+  MainType abs_value = static_cast<MainType>(value);
3287
+  if (internal::is_negative(value)) {
3288
+    *buffer++ = '-';
3289
+    abs_value = 0 - abs_value;
3290
+  }
3291
+  if (abs_value < 100) {
3292
+    if (abs_value < 10) {
3293
+      *buffer++ = static_cast<char>('0' + abs_value);
3294
+      return;
3295
+    }
3296
+    unsigned index = static_cast<unsigned>(abs_value * 2);
3297
+    *buffer++ = internal::Data::DIGITS[index];
3298
+    *buffer++ = internal::Data::DIGITS[index + 1];
3299
+    return;
3300
+  }
3301
+  unsigned num_digits = internal::count_digits(abs_value);
3302
+  internal::format_decimal(buffer, abs_value, num_digits);
3303
+  buffer += num_digits;
3304
+}
3305
+
3306
+/**
3307
+  \rst
3308
+  Returns a named argument for formatting functions.
3309
+
3310
+  **Example**::
3311
+
3312
+    print("Elapsed time: {s:.2f} seconds", arg("s", 1.23));
3313
+
3314
+  \endrst
3315
+ */
3316
+template <typename T>
3317
+inline internal::NamedArg<char> arg(StringRef name, const T &arg) {
3318
+  return internal::NamedArg<char>(name, arg);
3319
+}
3320
+
3321
+template <typename T>
3322
+inline internal::NamedArg<wchar_t> arg(WStringRef name, const T &arg) {
3323
+  return internal::NamedArg<wchar_t>(name, arg);
3324
+}
3325
+
3326
+// The following two functions are deleted intentionally to disable
3327
+// nested named arguments as in ``format("{}", arg("a", arg("b", 42)))``.
3328
+template <typename Char>
3329
+void arg(StringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
3330
+template <typename Char>
3331
+void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
3332
+}
3333
+
3334
+#if FMT_GCC_VERSION
3335
+// Use the system_header pragma to suppress warnings about variadic macros
3336
+// because suppressing -Wvariadic-macros with the diagnostic pragma doesn't
3337
+// work. It is used at the end because we want to suppress as little warnings
3338
+// as possible.
3339
+# pragma GCC system_header
3340
+#endif
3341
+
3342
+// This is used to work around VC++ bugs in handling variadic macros.
3343
+#define FMT_EXPAND(args) args
3344
+
3345
+// Returns the number of arguments.
3346
+// Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s.
3347
+#define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N())
3348
+#define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__))
3349
+#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
3350
+#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
3351
+
3352
+#define FMT_CONCAT(a, b) a##b
3353
+#define FMT_FOR_EACH_(N, f, ...) \
3354
+  FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
3355
+#define FMT_FOR_EACH(f, ...) \
3356
+  FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__))
3357
+
3358
+#define FMT_ADD_ARG_NAME(type, index) type arg##index
3359
+#define FMT_GET_ARG_NAME(type, index) arg##index
3360
+
3361
+#if FMT_USE_VARIADIC_TEMPLATES
3362
+# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
3363
+  template <typename... Args> \
3364
+  ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
3365
+      const Args & ... args) { \
3366
+    typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray; \
3367
+    typename ArgArray::Type array{ \
3368
+      ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
3369
+    call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
3370
+      fmt::ArgList(fmt::internal::make_type(args...), array)); \
3371
+  }
3372
+#else
3373
+// Defines a wrapper for a function taking __VA_ARGS__ arguments
3374
+// and n additional arguments of arbitrary types.
3375
+# define FMT_WRAP(Char, ReturnType, func, call, n, ...) \
3376
+  template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
3377
+  inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
3378
+      FMT_GEN(n, FMT_MAKE_ARG)) { \
3379
+    fmt::internal::ArgArray<n>::Type arr; \
3380
+    FMT_GEN(n, FMT_ASSIGN_##Char); \
3381
+    call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \
3382
+      fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \
3383
+  }
3384
+
3385
+# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
3386
+  inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \
3387
+    call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \
3388
+  } \
3389
+  FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \
3390
+  FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \
3391
+  FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \
3392
+  FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \
3393
+  FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \
3394
+  FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \
3395
+  FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \
3396
+  FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \
3397
+  FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \
3398
+  FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \
3399
+  FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \
3400
+  FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \
3401
+  FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \
3402
+  FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \
3403
+  FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__)
3404
+#endif  // FMT_USE_VARIADIC_TEMPLATES
3405
+
3406
+/**
3407
+  \rst
3408
+  Defines a variadic function with the specified return type, function name
3409
+  and argument types passed as variable arguments to this macro.
3410
+
3411
+  **Example**::
3412
+
3413
+    void print_error(const char *file, int line, const char *format,
3414
+                     fmt::ArgList args) {
3415
+      fmt::print("{}: {}: ", file, line);
3416
+      fmt::print(format, args);
3417
+    }
3418
+    FMT_VARIADIC(void, print_error, const char *, int, const char *)
3419
+
3420
+  ``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that
3421
+  don't implement variadic templates. You don't have to use this macro if
3422
+  you don't need legacy compiler support and can use variadic templates
3423
+  directly::
3424
+
3425
+    template <typename... Args>
3426
+    void print_error(const char *file, int line, const char *format,
3427
+                     const Args & ... args) {
3428
+      fmt::print("{}: {}: ", file, line);
3429
+      fmt::print(format, args...);
3430
+    }
3431
+  \endrst
3432
+ */
3433
+#define FMT_VARIADIC(ReturnType, func, ...) \
3434
+  FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
3435
+
3436
+#define FMT_VARIADIC_W(ReturnType, func, ...) \
3437
+  FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__)
3438
+
3439
+#define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id)
3440
+
3441
+#define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id)
3442
+
3443
+/**
3444
+  \rst
3445
+  Convenient macro to capture the arguments' names and values into several
3446
+  ``fmt::arg(name, value)``.
3447
+
3448
+  **Example**::
3449
+
3450
+    int x = 1, y = 2;
3451
+    print("point: ({x}, {y})", FMT_CAPTURE(x, y));
3452
+    // same as:
3453
+    // print("point: ({x}, {y})", arg("x", x), arg("y", y));
3454
+
3455
+  \endrst
3456
+ */
3457
+#define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__)
3458
+
3459
+#define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__)
3460
+
3461
+namespace fmt {
3462
+FMT_VARIADIC(std::string, format, CStringRef)
3463
+FMT_VARIADIC_W(std::wstring, format, WCStringRef)
3464
+FMT_VARIADIC(void, print, CStringRef)
3465
+FMT_VARIADIC(void, print, std::FILE *, CStringRef)
3466
+
3467
+FMT_VARIADIC(void, print_colored, Color, CStringRef)
3468
+FMT_VARIADIC(std::string, sprintf, CStringRef)
3469
+FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef)
3470
+FMT_VARIADIC(int, printf, CStringRef)
3471
+FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
3472
+
3473
+namespace internal {
3474
+template <typename Char>
3475
+inline bool is_name_start(Char c) {
3476
+  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
3477
+}
3478
+
3479
+// Parses an unsigned integer advancing s to the end of the parsed input.
3480
+// This function assumes that the first character of s is a digit.
3481
+template <typename Char>
3482
+unsigned parse_nonnegative_int(const Char *&s) {
3483
+  assert('0' <= *s && *s <= '9');
3484
+  unsigned value = 0;
3485
+  do {
3486
+    unsigned new_value = value * 10 + (*s++ - '0');
3487
+    // Check if value wrapped around.
3488
+    if (new_value < value) {
3489
+      value = (std::numeric_limits<unsigned>::max)();
3490
+      break;
3491
+    }
3492
+    value = new_value;
3493
+  } while ('0' <= *s && *s <= '9');
3494
+  // Convert to unsigned to prevent a warning.
3495
+  unsigned max_int = (std::numeric_limits<int>::max)();
3496
+  if (value > max_int)
3497
+    FMT_THROW(FormatError("number is too big"));
3498
+  return value;
3499
+}
3500
+
3501
+inline void require_numeric_argument(const Arg &arg, char spec) {
3502
+  if (arg.type > Arg::LAST_NUMERIC_TYPE) {
3503
+    std::string message =
3504
+        fmt::format("format specifier '{}' requires numeric argument", spec);
3505
+    FMT_THROW(fmt::FormatError(message));
3506
+  }
3507
+}
3508
+
3509
+template <typename Char>
3510
+void check_sign(const Char *&s, const Arg &arg) {
3511
+  char sign = static_cast<char>(*s);
3512
+  require_numeric_argument(arg, sign);
3513
+  if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) {
3514
+    FMT_THROW(FormatError(fmt::format(
3515
+      "format specifier '{}' requires signed argument", sign)));
3516
+  }
3517
+  ++s;
3518
+}
3519
+}  // namespace internal
3520
+
3521
+template <typename Char, typename AF>
3522
+inline internal::Arg BasicFormatter<Char, AF>::get_arg(
3523
+    BasicStringRef<Char> arg_name, const char *&error) {
3524
+  if (check_no_auto_index(error)) {
3525
+    map_.init(args());
3526
+    const internal::Arg *arg = map_.find(arg_name);
3527
+    if (arg)
3528
+      return *arg;
3529
+    error = "argument not found";
3530
+  }
3531
+  return internal::Arg();
3532
+}
3533
+
3534
+template <typename Char, typename AF>
3535
+inline internal::Arg BasicFormatter<Char, AF>::parse_arg_index(const Char *&s) {
3536
+  const char *error = 0;
3537
+  internal::Arg arg = *s < '0' || *s > '9' ?
3538
+        next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error);
3539
+  if (error) {
3540
+    FMT_THROW(FormatError(
3541
+                *s != '}' && *s != ':' ? "invalid format string" : error));
3542
+  }
3543
+  return arg;
3544
+}
3545
+
3546
+template <typename Char, typename AF>
3547
+inline internal::Arg BasicFormatter<Char, AF>::parse_arg_name(const Char *&s) {
3548
+  assert(internal::is_name_start(*s));
3549
+  const Char *start = s;
3550
+  Char c;
3551
+  do {
3552
+    c = *++s;
3553
+  } while (internal::is_name_start(c) || ('0' <= c && c <= '9'));
3554
+  const char *error = 0;
3555
+  internal::Arg arg = get_arg(BasicStringRef<Char>(start, s - start), error);
3556
+  if (error)
3557
+    FMT_THROW(FormatError(error));
3558
+  return arg;
3559
+}
3560
+
3561
+template <typename Char, typename ArgFormatter>
3562
+const Char *BasicFormatter<Char, ArgFormatter>::format(
3563
+    const Char *&format_str, const internal::Arg &arg) {
3564
+  using internal::Arg;
3565
+  const Char *s = format_str;
3566
+  FormatSpec spec;
3567
+  if (*s == ':') {
3568
+    if (arg.type == Arg::CUSTOM) {
3569
+      arg.custom.format(this, arg.custom.value, &s);
3570
+      return s;
3571
+    }
3572
+    ++s;
3573
+    // Parse fill and alignment.
3574
+    if (Char c = *s) {
3575
+      const Char *p = s + 1;
3576
+      spec.align_ = ALIGN_DEFAULT;
3577
+      do {
3578
+        switch (*p) {
3579
+          case '<':
3580
+            spec.align_ = ALIGN_LEFT;
3581
+            break;
3582
+          case '>':
3583
+            spec.align_ = ALIGN_RIGHT;
3584
+            break;
3585
+          case '=':
3586
+            spec.align_ = ALIGN_NUMERIC;
3587
+            break;
3588
+          case '^':
3589
+            spec.align_ = ALIGN_CENTER;
3590
+            break;
3591
+        }
3592
+        if (spec.align_ != ALIGN_DEFAULT) {
3593
+          if (p != s) {
3594
+            if (c == '}') break;
3595
+            if (c == '{')
3596
+              FMT_THROW(FormatError("invalid fill character '{'"));
3597
+            s += 2;
3598
+            spec.fill_ = c;
3599
+          } else ++s;
3600
+          if (spec.align_ == ALIGN_NUMERIC)
3601
+            require_numeric_argument(arg, '=');
3602
+          break;
3603
+        }
3604
+      } while (--p >= s);
3605
+    }
3606
+
3607
+    // Parse sign.
3608
+    switch (*s) {
3609
+      case '+':
3610
+        check_sign(s, arg);
3611
+        spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
3612
+        break;
3613
+      case '-':
3614
+        check_sign(s, arg);
3615
+        spec.flags_ |= MINUS_FLAG;
3616
+        break;
3617
+      case ' ':
3618
+        check_sign(s, arg);
3619
+        spec.flags_ |= SIGN_FLAG;
3620
+        break;
3621
+    }
3622
+
3623
+    if (*s == '#') {
3624
+      require_numeric_argument(arg, '#');
3625
+      spec.flags_ |= HASH_FLAG;
3626
+      ++s;
3627
+    }
3628
+
3629
+    // Parse zero flag.
3630
+    if (*s == '0') {
3631
+      require_numeric_argument(arg, '0');
3632
+      spec.align_ = ALIGN_NUMERIC;
3633
+      spec.fill_ = '0';
3634
+      ++s;
3635
+    }
3636
+
3637
+    // Parse width.
3638
+    if ('0' <= *s && *s <= '9') {
3639
+      spec.width_ = internal::parse_nonnegative_int(s);
3640
+    } else if (*s == '{') {
3641
+      ++s;
3642
+      Arg width_arg = internal::is_name_start(*s) ?
3643
+            parse_arg_name(s) : parse_arg_index(s);
3644
+      if (*s++ != '}')
3645
+        FMT_THROW(FormatError("invalid format string"));
3646
+      ULongLong value = 0;
3647
+      switch (width_arg.type) {
3648
+      case Arg::INT:
3649
+        if (width_arg.int_value < 0)
3650
+          FMT_THROW(FormatError("negative width"));
3651
+        value = width_arg.int_value;
3652
+        break;
3653
+      case Arg::UINT:
3654
+        value = width_arg.uint_value;
3655
+        break;
3656
+      case Arg::LONG_LONG:
3657
+        if (width_arg.long_long_value < 0)
3658
+          FMT_THROW(FormatError("negative width"));
3659
+        value = width_arg.long_long_value;
3660
+        break;
3661
+      case Arg::ULONG_LONG:
3662
+        value = width_arg.ulong_long_value;
3663
+        break;
3664
+      default:
3665
+        FMT_THROW(FormatError("width is not integer"));
3666
+      }
3667
+      if (value > (std::numeric_limits<int>::max)())
3668
+        FMT_THROW(FormatError("number is too big"));
3669
+      spec.width_ = static_cast<int>(value);
3670
+    }
3671
+
3672
+    // Parse precision.
3673
+    if (*s == '.') {
3674
+      ++s;
3675
+      spec.precision_ = 0;
3676
+      if ('0' <= *s && *s <= '9') {
3677
+        spec.precision_ = internal::parse_nonnegative_int(s);
3678
+      } else if (*s == '{') {
3679
+        ++s;
3680
+        Arg precision_arg = internal::is_name_start(*s) ?
3681
+              parse_arg_name(s) : parse_arg_index(s);
3682
+        if (*s++ != '}')
3683
+          FMT_THROW(FormatError("invalid format string"));
3684
+        ULongLong value = 0;
3685
+        switch (precision_arg.type) {
3686
+          case Arg::INT:
3687
+            if (precision_arg.int_value < 0)
3688
+              FMT_THROW(FormatError("negative precision"));
3689
+            value = precision_arg.int_value;
3690
+            break;
3691
+          case Arg::UINT:
3692
+            value = precision_arg.uint_value;
3693
+            break;
3694
+          case Arg::LONG_LONG:
3695
+            if (precision_arg.long_long_value < 0)
3696
+              FMT_THROW(FormatError("negative precision"));
3697
+            value = precision_arg.long_long_value;
3698
+            break;
3699
+          case Arg::ULONG_LONG:
3700
+            value = precision_arg.ulong_long_value;
3701
+            break;
3702
+          default:
3703
+            FMT_THROW(FormatError("precision is not integer"));
3704
+        }
3705
+        if (value > (std::numeric_limits<int>::max)())
3706
+          FMT_THROW(FormatError("number is too big"));
3707
+        spec.precision_ = static_cast<int>(value);
3708
+      } else {
3709
+        FMT_THROW(FormatError("missing precision specifier"));
3710
+      }
3711
+      if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
3712
+        FMT_THROW(FormatError(
3713
+            fmt::format("precision not allowed in {} format specifier",
3714
+            arg.type == Arg::POINTER ? "pointer" : "integer")));
3715
+      }
3716
+    }
3717
+
3718
+    // Parse type.
3719
+    if (*s != '}' && *s)
3720
+      spec.type_ = static_cast<char>(*s++);
3721
+  }
3722
+
3723
+  if (*s++ != '}')
3724
+    FMT_THROW(FormatError("missing '}' in format string"));
3725
+
3726
+  // Format argument.
3727
+  ArgFormatter(*this, spec, s - 1).visit(arg);
3728
+  return s;
3729
+}
3730
+
3731
+template <typename Char, typename AF>
3732
+void BasicFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
3733
+  const Char *s = format_str.c_str();
3734
+  const Char *start = s;
3735
+  while (*s) {
3736
+    Char c = *s++;
3737
+    if (c != '{' && c != '}') continue;
3738
+    if (*s == c) {
3739
+      write(writer_, start, s);
3740
+      start = ++s;
3741
+      continue;
3742
+    }
3743
+    if (c == '}')
3744
+      FMT_THROW(FormatError("unmatched '}' in format string"));
3745
+    write(writer_, start, s - 1);
3746
+    internal::Arg arg = internal::is_name_start(*s) ?
3747
+          parse_arg_name(s) : parse_arg_index(s);
3748
+    start = s = format(s, arg);
3749
+  }
3750
+  write(writer_, start, s);
3751
+}
3752
+}  // namespace fmt
3753
+
3754
+#if FMT_USE_USER_DEFINED_LITERALS
3755
+namespace fmt {
3756
+namespace internal {
3757
+
3758
+template <typename Char>
3759
+struct UdlFormat {
3760
+  const Char *str;
3761
+
3762
+  template <typename... Args>
3763
+  auto operator()(Args && ... args) const
3764
+                  -> decltype(format(str, std::forward<Args>(args)...)) {
3765
+    return format(str, std::forward<Args>(args)...);
3766
+  }
3767
+};
3768
+
3769
+template <typename Char>
3770
+struct UdlArg {
3771
+  const Char *str;
3772
+
3773
+  template <typename T>
3774
+  NamedArg<Char> operator=(T &&value) const {
3775
+    return {str, std::forward<T>(value)};
3776
+  }
3777
+};
3778
+
3779
+} // namespace internal
3780
+
3781
+inline namespace literals {
3782
+
3783
+/**
3784
+  \rst
3785
+  C++11 literal equivalent of :func:`fmt::format`.
3786
+
3787
+  **Example**::
3788
+
3789
+    using namespace fmt::literals;
3790
+    std::string message = "The answer is {}"_format(42);
3791
+  \endrst
3792
+ */
3793
+inline internal::UdlFormat<char>
3794
+operator"" _format(const char *s, std::size_t) { return {s}; }
3795
+inline internal::UdlFormat<wchar_t>
3796
+operator"" _format(const wchar_t *s, std::size_t) { return {s}; }
3797
+
3798
+/**
3799
+  \rst
3800
+  C++11 literal equivalent of :func:`fmt::arg`.
3801
+
3802
+  **Example**::
3803
+
3804
+    using namespace fmt::literals;
3805
+    print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
3806
+  \endrst
3807
+ */
3808
+inline internal::UdlArg<char>
3809
+operator"" _a(const char *s, std::size_t) { return {s}; }
3810
+inline internal::UdlArg<wchar_t>
3811
+operator"" _a(const wchar_t *s, std::size_t) { return {s}; }
3812
+
3813
+} // inline namespace literals
3814
+} // namespace fmt
3815
+#endif // FMT_USE_USER_DEFINED_LITERALS
3816
+
3817
+// Restore warnings.
3818
+#if FMT_GCC_VERSION >= 406
3819
+# pragma GCC diagnostic pop
3820
+#endif
3821
+
3822
+#if defined(__clang__) && !defined(FMT_ICC_VERSION)
3823
+# pragma clang diagnostic pop
3824
+#endif
3825
+
3826
+#ifdef FMT_HEADER_ONLY
3827
+# define FMT_FUNC inline
3828
+# include "format.cc"
3829
+#else
3830
+# define FMT_FUNC
3831
+#endif
3832
+
3833
+#endif  // FMT_FORMAT_H_
3834
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/apple/browser-manager-mac.h -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/apple/browser-manager-mac.h Changed
10
 
1
@@ -56,6 +56,8 @@
2
     
3
     void RefreshPageNoCache(int browserIdentifier);
4
 
5
+   void DispatchJSEvent(const char *eventName, const char *jsonData);
6
+
7
 private:
8
    std::unique_ptr<CEFIsolationServiceManager> cefIsolationServiceManager;
9
 };
10
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/apple/browser-manager-mac.mm -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/apple/browser-manager-mac.mm Changed
25
 
1
@@ -96,6 +96,11 @@
2
     pimpl->RefreshPageNoCache(browserIdentifier);
3
 }
4
 
5
+void BrowserManager::DispatchJSEvent(const char *name, const char *jsonData)
6
+{
7
+   pimpl->DispatchJSEvent(name, jsonData);
8
+}
9
+
10
 int BrowserManager::CreateBrowser(const BrowserSettings &browserSettings,
11
        const std::shared_ptr<BrowserListener> &browserListener)
12
 {
13
@@ -191,6 +196,11 @@
14
     cefIsolationServiceManager->RefreshPageNoCache(browserIdentifier);
15
 }
16
 
17
+void BrowserManager::Impl::DispatchJSEvent(const char *eventName, const char *jsonData)
18
+{
19
+   cefIsolationServiceManager->DispatchJSEvent(eventName, jsonData);
20
+}
21
+
22
 static BrowserManager *instance;
23
 
24
 BrowserManager *BrowserManager::Instance()
25
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/apple/cef-isolation-service-manager.h -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/apple/cef-isolation-service-manager.h Changed
25
 
1
@@ -19,6 +19,7 @@
2
 
3
 #include <Foundation/Foundation.h>
4
 #include <string>
5
+#include <jansson.h>
6
 
7
 @class CEFIsolationService;
8
 @class ClientConnectionDelegate;
9
@@ -62,6 +63,8 @@
10
     
11
     void RefreshPageNoCache(int browserIdentifier);
12
 
13
+   void DispatchJSEvent(const char *eventName, const char *jsonData);
14
+
15
 public:
16
    NSString *GetUniqueClientName() { return _uniqueClientName; }
17
 
18
@@ -76,4 +79,4 @@
19
    CEFIsolationService *_cefIsolationService;
20
    NSObject *cefIsolationServiceLock;
21
 
22
-};
23
\ No newline at end of file
24
+};
25
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/apple/cef-isolation-service-manager.mm -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/apple/cef-isolation-service-manager.mm Changed
25
 
1
@@ -16,6 +16,7 @@
2
  ******************************************************************************/
3
 
4
 #include <string>
5
+#import <Foundation/Foundation.h>
6
 
7
 // shared
8
 #include "browser-listener.hpp"
9
@@ -266,6 +267,12 @@
10
    @catch (NSException *exception) {}
11
 }
12
 
13
-
14
-
15
-
16
+void CEFIsolationServiceManager::DispatchJSEvent(const char *eventName, const char *jsonData)
17
+{
18
+   id<CEFIsolatedClient> cefIsolatedClient =
19
+       [_cefIsolationService client];
20
+   @try {
21
+       [cefIsolatedClient dispatchJSEvent:eventName data:jsonData];
22
+   }
23
+   @catch (NSException *exception) {}
24
+}
25
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/apple/cef-isolation-service.mm -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/apple/cef-isolation-service.mm Changed
36
 
1
@@ -26,6 +26,9 @@
2
 
3
 #include "browser-listener.hpp"
4
 
5
+#include <obs-frontend-api.h>
6
+#include "util.hpp"
7
+
8
 @implementation CEFIsolationService
9
 {
10
    std::map<int, std::shared_ptr<BrowserListener> > listenerMap;
11
@@ -106,6 +109,17 @@
12
    }
13
 }
14
 
15
+- (const char*)getCurrentSceneJSONData
16
+{
17
+   obs_source_t *source = obs_frontend_get_current_scene();
18
+
19
+   const char* jsonString = obsSourceToJSON(source);
20
+
21
+   obs_source_release(source);
22
+
23
+   return jsonString;
24
+}
25
+
26
 - (void)invalidateClient:(id)client withException:(NSException *)exception
27
 {
28
    UNUSED_PARAMETER(client);
29
@@ -123,4 +137,4 @@
30
    }
31
 }
32
 
33
-@end
34
\ No newline at end of file
35
+@end
36
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/browser-manager-base.cpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/browser-manager-base.cpp Changed
66
 
1
@@ -8,6 +8,7 @@
2
 #include "browser-client.hpp"
3
 #include "browser-render-handler.hpp"
4
 #include "browser-load-handler.hpp"
5
+#include "browser-obs-bridge-base.hpp"
6
 
7
 BrowserManager::BrowserManager()
8
 : pimpl(new BrowserManager::Impl())
9
@@ -90,6 +91,19 @@
10
    pimpl->RefreshPageNoCache(browserIdentifier);
11
 }
12
 
13
+/**
14
+   Sends JSON Data about an OBS event to be executed as a DOM event.
15
+   The jsonString is already encoded so that we can pass it across the process boundary that cef-isolation creates.
16
+
17
+   @param eventName the name of the DOM event that we will fire
18
+   @param jsonString A json encoded string that will be accessable from the detail field of the event object
19
+   @return
20
+*/
21
+void BrowserManager::DispatchJSEvent(const char *eventName, const char *jsonString)
22
+{
23
+   pimpl->DispatchJSEvent(eventName, jsonString);
24
+}
25
+
26
 BrowserManager::Impl::Impl()
27
 {
28
    os_event_init(&dispatchEvent, OS_EVENT_TYPE_AUTO);
29
@@ -110,6 +124,8 @@
30
    os_event_t *createdEvent;
31
    os_event_init(&createdEvent, OS_EVENT_TYPE_AUTO);
32
 
33
+   BrowserOBSBridge *browserOBSBridge = new BrowserOBSBridgeBase();
34
+
35
    CefPostTask(TID_UI, BrowserTask::newTask(
36
            [&] 
37
    {
38
@@ -121,7 +137,7 @@
39
                new BrowserLoadHandler(browserSettings.css));
40
 
41
        CefRefPtr<BrowserClient> browserClient(
42
-               new BrowserClient(renderHandler,loadHandler)); 
43
+               new BrowserClient(renderHandler, loadHandler, browserOBSBridge));
44
 
45
        CefWindowInfo windowInfo;
46
        windowInfo.transparent_painting_enabled = true;
47
@@ -335,6 +351,18 @@
48
    });
49
 }
50
 
51
+void BrowserManager::Impl::DispatchJSEvent(const char *eventName, const char *jsonString)
52
+{
53
+   ExecuteOnAllBrowsers([&](CefRefPtr<CefBrowser> b)
54
+   {
55
+       CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("DispatchJSEvent");
56
+       CefRefPtr<CefListValue> args = msg->GetArgumentList();
57
+       args->SetString(0, eventName);
58
+       args->SetString(1, jsonString);
59
+       b->SendProcessMessage(PID_RENDERER, msg);
60
+   });
61
+}
62
+
63
 void
64
 BrowserManager::Impl::Startup() 
65
 {
66
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/browser-manager-base.hpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/browser-manager-base.hpp Changed
10
 
1
@@ -59,6 +59,8 @@
2
    void ExecuteSceneChangeJSCallback(const char *name);
3
 
4
    void RefreshPageNoCache(int browserIdentifier);
5
+   
6
+   void DispatchJSEvent(const char *eventName, const char *jsonString);
7
 
8
 private: 
9
    void ExecuteOnBrowser(int browserIdentifier, 
10
obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/browser-obs-bridge-base.cpp Added
19
 
1
@@ -0,0 +1,17 @@
2
+#include "browser-obs-bridge-base.hpp"
3
+
4
+#include "util.hpp"
5
+
6
+BrowserOBSBridgeBase::BrowserOBSBridgeBase()
7
+{}
8
+
9
+const char* BrowserOBSBridgeBase::GetCurrentSceneJSONData()
10
+{
11
+   obs_source_t *source = obs_frontend_get_current_scene();
12
+
13
+   const char* jsonString = obsSourceToJSON(source);
14
+
15
+   obs_source_release(source);
16
+
17
+   return jsonString; 
18
+}
19
obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/browser-obs-bridge-base.hpp Added
13
 
1
@@ -0,0 +1,11 @@
2
+#pragma once
3
+
4
+#include "browser-obs-bridge.hpp"
5
+
6
+class BrowserOBSBridgeBase : public BrowserOBSBridge
7
+{
8
+public:
9
+   BrowserOBSBridgeBase();
10
+
11
+    const char* GetCurrentSceneJSONData() override;
12
+};
13
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/main-source.cpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/main-source.cpp Changed
53
 
1
@@ -29,6 +29,7 @@
2
    obs_data_set_default_int(settings, "height", 600);
3
    obs_data_set_default_int(settings, "fps", 30);
4
    obs_data_set_default_bool(settings, "shutdown", false);
5
+   obs_data_set_default_bool(settings, "restart_when_active", false);
6
    obs_data_set_default_string(settings, "css", "body { background-color: rgba(0, 0, 0, 0); margin: 0px auto; overflow: hidden; }");
7
 }
8
 
9
@@ -106,7 +107,9 @@
10
    obs_properties_add_text(props, "css",
11
        obs_module_text("CSS"), OBS_TEXT_MULTILINE);
12
    obs_properties_add_bool(props, "shutdown",
13
-       obs_module_text("Shutdown when not active"));
14
+       obs_module_text("Shutdown source when not visible"));
15
+   obs_properties_add_bool(props, "restart_when_active",
16
+       obs_module_text("Refresh browser when scene becomes active"));
17
 
18
    obs_properties_add_button(props, "refreshnocache",
19
        obs_module_text("Refresh cache of current page"), refreshnocache_button_clicked);
20
@@ -143,6 +146,21 @@
21
    return obs_module_text("BrowserSource");
22
 }
23
 
24
+static void browser_source_activate(void *data)
25
+{
26
+   BrowserSource *bs = static_cast<BrowserSource *>(data);
27
+   obs_data_t *settings = obs_source_get_settings(bs->GetSource());
28
+   bool restart = obs_data_get_bool(settings, "restart_when_active");
29
+
30
+   if (restart)
31
+       BrowserManager::Instance()->RefreshPageNoCache(bs->GetBrowserIdentifier());
32
+}
33
+
34
+static void browser_source_deactivate(void *data)
35
+{
36
+
37
+}
38
+
39
 // Called when the source is visible
40
 static void browser_source_show(void *data)
41
 {
42
@@ -267,6 +285,9 @@
43
    browser_source_info.video_render = browser_source_render;
44
    browser_source_info.show = browser_source_show;
45
    browser_source_info.hide = browser_source_hide;
46
+   browser_source_info.activate = browser_source_activate;
47
+   browser_source_info.deactivate = browser_source_deactivate;
48
+
49
 
50
    return browser_source_info;
51
 }
52
\ No newline at end of file
53
obs-studio-0.17.0.tar.xz/plugins/obs-browser/obs-browser/main.cpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/obs-browser/main.cpp Changed
80
 
1
@@ -20,6 +20,7 @@
2
 
3
 #include "browser-version.h"
4
 #include "browser-manager.hpp"
5
+#include "util.hpp"
6
 
7
 OBS_DECLARE_MODULE()
8
 OBS_MODULE_USE_DEFAULT_LOCALE("obs-browser", "en-US")
9
@@ -30,14 +31,62 @@
10
 // Handle events from the frontend
11
 static void handle_obs_frontend_event(enum obs_frontend_event event, void *)
12
 {
13
-   if (event == OBS_FRONTEND_EVENT_SCENE_CHANGED) {
14
-
15
-       obs_source_t *source = obs_frontend_get_current_scene();
16
-
17
-       const char *name = obs_source_get_name(source);
18
-
19
-       BrowserManager::Instance()->ExecuteSceneChangeJSCallback(name);
20
-       obs_source_release(source);
21
+   switch(event)
22
+   {
23
+   case OBS_FRONTEND_EVENT_STREAMING_STARTING:
24
+       BrowserManager::Instance()->DispatchJSEvent("obsStreamingStarting", nullptr);
25
+       break;
26
+   case OBS_FRONTEND_EVENT_STREAMING_STARTED:
27
+       BrowserManager::Instance()->DispatchJSEvent("obsStreamingStarted", nullptr);
28
+       break;
29
+   case OBS_FRONTEND_EVENT_STREAMING_STOPPING:
30
+       BrowserManager::Instance()->DispatchJSEvent("obsStreamingStopping", nullptr);
31
+       break;
32
+   case OBS_FRONTEND_EVENT_STREAMING_STOPPED:
33
+       BrowserManager::Instance()->DispatchJSEvent("obsStreamingStopped", nullptr);
34
+       break;
35
+   case OBS_FRONTEND_EVENT_RECORDING_STARTING:
36
+       BrowserManager::Instance()->DispatchJSEvent("obsRecordingStarting", nullptr);
37
+       break;
38
+   case OBS_FRONTEND_EVENT_RECORDING_STARTED:
39
+       BrowserManager::Instance()->DispatchJSEvent("obsRecordingStarted", nullptr);
40
+       break;
41
+   case OBS_FRONTEND_EVENT_RECORDING_STOPPING:
42
+       BrowserManager::Instance()->DispatchJSEvent("obsRecordingStopping", nullptr);
43
+       break;
44
+   case OBS_FRONTEND_EVENT_RECORDING_STOPPED:
45
+       BrowserManager::Instance()->DispatchJSEvent("obsRecordingStopped", nullptr);
46
+       break;
47
+   case OBS_FRONTEND_EVENT_SCENE_CHANGED:
48
+       {
49
+           obs_source_t *source = obs_frontend_get_current_scene();
50
+
51
+           const char* jsonString = obsSourceToJSON(source);
52
+
53
+           BrowserManager::Instance()->DispatchJSEvent("obsSceneChanged", jsonString);
54
+
55
+           obs_source_release(source);
56
+           break;
57
+       }
58
+   case OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED:
59
+       break;
60
+   case OBS_FRONTEND_EVENT_TRANSITION_CHANGED:
61
+       break;
62
+   case OBS_FRONTEND_EVENT_TRANSITION_STOPPED:
63
+       break;
64
+   case OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED:
65
+       break;
66
+   case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED:
67
+       break;
68
+   case OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED:
69
+       break;
70
+   case OBS_FRONTEND_EVENT_PROFILE_CHANGED:
71
+       break;
72
+   case OBS_FRONTEND_EVENT_PROFILE_LIST_CHANGED:
73
+       break;
74
+   case OBS_FRONTEND_EVENT_EXIT:
75
+       BrowserManager::Instance()->DispatchJSEvent("obsExit", nullptr);
76
+       break;
77
    }
78
 }
79
 
80
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared-apple/cef-isolation.h -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared-apple/cef-isolation.h Changed
29
 
1
@@ -18,6 +18,7 @@
2
 #pragma once
3
 
4
 #import <Foundation/Foundation.h>
5
+#include <jansson.h>
6
 
7
 #include "browser-types.h"
8
 
9
@@ -36,6 +37,7 @@
10
        height:(int)height
11
        surfaceHandle:(BrowserSurfaceHandle)surfaceHandle;
12
 - (void)invalidateClient:(id)client withException:(NSException *)exception;
13
+- (const char*)getCurrentSceneJSONData;
14
 @end
15
 
16
 @protocol CEFIsolatedClient
17
@@ -53,6 +55,11 @@
18
 - (oneway void)sendFocus:(int)browserIdentifier focus:(BOOL)focus;
19
 - (void)sendKeyClick:(int) browserIdentifier
20
        event:(bycopy ObsKeyEventBridge *)event keyUp:(BOOL)keyUp;
21
+- (void)refreshPageNoCache:(const int)browserIdentifier;
22
+- (void)executeVisiblityJSCallback:(const int)browserIdentifier
23
+       visible:(BOOL)visible;
24
+- (void)executeSceneChangeJSCallback:(const char *)name;
25
+- (void)dispatchJSEvent:(const char *)eventName data:(const char*) jsonString;
26
 @end
27
 
28
 
29
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared/browser-app.cpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-app.cpp Changed
143
 
1
@@ -19,8 +19,9 @@
2
 
3
 #include <iostream>
4
 #include <string>
5
+#include <jansson.h>
6
 
7
-#include "cefsimple/simple_handler.h"
8
+#include "fmt/format.h"
9
 #include "include/cef_browser.h"
10
 #include "include/cef_command_line.h"
11
 #include "include/wrapper/cef_helpers.h"
12
@@ -64,11 +65,14 @@
13
 {
14
    CefRefPtr<CefV8Value> globalObj = context->GetGlobal();
15
 
16
-   CefRefPtr<CefV8Value> obsStudioObj = CefV8Value::CreateObject(0);
17
+   CefRefPtr<CefV8Value> obsStudioObj = CefV8Value::CreateObject(0, 0);
18
    globalObj->SetValue("obsstudio", obsStudioObj, V8_PROPERTY_ATTRIBUTE_NONE);
19
 
20
    CefRefPtr<CefV8Value> pluginVersion = CefV8Value::CreateString(OBS_BROWSER_VERSION);
21
    obsStudioObj->SetValue("pluginVersion", pluginVersion, V8_PROPERTY_ATTRIBUTE_NONE);
22
+
23
+   CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("getCurrentScene", this);
24
+   obsStudioObj->SetValue("getCurrentScene", func, V8_PROPERTY_ATTRIBUTE_NONE);
25
 }
26
 
27
 void BrowserApp::ExecuteJSFunction(CefRefPtr<CefBrowser> browser,
28
@@ -93,7 +97,8 @@
29
 
30
 bool BrowserApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
31
        CefProcessId source_process,
32
-       CefRefPtr<CefProcessMessage> message) {
33
+       CefRefPtr<CefProcessMessage> message)
34
+{
35
    DCHECK(source_process == PID_BROWSER);
36
 
37
    CefRefPtr<CefListValue> args = message->GetArgumentList();
38
@@ -105,13 +110,101 @@
39
        ExecuteJSFunction(browser, "onVisibilityChange", arguments);
40
        return true;
41
    }
42
-   else if (message->GetName() == "SceneChange") {
43
+   else if (message->GetName() == "DispatchJSEvent") {       
44
+       CefRefPtr<CefV8Context> context = browser->GetMainFrame()->GetV8Context();
45
+
46
+       context->Enter();
47
+
48
+       CefRefPtr<CefV8Value> globalObj = context->GetGlobal();
49
+
50
+       // Build up a new json object to store the CustomEvent data in.
51
+       json_t *json = json_object();
52
+        
53
+       if (args->GetSize() > 1) {
54
+           json_error_t error;
55
+
56
+           json_object_set_new(json, "detail", json_loads(args->GetString(1).ToString().c_str(), 0, &error));
57
+       }
58
+
59
+       char *jsonString = json_dumps(json, 0);
60
+
61
+       std::string script = fmt::format(
62
+           "new CustomEvent('{}', {});", 
63
+           args->GetString(0).ToString(),
64
+           jsonString);
65
+
66
+       free(jsonString);
67
+
68
+       CefRefPtr<CefV8Value> returnValue;
69
+       CefRefPtr<CefV8Exception> exception;
70
+
71
+       // Create the CustomEvent object
72
+       // We have to use eval to invoke the new operator
73
+       context->Eval(script, browser->GetMainFrame()->GetURL(), 0, returnValue, exception);
74
+
75
        CefV8ValueList arguments;
76
-       arguments.push_back(CefV8Value::CreateString(args->GetString(0)));
77
+       arguments.push_back(returnValue);
78
+
79
+       CefRefPtr<CefV8Value> dispatchEvent = globalObj->GetValue("dispatchEvent");
80
+       dispatchEvent->ExecuteFunction(NULL, arguments);
81
+
82
+       context->Exit();
83
+
84
+       return true;
85
+   }
86
+   else if (message->GetName() == "executeCallback") {
87
+        CefRefPtr<CefV8Context> context = browser->GetMainFrame()->GetV8Context();
88
+        
89
+        context->Enter();
90
+
91
+       int callbackID = message->GetArgumentList()->GetInt(0);
92
+       CefString jsonString = message->GetArgumentList()->GetString(1);
93
+
94
+       CefRefPtr<CefV8Value> callback = callbackMap[callbackID];
95
+       
96
+       CefV8ValueList args;
97
+       args.push_back(CefV8Value::CreateString(jsonString));
98
+
99
+       CefRefPtr<CefV8Value> retval;
100
+       CefRefPtr<CefV8Exception> exception;
101
+        callback->ExecuteFunction(NULL, args);
102
+        
103
+        context->Exit();
104
+
105
+       callbackMap.erase(callbackID);
106
+
107
+       
108
+       return true;
109
+   }
110
+
111
+   return false;
112
+}
113
+
114
+// CefV8Handler::Execute
115
+bool BrowserApp::Execute(const CefString& name,
116
+       CefRefPtr<CefV8Value> object,
117
+       const CefV8ValueList& arguments,
118
+       CefRefPtr<CefV8Value>& retval,
119
+       CefString& exception)
120
+{
121
+   if (name == "getCurrentScene") {
122
+
123
+       if (arguments.size() == 1 && arguments[0]->IsFunction()) {
124
+           callbackId++;
125
+           callbackMap[callbackId] = arguments[0];
126
+       }
127
+
128
+       CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("getCurrentScene");
129
+       CefRefPtr<CefListValue> args = msg->GetArgumentList();
130
+       args->SetInt(0, callbackId);
131
+
132
+       CefRefPtr<CefBrowser> browser = 
133
+                CefV8Context::GetCurrentContext()->GetBrowser();
134
+       browser->SendProcessMessage(PID_BROWSER, msg);
135
 
136
-       ExecuteJSFunction(browser , "onSceneChange", arguments);
137
        return true;
138
    }
139
 
140
+   // Function does not exist.
141
    return false;
142
 }
143
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared/browser-app.hpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-app.hpp Changed
35
 
1
@@ -21,7 +21,8 @@
2
 #include <include/cef_render_process_handler.h>
3
 
4
 class BrowserApp : public CefApp,
5
-                  public CefRenderProcessHandler
6
+                  public CefRenderProcessHandler,
7
+                  public CefV8Handler
8
 {
9
 
10
 public:
11
@@ -44,11 +45,21 @@
12
        CefProcessId source_process,
13
        CefRefPtr<CefProcessMessage> message) OVERRIDE;
14
 
15
+public: /* CefV8Handler */
16
+   virtual bool Execute(const CefString& name,
17
+           CefRefPtr<CefV8Value> object,
18
+           const CefV8ValueList& arguments,
19
+           CefRefPtr<CefV8Value>& retval,
20
+           CefString& exception) OVERRIDE;
21
+
22
 private:
23
    virtual void ExecuteJSFunction(CefRefPtr<CefBrowser> browser,
24
        const char *functionName,
25
        CefV8ValueList arguments);
26
-   
27
-   IMPLEMENT_REFCOUNTING(BrowserApp);
28
 
29
+   typedef std::map<int, CefRefPtr<CefV8Value>> CallbackMap;
30
+   int callbackId;
31
+   CallbackMap callbackMap;
32
+
33
+   IMPLEMENT_REFCOUNTING(BrowserApp);
34
 };
35
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared/browser-client.cpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-client.cpp Changed
46
 
1
@@ -18,10 +18,11 @@
2
 #include <include/cef_render_handler.h>
3
 
4
 #include "browser-client.hpp"
5
+#include "browser-obs-bridge.hpp"
6
 
7
 BrowserClient::BrowserClient(CefRenderHandler *renderHandler,
8
-   CefLoadHandler *loadHandler)
9
-   : renderHandler(renderHandler), loadHandler(loadHandler)
10
+   CefLoadHandler *loadHandler, BrowserOBSBridge *browserOBSBridge)
11
+   : renderHandler(renderHandler), loadHandler(loadHandler), browserOBSBridge(browserOBSBridge)
12
 {
13
 }
14
 
15
@@ -81,4 +82,28 @@
16
 
17
    // remove all context menu contributions
18
    model->Clear();
19
-}
20
\ No newline at end of file
21
+}
22
+
23
+bool BrowserClient::OnProcessMessageReceived(
24
+   CefRefPtr<CefBrowser> browser,
25
+   CefProcessId source_process,
26
+   CefRefPtr<CefProcessMessage> message)
27
+{
28
+   const std::string& message_name = message->GetName();
29
+   if (message_name == "getCurrentScene") {
30
+
31
+       int callbackID = message->GetArgumentList()->GetInt(0);
32
+
33
+       const char* jsonString = browserOBSBridge->GetCurrentSceneJSONData();
34
+
35
+       CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("executeCallback");
36
+       CefRefPtr<CefListValue> args = msg->GetArgumentList();
37
+       args->SetInt(0, callbackID);
38
+       args->SetString(1, jsonString);
39
+
40
+       browser->SendProcessMessage(PID_RENDERER, msg);
41
+
42
+       return true;
43
+   }
44
+   return false;
45
+}
46
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared/browser-client.hpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-client.hpp Changed
45
 
1
@@ -18,6 +18,7 @@
2
 #pragma once
3
 
4
 #include <include/cef_client.h>
5
+#include "browser-obs-bridge.hpp"
6
 
7
 class BrowserSource;
8
 class BrowserRenderHandler;
9
@@ -28,7 +29,8 @@
10
 {
11
 public:
12
    BrowserClient(CefRenderHandler *renderHandler,
13
-       CefLoadHandler *loadHandler);
14
+       CefLoadHandler *loadHandler,
15
+       BrowserOBSBridge *browserOBSBridge);
16
 
17
 public: /* CefClient overrides */
18
    virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE;
19
@@ -36,6 +38,10 @@
20
    virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler()
21
            OVERRIDE;
22
    virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE;
23
+   virtual bool OnProcessMessageReceived(
24
+           CefRefPtr<CefBrowser> browser,
25
+           CefProcessId source_process,
26
+           CefRefPtr<CefProcessMessage> message) OVERRIDE;
27
 
28
 public: /* CefLifeSpanHandler overrides */
29
    virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
30
@@ -52,10 +58,12 @@
31
            CefRefPtr<CefFrame> frame,
32
            CefRefPtr<CefContextMenuParams> params,
33
            CefRefPtr<CefMenuModel> model);
34
+
35
 private:
36
    CefRefPtr<CefRenderHandler> renderHandler;
37
    CefRefPtr<CefLoadHandler> loadHandler;
38
+   BrowserOBSBridge *browserOBSBridge;
39
 
40
 public:
41
    IMPLEMENT_REFCOUNTING(BrowserClient);
42
-};
43
\ No newline at end of file
44
+};
45
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared/browser-listener.hpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-listener.hpp Changed
9
 
1
@@ -30,7 +30,6 @@
2
            BrowserSurfaceHandle *surfaceHandle) = 0;
3
    virtual void DestroySurface(BrowserSurfaceHandle surfaceHandle) = 0;
4
    virtual void Invalidated() = 0;
5
-
6
 };
7
 
8
 class BrowserListener : public BrowserListenerBase
9
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared/browser-manager.hpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-manager.hpp Changed
18
 
1
@@ -18,6 +18,7 @@
2
 #pragma once
3
 
4
 #include <memory>
5
+#include <jansson.h>
6
 
7
 class BrowserListener;
8
 struct BrowserSettings;
9
@@ -65,6 +66,8 @@
10
 
11
    void RefreshPageNoCache(int browserIdentifier);
12
 
13
+   void DispatchJSEvent(const char *eventName, const char *jsonString);
14
+
15
 private:
16
    class Impl;
17
    std::unique_ptr<Impl> pimpl;
18
obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-obs-bridge.hpp Added
10
 
1
@@ -0,0 +1,7 @@
2
+#pragma once
3
+
4
+class BrowserOBSBridge
5
+{
6
+public:
7
+   virtual const char* GetCurrentSceneJSONData() = 0;
8
+};
9
\ No newline at end of file
10
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared/browser-source.hpp -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-source.hpp Changed
9
 
1
@@ -82,6 +82,7 @@
2
    uint32_t height;
3
    uint32_t fps;
4
    bool shutdown;
5
+   bool restart_when_active;
6
 
7
    int browserIdentifier;
8
 
9
obs-studio-0.17.0.tar.xz/plugins/obs-browser/shared/browser-version.h -> obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/browser-version.h Changed
8
 
1
@@ -1,3 +1,3 @@
2
 #pragma once
3
 
4
-#define OBS_BROWSER_VERSION "1.25.0"
5
\ No newline at end of file
6
+#define OBS_BROWSER_VERSION "1.27.0"
7
\ No newline at end of file
8
obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/util.cpp Added
24
 
1
@@ -0,0 +1,21 @@
2
+#include "util.hpp"
3
+
4
+/**
5
+   Takes an OBS source and generates a JSON encoded string representing information about the source.
6
+   
7
+   @param source is the OBS source that we want to turn into json data
8
+   @return json encoded string
9
+*/
10
+const char* obsSourceToJSON(obs_source_t *source)
11
+{
12
+   const char *name = obs_source_get_name(source);
13
+
14
+   json_t *obj = json_object();
15
+   json_object_set_new(obj, "name", json_string(name));
16
+   json_object_set_new(obj, "width", json_integer(obs_source_get_width(source)));
17
+   json_object_set_new(obj, "height", json_integer(obs_source_get_height(source)));
18
+   const char *jsonString = json_dumps(obj, 0);
19
+   free(obj);
20
+
21
+   return jsonString;
22
+}
23
\ No newline at end of file
24
obs-studio-17.0.1.tar.xz/plugins/obs-browser/shared/util.hpp Added
9
 
1
@@ -0,0 +1,6 @@
2
+#pragma once
3
+
4
+#include <jansson.h>
5
+#include <obs-frontend-api.h>
6
+
7
+extern const char* obsSourceToJSON(obs_source_t *source);
8
\ No newline at end of file
9
obs-studio-0.17.0.tar.xz/plugins/obs-ffmpeg/data/locale/ca-ES.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-ffmpeg/data/locale/ca-ES.ini Changed
16
 
1
@@ -6,6 +6,7 @@
2
 KeyframeIntervalSec="Interval de fotograma clau (en segons, 0 = automàtic)"
3
 Lossless="Sense pèrdues"
4
 
5
+BFrames="B-frames"
6
 
7
 NVENC.Use2Pass="Utilitza codificació en dues passades"
8
 NVENC.Preset.default="Per defecte"
9
@@ -48,4 +49,6 @@
10
 MediaFileFilter.AudioFiles="Arxius d'àudio"
11
 MediaFileFilter.AllFiles="Tots els fitxers"
12
 
13
+ReplayBuffer="Memòria intermèdia de reproducció"
14
+ReplayBuffer.Save="Desa la repetició"
15
 
16
obs-studio-0.17.0.tar.xz/plugins/obs-ffmpeg/data/locale/cs-CZ.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-ffmpeg/data/locale/cs-CZ.ini Changed
9
 
1
@@ -6,6 +6,7 @@
2
 KeyframeIntervalSec="Interval klíč. snímků (vteřiny, 0=auto)"
3
 Lossless="Lossless"
4
 
5
+BFrames="B-frames"
6
 
7
 NVENC.Use2Pass="Použít dvoustupňové enkódování"
8
 NVENC.Preset.default="Výchozí"
9
obs-studio-0.17.0.tar.xz/plugins/obs-ffmpeg/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-ffmpeg/data/locale/hu-HU.ini Changed
9
 
1
@@ -1,6 +1,6 @@
2
 FFmpegOutput="FFmpeg kimenet"
3
 FFmpegAAC="FFmpeg alapértelmezett AAC kódoló"
4
-Bitrate="Bitráta"
5
+Bitrate="Bitsebesség"
6
 Preset="Készlet"
7
 RateControl="Sebesség Vezérlés"
8
 KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)"
9
obs-studio-0.17.0.tar.xz/plugins/obs-ffmpeg/data/locale/it-IT.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-ffmpeg/data/locale/it-IT.ini Changed
16
 
1
@@ -6,6 +6,7 @@
2
 KeyframeIntervalSec="Intervallo Keyframe (secondi, 0=automatico)"
3
 Lossless="Lossless"
4
 
5
+BFrames="B-frames"
6
 
7
 NVENC.Use2Pass="Usa codifica in due passaggi"
8
 NVENC.Preset.default="Predefinito"
9
@@ -48,4 +49,6 @@
10
 MediaFileFilter.AudioFiles="File audio"
11
 MediaFileFilter.AllFiles="Tutti i file"
12
 
13
+ReplayBuffer="Buffer di Replay"
14
+ReplayBuffer.Save="Salva Replay"
15
 
16
obs-studio-0.17.0.tar.xz/plugins/obs-ffmpeg/data/locale/ru-RU.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-ffmpeg/data/locale/ru-RU.ini Changed
16
 
1
@@ -6,6 +6,7 @@
2
 KeyframeIntervalSec="Интервал ключевых кадров (сек, 0=авто)"
3
 Lossless="Без потерь"
4
 
5
+BFrames="B-Кадры"
6
 
7
 NVENC.Use2Pass="Использовать двухпроходное кодирование"
8
 NVENC.Preset.default="По умолчанию"
9
@@ -48,5 +49,6 @@
10
 MediaFileFilter.AudioFiles="Аудиофайлы"
11
 MediaFileFilter.AllFiles="Все файлы"
12
 
13
+ReplayBuffer="Буфер повтора"
14
 ReplayBuffer.Save="Сохранить повтор"
15
 
16
obs-studio-0.17.0.tar.xz/plugins/obs-ffmpeg/data/locale/sv-SE.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-ffmpeg/data/locale/sv-SE.ini Changed
16
 
1
@@ -6,6 +6,7 @@
2
 KeyframeIntervalSec="Intervall för keyframes (sekunder, 0=automatisk)"
3
 Lossless="Förlustfri"
4
 
5
+BFrames="B-bildrutor"
6
 
7
 NVENC.Use2Pass="Använd tvåpassavkodning"
8
 NVENC.Preset.default="Standard"
9
@@ -48,4 +49,6 @@
10
 MediaFileFilter.AudioFiles="Ljudfiler"
11
 MediaFileFilter.AllFiles="Alla filer"
12
 
13
+ReplayBuffer="Reprisbuffert"
14
+ReplayBuffer.Save="Spara repris"
15
 
16
obs-studio-0.17.0.tar.xz/plugins/obs-ffmpeg/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-ffmpeg/data/locale/tr-TR.ini Changed
29
 
1
@@ -2,10 +2,13 @@
2
 FFmpegAAC="FFmpeg Varsayılan AAC Kodlayıcı"
3
 Bitrate="Bit hızı"
4
 Preset="Ön Tanımlı"
5
+RateControl="Oran Kontrolü"
6
 KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)"
7
 Lossless="Kayıpsız"
8
 
9
+BFrames="B-frame'leri"
10
 
11
+NVENC.Use2Pass="İki Taramalı Kodlama Kullan"
12
 NVENC.Preset.default="Varsayılan"
13
 NVENC.Preset.hq="Yüksek Kalite"
14
 NVENC.Preset.hp="Yüksek Performans"
15
@@ -34,6 +37,7 @@
16
 DiscardNonIntra="Intra Olmayan Kareler"
17
 DiscardNonKey="Anahtar Olmayan Kareler"
18
 DiscardAll="Tüm Kareler (Dikkatli Olun!)"
19
+RestartWhenActivated="Yeniden oynatmayı kaynak etkin olduğunda yeniden başlat"
20
 ColorRange="YUV Renk Aralığı"
21
 ColorRange.Auto="Otomatik"
22
 ColorRange.Partial="Kısmi"
23
@@ -46,4 +50,5 @@
24
 MediaFileFilter.AllFiles="Tüm Dosyalar"
25
 
26
 ReplayBuffer="Tekrar Oynatma Arabelleği"
27
+ReplayBuffer.Save="Yeniden Oynatmayı Kaydet"
28
 
29
obs-studio-0.17.0.tar.xz/plugins/obs-filters/color-correction-filter.c -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/color-correction-filter.c Changed
37
 
1
@@ -71,6 +71,10 @@
2
 };
3
 
4
 const static float root3 = 0.57735f;
5
+const static float red_weight = 0.299f;
6
+const static float green_weight = 0.587f;
7
+const static float blue_weight = 0.114f;
8
+
9
 
10
 /*
11
  * As the functions' namesake, this provides the internal name of your Filter,
12
@@ -130,15 +134,19 @@
13
            SETTING_SATURATION) + 1.0f;
14
 
15
    /* Factor in the selected color weights. */
16
-   float one_minus_sat = (1.0f - filter->saturation) / 3.0f;
17
-   float sat_val = one_minus_sat + filter->saturation;
18
+   float one_minus_sat_red = (1.0f - filter->saturation) * red_weight;
19
+   float one_minus_sat_green = (1.0f - filter->saturation) * green_weight;
20
+   float one_minus_sat_blue = (1.0f - filter->saturation) * blue_weight;
21
+   float sat_val_red   = one_minus_sat_red + filter->saturation;
22
+   float sat_val_green = one_minus_sat_green + filter->saturation;
23
+   float sat_val_blue  = one_minus_sat_blue + filter->saturation;
24
 
25
    /* Now we build our Saturation matrix. */
26
    filter->sat_matrix = (struct matrix4)
27
    {
28
-       sat_val, one_minus_sat, one_minus_sat, 0.0f,
29
-       one_minus_sat, sat_val, one_minus_sat, 0.0f,
30
-       one_minus_sat, one_minus_sat, sat_val, 0.0f,
31
+       sat_val_red, one_minus_sat_red, one_minus_sat_red, 0.0f,
32
+       one_minus_sat_green, sat_val_green, one_minus_sat_green, 0.0f,
33
+       one_minus_sat_blue, one_minus_sat_blue, sat_val_blue, 0.0f,
34
        0.0f, 0.0f, 0.0f, 1.0f
35
    };
36
 
37
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/color_correction_filter.effect -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/color_correction_filter.effect Changed
40
 
1
@@ -35,10 +35,6 @@
2
    float2 uv : TEXCOORD0;
3
 };
4
 
5
-struct CurrentPixel {
6
-   float4 current_pixel;
7
-};
8
-
9
 VertData VSDefault(VertData vert_in)
10
 {
11
    VertData vert_out;
12
@@ -49,23 +45,20 @@
13
 
14
 float4 PSColorFilterRGBA(VertData vert_in) : TARGET
15
 {
16
-   /* Realize the struct. */
17
-   CurrentPixel pixel = (CurrentPixel) 0;
18
-
19
    /* Grab the current pixel to perform operations on. */
20
-   pixel.current_pixel = image.Sample(textureSampler, vert_in.uv);
21
+   float4 currentPixel = image.Sample(textureSampler, vert_in.uv);
22
 
23
    /* Always address the gamma first. */
24
-   pixel.current_pixel.rgb = pow(pixel.current_pixel.rgb, gamma);
25
+   currentPixel.rgb = pow(currentPixel.rgb, gamma);
26
 
27
    /* Much easier to manipulate pixels for these types of operations
28
     * when in a matrix such as the below. See
29
     * http://www.graficaobscura.com/matrix/index.html and
30
     * https://docs.rainmeter.net/tips/colormatrix-guide/for more info.
31
     */
32
-   pixel.current_pixel = mul(color_matrix, pixel.current_pixel);
33
+   currentPixel = mul(color_matrix, currentPixel);
34
 
35
-   return pixel.current_pixel;
36
+   return currentPixel;
37
 }
38
 
39
 technique Draw
40
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/ca-ES.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/ca-ES.ini Changed
8
 
1
@@ -61,4 +61,6 @@
2
 ScaleFiltering.Bicubic="Bicúbic"
3
 ScaleFiltering.Lanczos="Lanczos"
4
 NoiseSuppress.SuppressLevel="Nivell de supressió (dB)"
5
+Saturation="Saturació"
6
+HueShift="Cavi de tonalitat"
7
 
8
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/cs-CZ.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/cs-CZ.ini Changed
8
 
1
@@ -61,4 +61,6 @@
2
 ScaleFiltering.Bicubic="Bikubický"
3
 ScaleFiltering.Lanczos="Lanczos"
4
 NoiseSuppress.SuppressLevel="Úroveň potlačení (dB)"
5
+Saturation="Saturace"
6
+HueShift="Posun odstínu"
7
 
8
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/eu-ES.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/eu-ES.ini Changed
8
 
1
@@ -61,4 +61,6 @@
2
 ScaleFiltering.Bicubic="Bikubikoa"
3
 ScaleFiltering.Lanczos="Lanczos"
4
 NoiseSuppress.SuppressLevel="Kenketaren maila (dB)"
5
+Saturation="Margoasetasuna"
6
+HueShift="Nabardura Aldaketa"
7
 
8
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/fi-FI.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/fi-FI.ini Changed
8
 
1
@@ -61,4 +61,6 @@
2
 ScaleFiltering.Bicubic="Bicubic"
3
 ScaleFiltering.Lanczos="Lanczos"
4
 NoiseSuppress.SuppressLevel="Vaimennustaso (dB)"
5
+Saturation="Värikylläisyys"
6
+HueShift="Värisävy"
7
 
8
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/it-IT.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/it-IT.ini Changed
8
 
1
@@ -61,4 +61,6 @@
2
 ScaleFiltering.Bicubic="Bicubico"
3
 ScaleFiltering.Lanczos="Lanczos"
4
 NoiseSuppress.SuppressLevel="Livello di soppressione (dB)"
5
+Saturation="Saturazione"
6
+HueShift="Cambio di tonalità"
7
 
8
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/ru-RU.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/ru-RU.ini Changed
8
 
1
@@ -61,4 +61,6 @@
2
 ScaleFiltering.Bicubic="Бикубическая"
3
 ScaleFiltering.Lanczos="Метод Ланцоша"
4
 NoiseSuppress.SuppressLevel="Уровень подавления (дБ)"
5
+Saturation="Насыщенность"
6
+HueShift="Сдвиг оттенка"
7
 
8
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/sv-SE.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/sv-SE.ini Changed
7
 
1
@@ -61,4 +61,5 @@
2
 ScaleFiltering.Bicubic="Bikubisk"
3
 ScaleFiltering.Lanczos="Lanczos"
4
 NoiseSuppress.SuppressLevel="Brusreduceringsnivå (dB)"
5
+Saturation="Mättnad"
6
 
7
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/tr-TR.ini Changed
30
 
1
@@ -1,10 +1,12 @@
2
 ColorFilter="Renk Düzeltme"
3
 MaskFilter="Görüntü Maskesi/Blend"
4
 AsyncDelayFilter="Görüntü Gecikmesi (Async)"
5
+CropFilter="Kes/Kaydır"
6
 ScrollFilter="Kaydır"
7
 ChromaKeyFilter="Chroma Anahtarı"
8
 ColorKeyFilter="Renk Anahtarı"
9
 SharpnessFilter="Keskinleştirme"
10
+ScaleFilter="Ölçeklendirme/Boy Oranı"
11
 NoiseGate="Gürültü Filtresi"
12
 NoiseSuppress="Gürültü Bastırma"
13
 Gain="Kazanç"
14
@@ -50,6 +52,7 @@
15
 NoiseGate.HoldTime="Kavrama Süresi (milisaniye)"
16
 NoiseGate.ReleaseTime="Bırakma Süresi (milisaniye)"
17
 Gain.GainDB="Kazanç (dB)"
18
+StretchImage="Görüntüyü Uzat (görüntü boy oranını görmezden gelir)"
19
 Resolution="Çözünürlük"
20
 None="Hiçbiri"
21
 ScaleFiltering="Ölçek Filtreleme"
22
@@ -57,4 +60,7 @@
23
 ScaleFiltering.Bilinear="Bilinear"
24
 ScaleFiltering.Bicubic="Bicubic"
25
 ScaleFiltering.Lanczos="Lanczos"
26
+NoiseSuppress.SuppressLevel="Bastırma Düzeyi (dB)"
27
+Saturation="Renk Doygunluğu"
28
+HueShift="Ton Kayması"
29
 
30
obs-studio-0.17.0.tar.xz/plugins/obs-filters/data/locale/uk-UA.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-filters/data/locale/uk-UA.ini Changed
8
 
1
@@ -61,4 +61,6 @@
2
 ScaleFiltering.Bicubic="Бікубічний"
3
 ScaleFiltering.Lanczos="Ланцош"
4
 NoiseSuppress.SuppressLevel="Рівень подавлення (дБ)"
5
+Saturation="Насиченість"
6
+HueShift="Відтінок"
7
 
8
obs-studio-0.17.0.tar.xz/plugins/obs-libfdk/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-libfdk/data/locale/hu-HU.ini Changed
7
 
1
@@ -1,4 +1,4 @@
2
 LibFDK="libfdk AAC kódoló"
3
-Bitrate="Bitráta"
4
+Bitrate="Bitsebesség"
5
 Afterburner="AAC Afterburner engedélyezése"
6
 
7
obs-studio-0.17.0.tar.xz/plugins/obs-outputs/net-if.h -> obs-studio-17.0.1.tar.xz/plugins/obs-outputs/net-if.h Changed
9
 
1
@@ -29,6 +29,7 @@
2
 #  ifdef __linux__
3
 #    include <linux/if_link.h>
4
 #  elif __FreeBSD__
5
+#    include <netinet/in.h>
6
 #    ifndef _GNU_SOURCE
7
 #      define _GNU_SOURCE
8
 #      define __NET_IF_GNU_SOURCE__
9
obs-studio-0.17.0.tar.xz/plugins/obs-qsv11/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-qsv11/data/locale/hu-HU.ini Changed
10
 
1
@@ -1,6 +1,6 @@
2
 TargetUsage="Felhasználási cél"
3
-Bitrate="Bitráta"
4
-MaxBitrate="Max bitráta"
5
+Bitrate="Bitsebesség"
6
+MaxBitrate="Max bitsebesség"
7
 RateControl="Sebesség Vezérlés"
8
 KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)"
9
 Profile="Profil"
10
obs-studio-0.17.0.tar.xz/plugins/obs-qsv11/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-qsv11/data/locale/tr-TR.ini Changed
14
 
1
@@ -1,8 +1,12 @@
2
 TargetUsage="Hedef Kullanımı"
3
 Bitrate="Bit hızı"
4
 MaxBitrate="Maks Bit hızı"
5
+RateControl="Oran Kontrolü"
6
 KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)"
7
 Profile="Profil"
8
+AsyncDepth="Eşzamansız Derinlik"
9
 Accuracy="Doğruluk"
10
+Convergence="Yakınsama"
11
 ICQQuality="ICQ Kalitesi"
12
+LookAheadDepth="İleri Yönlü Derinlik"
13
 
14
obs-studio-0.17.0.tar.xz/plugins/obs-text/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-text/data/locale/tr-TR.ini Changed
9
 
1
@@ -26,6 +26,7 @@
2
 Outline.Color="Anahat Rengi"
3
 Outline.Opacity="Anahat Saydamlığı"
4
 UseCustomExtents="İsteğe Bağlı Metin Boyutu Kullan"
5
+UseCustomExtents.Wrap="Metni Kaydır"
6
 Width="Genişlik"
7
 Height="Yükseklik"
8
 
9
obs-studio-0.17.0.tar.xz/plugins/obs-transitions/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-transitions/data/locale/tr-TR.ini Changed
10
 
1
@@ -10,6 +10,8 @@
2
 Direction.Down="Aşağı"
3
 SwipeIn="İçeri Kaydır"
4
 Color="Renk"
5
+SwitchPoint="En yüksek Renk Noktası (yüzde)"
6
+LumaWipeTransition="Luma Wipe"
7
 LumaWipe.Image="Görüntü"
8
 LumaWipe.Invert="Ters Çevir"
9
 LumaWipe.Softness="Yumuşaklık"
10
obs-studio-0.17.0.tar.xz/plugins/obs-x264/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-x264/data/locale/hu-HU.ini Changed
7
 
1
@@ -1,4 +1,4 @@
2
-Bitrate="Bitráta"
3
+Bitrate="Bitsebesség"
4
 CustomBufsize="Egyéni pufferméret használata"
5
 BufferSize="Pufferméret"
6
 RateControl="Sebesség Vezérlés"
7
obs-studio-0.17.0.tar.xz/plugins/obs-x264/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/obs-x264/data/locale/tr-TR.ini Changed
9
 
1
@@ -1,6 +1,7 @@
2
 Bitrate="Bit hızı"
3
 CustomBufsize="İsteğe Bağlı Arabellek Boyutu Kullan"
4
 BufferSize="Arabellek Boyutu"
5
+RateControl="Oran Kontrolü"
6
 CRF="CRF"
7
 KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)"
8
 CPUPreset="CPU Kullanım Önayarı (yüksek = az CPU kullanımı)"
9
obs-studio-0.17.0.tar.xz/plugins/obs-x264/obs-x264.c -> obs-studio-17.0.1.tar.xz/plugins/obs-x264/obs-x264.c Changed
22
 
1
@@ -288,6 +288,8 @@
2
                preset, profile, tune);
3
 }
4
 
5
+#define OPENCL_ALIAS "opencl_is_experimental_and_potentially_unstable"
6
+
7
 static inline void set_param(struct obs_x264 *obsx264, const char *param)
8
 {
9
    char       *name;
10
@@ -300,7 +302,10 @@
11
            strcmp(name, "fps")       != 0 &&
12
            strcmp(name, "force-cfr") != 0 &&
13
            strcmp(name, "width")     != 0 &&
14
-           strcmp(name, "height")    != 0) {
15
+           strcmp(name, "height")    != 0 &&
16
+           strcmp(name, "opencl")    != 0) {
17
+           if (strcmp(name, OPENCL_ALIAS) == 0)
18
+               strcpy(name, "opencl");
19
            if (x264_param_parse(&obsx264->params, name, val) != 0)
20
                warn("x264 param: %s failed", param);
21
        }
22
obs-studio-0.17.0.tar.xz/plugins/rtmp-services/data/package.json -> obs-studio-17.0.1.tar.xz/plugins/rtmp-services/data/package.json Changed
14
 
1
@@ -1,10 +1,10 @@
2
 {
3
    "url": "https://obsproject.com/obs2_update/rtmp-services",
4
-   "version": 43,
5
+   "version": 44,
6
    "files": [
7
        {
8
            "name": "services.json",
9
-           "version": 43
10
+           "version": 44
11
        }
12
    ]
13
 }
14
obs-studio-0.17.0.tar.xz/plugins/rtmp-services/data/services.json -> obs-studio-17.0.1.tar.xz/plugins/rtmp-services/data/services.json Changed
10
 
1
@@ -133,7 +133,7 @@
2
             "recommended": {
3
                 "keyint": 2,
4
                 "profile": "main",
5
-                "max video bitrate": 18000,
6
+                "max video bitrate": 51000,
7
                 "max audio bitrate": 160
8
             }
9
         },
10
obs-studio-0.17.0.tar.xz/plugins/vlc-video/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/vlc-video/data/locale/tr-TR.ini Changed
10
 
1
@@ -1,3 +1,8 @@
2
 VLCSource="VLC Video Kaynağı"
3
 Playlist="Oynatma Listesi"
4
+LoopPlaylist="Oynatma Listesini Yinele"
5
+PlaybackBehavior="Görünürlük davranışı"
6
+PlaybackBehavior.StopRestart="Görünür değilken durdur, görünür olunca yeniden başlat"
7
+PlaybackBehavior.PauseUnpause="Görünür değilken duraklat, görünür olunca oynat"
8
+PlaybackBehavior.AlwaysPlay="Görünür değilken bile oynat"
9
 
10
obs-studio-0.17.0.tar.xz/plugins/win-capture/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/win-capture/data/locale/tr-TR.ini Changed
16
 
1
@@ -12,10 +12,14 @@
2
 PrimaryMonitor="Birincil Ekran"
3
 GameCapture="Oyun Yakalama"
4
 GameCapture.AnyFullscreen="Tam ekran herhangi bir uygulamayı yakala"
5
+GameCapture.CaptureWindow="Belirli bir pencereyi yakala"
6
+GameCapture.UseHotkey="Ön plandaki pencereyi kısayol ile yakala"
7
 GameCapture.ForceScaling="Zorla Ölçekle"
8
 GameCapture.ScaleRes="Ölçekleme Çözünürlüğü"
9
 GameCapture.LimitFramerate="Yakalama kare hızını sınırlandır"
10
 GameCapture.CaptureOverlays="Üçüncü taraf katmanları yakala (steam vb.)"
11
 GameCapture.AntiCheatHook="Anti-hile uyumluluğunu kullan"
12
+GameCapture.HotkeyStart="Ön plandaki pencereyi yakala"
13
+GameCapture.HotkeyStop="Yakalamayı devre dışı bırak"
14
 Mode="Mod"
15
 
16
obs-studio-0.17.0.tar.xz/plugins/win-capture/game-capture.c -> obs-studio-17.0.1.tar.xz/plugins/win-capture/game-capture.c Changed
130
 
1
@@ -136,8 +136,7 @@
2
    ipc_pipe_server_t             pipe;
3
    gs_texture_t                  *texture;
4
    struct hook_info              *global_hook_info;
5
-   HANDLE                        keepalive_thread;
6
-   DWORD                         keepalive_thread_id;
7
+   HANDLE                        keepalive_mutex;
8
    HANDLE                        hook_init;
9
    HANDLE                        hook_restart;
10
    HANDLE                        hook_stop;
11
@@ -281,12 +280,6 @@
12
        gc->data = NULL;
13
    }
14
 
15
-   if (gc->keepalive_thread) {
16
-       PostThreadMessage(gc->keepalive_thread_id, WM_QUIT, 0, 0);
17
-       WaitForSingleObject(gc->keepalive_thread, 300);
18
-       close_handle(&gc->keepalive_thread);
19
-   }
20
-
21
    if (gc->app_sid) {
22
        LocalFree(gc->app_sid);
23
        gc->app_sid = NULL;
24
@@ -298,6 +291,7 @@
25
    close_handle(&gc->hook_exit);
26
    close_handle(&gc->hook_init);
27
    close_handle(&gc->hook_data_map);
28
+   close_handle(&gc->keepalive_mutex);
29
    close_handle(&gc->global_hook_info_map);
30
    close_handle(&gc->target_process);
31
    close_handle(&gc->texture_mutexes[0]);
32
@@ -641,78 +635,18 @@
33
    return true;
34
 }
35
 
36
-struct keepalive_data {
37
-   struct game_capture *gc;
38
-   HANDLE initialized;
39
-};
40
-
41
-#define DEF_FLAGS (WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
42
-
43
-static DWORD WINAPI keepalive_window_thread(struct keepalive_data *data)
44
-{
45
-   HANDLE initialized = data->initialized;
46
-   struct game_capture *gc = data->gc;
47
-   wchar_t new_name[64];
48
-   WNDCLASSW wc;
49
-   HWND window;
50
-   MSG msg;
51
-
52
-   _snwprintf(new_name, sizeof(new_name), L"%s%lu",
53
-           WINDOW_HOOK_KEEPALIVE, gc->process_id);
54
-
55
-   memset(&wc, 0, sizeof(wc));
56
-   wc.style = CS_OWNDC;
57
-   wc.hInstance = GetModuleHandleW(NULL);
58
-   wc.lpfnWndProc = (WNDPROC)DefWindowProc;
59
-   wc.lpszClassName = new_name;
60
-
61
-   if (!RegisterClass(&wc)) {
62
-       warn("Failed to create keepalive window class: %lu",
63
-               GetLastError());
64
-       return 0;
65
-   }
66
-
67
-   window = CreateWindowExW(0, new_name, NULL, DEF_FLAGS, 0, 0, 1, 1,
68
-           NULL, NULL, wc.hInstance, NULL);
69
-   if (!window) {
70
-       warn("Failed to create keepalive window: %lu",
71
-               GetLastError());
72
-       return 0;
73
-   }
74
-
75
-   SetEvent(initialized);
76
-
77
-   while (GetMessage(&msg, NULL, 0, 0)) {
78
-       TranslateMessage(&msg);
79
-       DispatchMessage(&msg);
80
-   }
81
-
82
-   DestroyWindow(window);
83
-   UnregisterClassW(new_name, wc.hInstance);
84
-
85
-   return 0;
86
-}
87
-
88
 static inline bool init_keepalive(struct game_capture *gc)
89
 {
90
-   struct keepalive_data data;
91
-   HANDLE initialized = CreateEvent(NULL, false, false, NULL);
92
-
93
-   data.gc = gc;
94
-   data.initialized = initialized;
95
+   wchar_t new_name[64];
96
+   _snwprintf(new_name, 64, L"%s%lu", WINDOW_HOOK_KEEPALIVE,
97
+           gc->process_id);
98
 
99
-   gc->keepalive_thread = CreateThread(NULL, 0,
100
-           (LPTHREAD_START_ROUTINE)keepalive_window_thread,
101
-           &data, 0, &gc->keepalive_thread_id);
102
-   if (!gc->keepalive_thread) {
103
-       warn("Failed to create keepalive window thread: %lu",
104
-               GetLastError());
105
+   gc->keepalive_mutex = CreateMutexW(NULL, false, new_name);
106
+   if (!gc->keepalive_mutex) {
107
+       warn("Failed to create keepalive mutex: %lu", GetLastError());
108
        return false;
109
    }
110
 
111
-   WaitForSingleObject(initialized, INFINITE);
112
-   CloseHandle(initialized);
113
-
114
    return true;
115
 }
116
 
117
@@ -794,8 +728,10 @@
118
    gc->global_hook_info->capture_overlay = gc->config.capture_overlays;
119
    gc->global_hook_info->force_shmem = gc->config.force_shmem;
120
    gc->global_hook_info->use_scale = gc->config.force_scaling;
121
-   gc->global_hook_info->cx = gc->config.scale_cx;
122
-   gc->global_hook_info->cy = gc->config.scale_cy;
123
+   if (gc->config.scale_cx)
124
+       gc->global_hook_info->cx = gc->config.scale_cx;
125
+   if (gc->config.scale_cy)
126
+       gc->global_hook_info->cy = gc->config.scale_cy;
127
    reset_frame_interval(gc);
128
 
129
    obs_enter_graphics();
130
obs-studio-0.17.0.tar.xz/plugins/win-capture/graphics-hook/graphics-hook.h -> obs-studio-17.0.1.tar.xz/plugins/win-capture/graphics-hook/graphics-hook.h Changed
16
 
1
@@ -143,7 +143,13 @@
2
 
3
 static inline bool capture_alive(void)
4
 {
5
-   return !!FindWindowW(keepalive_name, NULL);
6
+   HANDLE handle = OpenMutexW(SYNCHRONIZE, false, keepalive_name);
7
+   CloseHandle(handle);
8
+
9
+   if (handle)
10
+       return true;
11
+
12
+   return GetLastError() != ERROR_FILE_NOT_FOUND;
13
 }
14
 
15
 static inline bool capture_active(void)
16
obs-studio-0.17.0.tar.xz/plugins/win-capture/window-helpers.c -> obs-studio-17.0.1.tar.xz/plugins/win-capture/window-helpers.c Changed
37
 
1
@@ -240,7 +240,7 @@
2
    HWND child;
3
 
4
    GetWindowThreadProcessId(parent, &parent_id);
5
-   child = FindWindowEx(parent, NULL, NULL, NULL);
6
+   child = GetWindow(parent, GW_CHILD);
7
 
8
    while (child) {
9
        DWORD child_id = 0;
10
@@ -249,7 +249,7 @@
11
        if (child_id != parent_id)
12
            return child;
13
 
14
-       child = FindWindowEx(parent, child, NULL, NULL);
15
+       child = GetNextWindow(child, GW_HWNDNEXT);
16
    }
17
 
18
    return NULL;
19
@@ -264,7 +264,7 @@
20
    }
21
 
22
    while (true) {
23
-       window = FindWindowEx(GetDesktopWindow(), window, NULL, NULL);
24
+       window = GetNextWindow(window, GW_HWNDNEXT);
25
        if (!window || check_window_valid(window, mode))
26
            break;
27
    }
28
@@ -282,7 +282,7 @@
29
 
30
 static inline HWND first_window(enum window_search_mode mode, HWND *parent)
31
 {
32
-   HWND window = FindWindowEx(GetDesktopWindow(), NULL, NULL, NULL);
33
+   HWND window = GetWindow(GetDesktopWindow(), GW_CHILD);
34
 
35
    *parent = NULL;
36
 
37
obs-studio-0.17.0.tar.xz/plugins/win-dshow/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/win-dshow/data/locale/hu-HU.ini Changed
10
 
1
@@ -33,7 +33,7 @@
2
 FlipVertically="Függőleges tükrözés"
3
 DeactivateWhenNotShowing="Kikapcsolás, ha nem jelenik meg"
4
 
5
-Bitrate="Bitráta"
6
+Bitrate="Bitsebesség"
7
 Encoder.C985="AVerMedia H.264 kódoló (c985)"
8
 Encoder.C353="AVerMedia H.264 kódoló"
9
 
10
obs-studio-0.17.0.tar.xz/plugins/win-dshow/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/win-dshow/data/locale/tr-TR.ini Changed
9
 
1
@@ -30,6 +30,7 @@
2
 Activate="Etkinleştir"
3
 Deactivate="Devredışı Bırak"
4
 FlipVertically="Dikey Çevir"
5
+DeactivateWhenNotShowing="Gösterilmediğinde devre dışı bırak"
6
 
7
 Bitrate="Bit hızı"
8
 Encoder.C985="AVerMedia H.264 Kodlayıcısı (c985)"
9
obs-studio-0.17.0.tar.xz/plugins/win-mf/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/win-mf/data/locale/hu-HU.ini Changed
27
 
1
@@ -1,5 +1,5 @@
2
 MFAACEnc="Media Foundation AAC kódoló"
3
-Bitrate="Bitráta"
4
+Bitrate="Bitsebesség"
5
 
6
 MF.H264.EncoderName="Media Foundation H264 kódoló"
7
 MF.H264.Encoder="Kódoló név"
8
@@ -7,13 +7,13 @@
9
 MF.H264.BFrames="Egymást követő B-Frame szám"
10
 MF.H264.CustomBufsize="Egyéni pufferméret használata"
11
 MF.H264.BufferSize="Pufferméret"
12
-MF.H264.CustomMaxBitrate="Egyéni maximális bitráta használata"
13
-MF.H264.Bitrate="Bitráta"
14
-MF.H264.MaxBitrate="Max bitráta"
15
+MF.H264.CustomMaxBitrate="Egyéni maximális bitsebesség használata"
16
+MF.H264.Bitrate="Bitsebesség"
17
+MF.H264.MaxBitrate="Max bitsebesség"
18
 MF.H264.KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)"
19
 MF.H264.RateControl="Sebesség vezérlés"
20
-MF.H264.CBR="CBR (állandó bitráta)"
21
-MF.H264.VBR="VBR (változó bitráta)"
22
+MF.H264.CBR="CBR (állandó bitsebesség)"
23
+MF.H264.VBR="VBR (változó bitsebesség)"
24
 MF.H264.CQP="CQP (állandó minőség)"
25
 MF.H264.MinQP="Minimális QP"
26
 MF.H264.MaxQP="Maximális QP"
27
obs-studio-0.17.0.tar.xz/plugins/win-mf/data/locale/tr-TR.ini -> obs-studio-17.0.1.tar.xz/plugins/win-mf/data/locale/tr-TR.ini Changed
31
 
1
@@ -3,15 +3,28 @@
2
 
3
 MF.H264.EncoderName="Medya Vakfı H264 Kodlayıcısı"
4
 MF.H264.Encoder="Kodlayıcı Adı"
5
+MF.H264.LowLatency="Düşük Gecikme Süresi (Çerçeve yeniden sıralamasını devre dışı bırak)"
6
+MF.H264.BFrames="Ardışık B-Frame sayısı"
7
 MF.H264.CustomBufsize="İsteğe Bağlı Arabellek Boyutu Kullan"
8
 MF.H264.BufferSize="Arabellek Boyutu"
9
+MF.H264.CustomMaxBitrate="Özel En Yüksek Bit Hızı Kullan"
10
 MF.H264.Bitrate="Bithızı"
11
-MF.H264.MaxBitrate="Maks Bit hızı"
12
+MF.H264.MaxBitrate="En Yüksek Bit Hızı"
13
 MF.H264.KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)"
14
+MF.H264.RateControl="Oran Kontrolü"
15
+MF.H264.CBR="CBR (Sabit bit hızı)"
16
 MF.H264.VBR="VBR (Değişken Bit Hızı)"
17
+MF.H264.CQP="CQP (Sabit Kalite)"
18
 MF.H264.MinQP="Minimum QP"
19
 MF.H264.MaxQP="Maksimum QP"
20
+MF.H264.QPI="QP I-Frame"
21
+MF.H264.QPP="QP P-Frame"
22
+MF.H264.QPB="QP B-Frame"
23
 MF.H264.Profile="Profil"
24
 MF.H264.Advanced="Gelişmiş"
25
 
26
+MF.H264.EncoderSWMicrosoft="Microsoft Software H.264 Kodlayıcısı"
27
+MF.H264.EncoderHWAMD="AMD Video Coding Engine H.264 Kodlayıcısı (Media Foundation)"
28
+MF.H264.EncoderHWIntel="Intel Quick Sync H.264 Kodlayıcısı (Media Foundation)"
29
+MF.H264.EncoderHWNVIDIA="NVIDIA NVENC H.264 Kodlayıcısı (Media Foundation)"
30
 
31
obs-studio-0.17.0.tar.xz/plugins/win-wasapi/data/locale/hu-HU.ini -> obs-studio-17.0.1.tar.xz/plugins/win-wasapi/data/locale/hu-HU.ini Changed
9
 
1
@@ -1,5 +1,5 @@
2
-AudioInput="Bemeneti hangrögzítés"
3
-AudioOutput="Kimeneti hangrögzítés"
4
+AudioInput="Bemeneti hangrögzítő"
5
+AudioOutput="Kimeneti hangrögzítő"
6
 Device="Eszköz"
7
 Default="Alapértelmezett"
8
 UseDeviceTiming="Eszköz időbélyegzőinek használata"
9