1 /* common.c
2
3 Copyright (c) 2003-2021 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
8 */
9
10 #include <stdarg.h>
11 #include <time.h>
12 #include <ctype.h>
13 #include <sys/time.h>
14
15 #include "handbrake/handbrake.h"
16 #include "handbrake/hbffmpeg.h"
17 #include "x264.h"
18 #include "handbrake/lang.h"
19 #include "handbrake/common.h"
20 #include "handbrake/h264_common.h"
21 #include "handbrake/h265_common.h"
22 #include "handbrake/encx264.h"
23 #if HB_PROJECT_FEATURE_QSV
24 #include "handbrake/qsv_common.h"
25 #endif
26
27 #if HB_PROJECT_FEATURE_X265
28 #include "x265.h"
29 #endif
30
31 #ifdef SYS_MINGW
32 #include <windows.h>
33 #endif
34
35 #if HB_PROJECT_FEATURE_NVENC
36 #include "handbrake/nvenc_common.h"
37 #endif
38 #if HB_PROJECT_FEATURE_VCE
39 #include "handbrake/vce_common.h"
40 #endif
41
42 #ifdef __APPLE__
43 #include "platform/macosx/vt_common.h"
44 #endif
45
46 static int mixdown_get_opus_coupled_stream_count(int mixdown);
47
48 /**********************************************************************
49 * Global variables
50 *********************************************************************/
51 static hb_error_handler_t *error_handler = NULL;
52
53 /* Generic IDs for encoders, containers, etc. */
54 enum
55 {
56 HB_GID_NONE = -1, // encoders must NEVER use it
57 HB_GID_VCODEC_H264_MF,
58 HB_GID_VCODEC_H264_NVENC,
59 HB_GID_VCODEC_H264_QSV,
60 HB_GID_VCODEC_H264_VCE,
61 HB_GID_VCODEC_H264_VT,
62 HB_GID_VCODEC_H264_X264,
63 HB_GID_VCODEC_H265_MF,
64 HB_GID_VCODEC_H265_NVENC,
65 HB_GID_VCODEC_H265_QSV,
66 HB_GID_VCODEC_H265_VCE,
67 HB_GID_VCODEC_H265_VT,
68 HB_GID_VCODEC_H265_X265,
69 HB_GID_VCODEC_MPEG2,
70 HB_GID_VCODEC_MPEG4,
71 HB_GID_VCODEC_THEORA,
72 HB_GID_VCODEC_VP8,
73 HB_GID_VCODEC_VP9,
74 HB_GID_ACODEC_AAC,
75 HB_GID_ACODEC_AAC_HE,
76 HB_GID_ACODEC_AAC_PASS,
77 HB_GID_ACODEC_AC3,
78 HB_GID_ACODEC_AC3_PASS,
79 HB_GID_ACODEC_AUTO_PASS,
80 HB_GID_ACODEC_DTS_PASS,
81 HB_GID_ACODEC_DTSHD_PASS,
82 HB_GID_ACODEC_EAC3,
83 HB_GID_ACODEC_EAC3_PASS,
84 HB_GID_ACODEC_FLAC,
85 HB_GID_ACODEC_FLAC_PASS,
86 HB_GID_ACODEC_MP2_PASS,
87 HB_GID_ACODEC_MP3,
88 HB_GID_ACODEC_MP3_PASS,
89 HB_GID_ACODEC_TRUEHD_PASS,
90 HB_GID_ACODEC_VORBIS,
91 HB_GID_ACODEC_OPUS,
92 HB_GID_MUX_MKV,
93 HB_GID_MUX_MP4,
94 HB_GID_MUX_WEBM,
95 };
96
97 #define HB_VIDEO_CLOCK 27000000 // 27MHz clock
98 #define HB_VIDEO_FPS_MIN 1
99 #define HB_VIDEO_FPS_MAX 1000
100 int hb_video_rate_clock = HB_VIDEO_CLOCK;
101 int hb_video_rate_min = HB_VIDEO_CLOCK / HB_VIDEO_FPS_MAX; // Min clock rate from *max* frame rate
102 int hb_video_rate_max = HB_VIDEO_CLOCK / HB_VIDEO_FPS_MIN; // Max clock rate from *min* frame rate
103
104 typedef struct
105 {
106 hb_rate_t item;
107 hb_rate_t *next;
108 int enabled;
109 } hb_rate_internal_t;
110 hb_rate_t *hb_video_rates_first_item = NULL;
111 hb_rate_t *hb_video_rates_last_item = NULL;
112 hb_rate_internal_t hb_video_rates[] =
113 {
114 // legacy framerates (disabled)
115 { { "23.976 (NTSC Film)", 1126125, }, NULL, 0, },
116 { { "25 (PAL Film/Video)", 1080000, }, NULL, 0, },
117 { { "29.97 (NTSC Video)", 900900, }, NULL, 0, },
118 // actual framerates
119 { { "5", 5400000, }, NULL, 1, },
120 { { "10", 2700000, }, NULL, 1, },
121 { { "12", 2250000, }, NULL, 1, },
122 { { "15", 1800000, }, NULL, 1, },
123 { { "20", 1350000, }, NULL, 1, },
124 { { "23.976", 1126125, }, NULL, 1, },
125 { { "24", 1125000, }, NULL, 1, },
126 { { "25", 1080000, }, NULL, 1, },
127 { { "29.97", 900900, }, NULL, 1, },
128 { { "30", 900000, }, NULL, 1, },
129 { { "48", 562500, }, NULL, 1, },
130 { { "50", 540000, }, NULL, 1, },
131 { { "59.94", 450450, }, NULL, 1, },
132 { { "60", 450000, }, NULL, 1, },
133 { { "72", 375000, }, NULL, 1, },
134 { { "75", 360000, }, NULL, 1, },
135 { { "90", 300000, }, NULL, 1, },
136 { { "100", 270000, }, NULL, 1, },
137 { { "120", 225000, }, NULL, 1, },
138 };
139 int hb_video_rates_count = sizeof(hb_video_rates) / sizeof(hb_video_rates[0]);
140
141 hb_rate_t *hb_audio_rates_first_item = NULL;
142 hb_rate_t *hb_audio_rates_last_item = NULL;
143 hb_rate_internal_t hb_audio_rates[] =
144 {
145 { { "8", 8000, }, NULL, 1, },
146 { { "11.025", 11025, }, NULL, 1, },
147 { { "12", 12000, }, NULL, 1, },
148 { { "16", 16000, }, NULL, 1, },
149 { { "22.05", 22050, }, NULL, 1, },
150 { { "24", 24000, }, NULL, 1, },
151 { { "32", 32000, }, NULL, 1, },
152 { { "44.1", 44100, }, NULL, 1, },
153 { { "48", 48000, }, NULL, 1, },
154 };
155 int hb_audio_rates_count = sizeof(hb_audio_rates) / sizeof(hb_audio_rates[0]);
156
157 hb_rate_t *hb_audio_bitrates_first_item = NULL;
158 hb_rate_t *hb_audio_bitrates_last_item = NULL;
159 hb_rate_internal_t hb_audio_bitrates[] =
160 {
161 // AC3-compatible bitrates
162 { { "6", 6, }, NULL, 1, },
163 { { "12", 12, }, NULL, 1, },
164 { { "24", 24, }, NULL, 1, },
165 { { "32", 32, }, NULL, 1, },
166 { { "40", 40, }, NULL, 1, },
167 { { "48", 48, }, NULL, 1, },
168 { { "56", 56, }, NULL, 1, },
169 { { "64", 64, }, NULL, 1, },
170 { { "80", 80, }, NULL, 1, },
171 { { "96", 96, }, NULL, 1, },
172 { { "112", 112, }, NULL, 1, },
173 { { "128", 128, }, NULL, 1, },
174 { { "160", 160, }, NULL, 1, },
175 { { "192", 192, }, NULL, 1, },
176 { { "224", 224, }, NULL, 1, },
177 { { "256", 256, }, NULL, 1, },
178 { { "320", 320, }, NULL, 1, },
179 { { "384", 384, }, NULL, 1, },
180 { { "448", 448, }, NULL, 1, },
181 { { "512", 512, }, NULL, 1, },
182 { { "576", 576, }, NULL, 1, },
183 { { "640", 640, }, NULL, 1, },
184 // additional bitrates
185 { { "768", 768, }, NULL, 1, },
186 { { "960", 960, }, NULL, 1, },
187 { { "1152", 1152, }, NULL, 1, },
188 { { "1344", 1344, }, NULL, 1, },
189 { { "1536", 1536, }, NULL, 1, },
190 { { "2304", 2304, }, NULL, 1, },
191 { { "3072", 3072, }, NULL, 1, },
192 { { "4608", 4608, }, NULL, 1, },
193 { { "6144", 6144, }, NULL, 1, },
194 };
195 int hb_audio_bitrates_count = sizeof(hb_audio_bitrates) / sizeof(hb_audio_bitrates[0]);
196
197 typedef struct
198 {
199 hb_dither_t item;
200 hb_dither_t *next;
201 int enabled;
202 } hb_dither_internal_t;
203 hb_dither_t *hb_audio_dithers_first_item = NULL;
204 hb_dither_t *hb_audio_dithers_last_item = NULL;
205 hb_dither_internal_t hb_audio_dithers[] =
206 {
207 { { "default", "auto", SWR_DITHER_NONE - 1, }, NULL, 1, },
208 { { "none", "none", SWR_DITHER_NONE, }, NULL, 1, },
209 { { "rectangular", "rectangular", SWR_DITHER_RECTANGULAR, }, NULL, 1, },
210 { { "triangular", "triangular", SWR_DITHER_TRIANGULAR, }, NULL, 1, },
211 { { "triangular with high pass", "triangular_hp", SWR_DITHER_TRIANGULAR_HIGHPASS, }, NULL, 1, },
212 { { "lipshitz noise shaping", "lipshitz_ns", SWR_DITHER_NS_LIPSHITZ, }, NULL, 1, },
213 };
214 int hb_audio_dithers_count = sizeof(hb_audio_dithers) / sizeof(hb_audio_dithers[0]);
215
216 typedef struct
217 {
218 hb_mixdown_t item;
219 hb_mixdown_t *next;
220 int enabled;
221 } hb_mixdown_internal_t;
222 hb_mixdown_t *hb_audio_mixdowns_first_item = NULL;
223 hb_mixdown_t *hb_audio_mixdowns_last_item = NULL;
224 hb_mixdown_internal_t hb_audio_mixdowns[] =
225 {
226 // legacy mixdowns, back to HB 0.9.4 whenever possible (disabled)
227 { { "AC3 Passthru", "", HB_AMIXDOWN_NONE, }, NULL, 0, },
228 { { "DTS Passthru", "", HB_AMIXDOWN_NONE, }, NULL, 0, },
229 { { "DTS-HD Passthru", "", HB_AMIXDOWN_NONE, }, NULL, 0, },
230 { { "6-channel discrete", "6ch", HB_AMIXDOWN_5POINT1, }, NULL, 0, },
231 // actual mixdowns
232 { { "None", "none", HB_AMIXDOWN_NONE, }, NULL, 1, },
233 { { "Mono", "mono", HB_AMIXDOWN_MONO, }, NULL, 1, },
234 { { "Mono (Left Only)", "left_only", HB_AMIXDOWN_LEFT, }, NULL, 1, },
235 { { "Mono (Right Only)", "right_only", HB_AMIXDOWN_RIGHT, }, NULL, 1, },
236 { { "Stereo", "stereo", HB_AMIXDOWN_STEREO, }, NULL, 1, },
237 { { "Dolby Surround", "dpl1", HB_AMIXDOWN_DOLBY, }, NULL, 1, },
238 { { "Dolby Pro Logic II", "dpl2", HB_AMIXDOWN_DOLBYPLII, }, NULL, 1, },
239 { { "5.1 Channels", "5point1", HB_AMIXDOWN_5POINT1, }, NULL, 1, },
240 { { "6.1 Channels", "6point1", HB_AMIXDOWN_6POINT1, }, NULL, 1, },
241 { { "7.1 Channels", "7point1", HB_AMIXDOWN_7POINT1, }, NULL, 1, },
242 { { "7.1 (5F/2R/LFE)", "5_2_lfe", HB_AMIXDOWN_5_2_LFE, }, NULL, 1, },
243 };
244 int hb_audio_mixdowns_count = sizeof(hb_audio_mixdowns) / sizeof(hb_audio_mixdowns[0]);
245
246 typedef struct
247 {
248 hb_encoder_t item;
249 hb_encoder_t *next;
250 int deprecated;
251 int enabled;
252 int gid;
253 } hb_encoder_internal_t;
254 hb_encoder_t *hb_video_encoders_first_item = NULL;
255 hb_encoder_t *hb_video_encoders_last_item = NULL;
256 hb_encoder_internal_t hb_video_encoders[] =
257 {
258 // legacy encoders, back to HB 0.9.4 whenever possible (disabled)
259 { { "FFmpeg", "ffmpeg", NULL, HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_VCODEC_MPEG4, },
260 { { "MPEG-4 (FFmpeg)", "ffmpeg4", NULL, HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_VCODEC_MPEG4, },
261 { { "MPEG-2 (FFmpeg)", "ffmpeg2", NULL, HB_VCODEC_FFMPEG_MPEG2, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_VCODEC_MPEG2, },
262 { { "VP3 (Theora)", "libtheora", NULL, HB_VCODEC_THEORA, HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_VCODEC_THEORA, },
263 // actual encoders
264 { { "H.264 (x264)", "x264", "H.264 (libx264)", HB_VCODEC_X264_8BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H264_X264, },
265 { { "H.264 10-bit (x264)", "x264_10bit", "H.264 10-bit (libx264)", HB_VCODEC_X264_10BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H264_X264, },
266 { { "H.264 (Intel QSV)", "qsv_h264", "H.264 (Intel Media SDK)", HB_VCODEC_QSV_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H264_QSV, },
267 { { "H.264 (AMD VCE)", "vce_h264", "H.264 (AMD VCE)", HB_VCODEC_FFMPEG_VCE_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H264_VCE, },
268 { { "H.264 (NVEnc)", "nvenc_h264", "H.264 (NVEnc)", HB_VCODEC_FFMPEG_NVENC_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H264_NVENC, },
269 { { "H.264 (MediaFoundation)","mf_h264", "H.264 (MediaFoundation)", HB_VCODEC_FFMPEG_MF_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H264_MF, },
270 { { "H.264 (VideoToolbox)","vt_h264", "H.264 (libavcodec)", HB_VCODEC_FFMPEG_VT_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H264_VT, },
271 { { "H.265 (x265)", "x265", "H.265 (libx265)", HB_VCODEC_X265_8BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_X265, },
272 { { "H.265 10-bit (x265)", "x265_10bit", "H.265 10-bit (libx265)", HB_VCODEC_X265_10BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_X265, },
273 { { "H.265 12-bit (x265)", "x265_12bit", "H.265 12-bit (libx265)", HB_VCODEC_X265_12BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_X265, },
274 { { "H.265 16-bit (x265)", "x265_16bit", "H.265 16-bit (libx265)", HB_VCODEC_X265_16BIT, HB_MUX_AV_MP4|HB_MUX_AV_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_X265, },
275 { { "H.265 (Intel QSV)", "qsv_h265", "H.265 (Intel Media SDK)", HB_VCODEC_QSV_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_QSV, },
276 { { "H.265 10-bit (Intel QSV)","qsv_h265_10bit", "H.265 10-bit (Intel Media SDK)", HB_VCODEC_QSV_H265_10BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_QSV, },
277 { { "H.265 (AMD VCE)", "vce_h265", "H.265 (AMD VCE)", HB_VCODEC_FFMPEG_VCE_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_VCE, },
278 { { "H.265 (NVEnc)", "nvenc_h265", "H.265 (NVEnc)", HB_VCODEC_FFMPEG_NVENC_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_NVENC, },
279 { { "H.265 (MediaFoundation)","mf_h265", "H.265 (MediaFoundation)", HB_VCODEC_FFMPEG_MF_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_MF, },
280 { { "H.265 (VideoToolbox)","vt_h265", "H.265 (libavcodec)", HB_VCODEC_FFMPEG_VT_H265, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_VT, },
281 { { "H.265 10-bit (VideoToolbox)","vt_h265_10bit", "H.265 (libavcodec)", HB_VCODEC_FFMPEG_VT_H265_10BIT, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_H265_VT, },
282 { { "MPEG-4", "mpeg4", "MPEG-4 (libavcodec)", HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_MPEG4, },
283 { { "MPEG-2", "mpeg2", "MPEG-2 (libavcodec)", HB_VCODEC_FFMPEG_MPEG2, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_MPEG2, },
284 { { "VP8", "VP8", "VP8 (libvpx)", HB_VCODEC_FFMPEG_VP8, HB_MUX_MASK_WEBM|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_VP8, },
285 { { "VP9", "VP9", "VP9 (libvpx)", HB_VCODEC_FFMPEG_VP9, HB_MUX_MASK_WEBM|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_VP9, },
286 { { "Theora", "theora", "Theora (libtheora)", HB_VCODEC_THEORA, HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_VCODEC_THEORA, },
287 };
288 int hb_video_encoders_count = sizeof(hb_video_encoders) / sizeof(hb_video_encoders[0]);
hb_video_encoder_is_enabled(int encoder,int disable_hardware)289 static int hb_video_encoder_is_enabled(int encoder, int disable_hardware)
290 {
291 // Hardware Encoders
292 if (!disable_hardware)
293 {
294 #if HB_PROJECT_FEATURE_QSV
295 if (encoder & HB_VCODEC_QSV_MASK)
296 {
297 return hb_qsv_video_encoder_is_enabled(hb_qsv_get_adapter_index(), encoder);
298 }
299 #endif
300
301 switch (encoder){
302 #if HB_PROJECT_FEATURE_VCE
303 case HB_VCODEC_FFMPEG_VCE_H264:
304 return hb_vce_h264_available();
305 case HB_VCODEC_FFMPEG_VCE_H265:
306 return hb_vce_h265_available();
307 #endif
308
309 #if HB_PROJECT_FEATURE_NVENC
310 case HB_VCODEC_FFMPEG_NVENC_H264:
311 return hb_nvenc_h264_available();
312 case HB_VCODEC_FFMPEG_NVENC_H265:
313 return hb_nvenc_h265_available();
314 #endif
315
316 #ifdef __APPLE__
317 case HB_VCODEC_FFMPEG_VT_H264:
318 return hb_vt_h264_is_available();
319 case HB_VCODEC_FFMPEG_VT_H265:
320 return hb_vt_h265_is_available();
321 case HB_VCODEC_FFMPEG_VT_H265_10BIT:
322 return hb_vt_h265_10bit_is_available();
323 #endif
324
325 #if HB_PROJECT_FEATURE_MF
326 // TODO: Try to instantiate a throwaway encoder to see if a suitable MediaFoundation encoder can be found?
327 // Alt, implement logic similar to ffmpeg's encoder selection, to see if one would be found.
328 case HB_VCODEC_FFMPEG_MF_H264:
329 return 1;
330 case HB_VCODEC_FFMPEG_MF_H265:
331 return 1;
332 #endif
333 }
334 }
335
336 // Software Encoders
337 switch (encoder)
338 {
339 // the following encoders are always enabled
340 case HB_VCODEC_THEORA:
341 case HB_VCODEC_FFMPEG_MPEG4:
342 case HB_VCODEC_FFMPEG_MPEG2:
343 case HB_VCODEC_FFMPEG_VP8:
344 case HB_VCODEC_FFMPEG_VP9:
345 return 1;
346
347 #if HB_PROJECT_FEATURE_X265
348 case HB_VCODEC_X265_8BIT:
349 case HB_VCODEC_X265_10BIT:
350 case HB_VCODEC_X265_12BIT:
351 case HB_VCODEC_X265_16BIT:
352 {
353 const x265_api *api;
354 api = x265_api_query(hb_video_encoder_get_depth(encoder), X265_BUILD, NULL);
355 return (api != NULL);
356 };
357 #endif
358
359 case HB_VCODEC_X264_8BIT:
360 case HB_VCODEC_X264_10BIT:
361 {
362 const x264_api_t *api;
363 api = hb_x264_api_get(hb_video_encoder_get_depth(encoder));
364 return (api != NULL);
365 }
366
367 default:
368 return 0;
369 }
370 }
371
372 hb_encoder_t *hb_audio_encoders_first_item = NULL;
373 hb_encoder_t *hb_audio_encoders_last_item = NULL;
374 hb_encoder_internal_t hb_audio_encoders[] =
375 {
376 // legacy encoders, back to HB 0.9.4 whenever possible (disabled)
377 { { "", "dts", NULL, HB_ACODEC_DCA_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_ACODEC_DTS_PASS, },
378 { { "AAC (faac)", "faac", NULL, 0, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_ACODEC_AAC, },
379 { { "AAC (ffmpeg)", "ffaac", NULL, HB_ACODEC_FFAAC, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_ACODEC_AAC, },
380 { { "AC3 (ffmpeg)", "ffac3", NULL, HB_ACODEC_AC3, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_ACODEC_AC3, },
381 { { "MP3 (lame)", "lame", NULL, HB_ACODEC_LAME, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_ACODEC_MP3, },
382 { { "Vorbis (vorbis)", "libvorbis", NULL, HB_ACODEC_VORBIS, HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_ACODEC_VORBIS, },
383 { { "FLAC (ffmpeg)", "ffflac", NULL, HB_ACODEC_FFFLAC, HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_ACODEC_FLAC, },
384 { { "FLAC (24-bit)", "ffflac24", NULL, HB_ACODEC_FFFLAC24, HB_MUX_MASK_MKV, }, NULL, 1, 0, HB_GID_ACODEC_FLAC, },
385 // generic names
386 { { "AAC", "aac", NULL, 0, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 0, HB_GID_ACODEC_AAC, },
387 { { "HE-AAC", "haac", NULL, 0, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 0, HB_GID_ACODEC_AAC_HE, },
388 // actual encoders
389 { { "None", "none", "None", HB_ACODEC_NONE, 0, }, NULL, 0, 1, HB_GID_NONE, },
390 { { "AAC (CoreAudio)", "ca_aac", "AAC (Apple AudioToolbox)", HB_ACODEC_CA_AAC, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AAC, },
391 { { "HE-AAC (CoreAudio)", "ca_haac", "HE-AAC (Apple AudioToolbox)", HB_ACODEC_CA_HAAC, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AAC_HE, },
392 { { "AAC (FDK)", "fdk_aac", "AAC (libfdk_aac)", HB_ACODEC_FDK_AAC, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AAC, },
393 { { "HE-AAC (FDK)", "fdk_haac", "HE-AAC (libfdk_aac)", HB_ACODEC_FDK_HAAC, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AAC_HE, },
394 { { "AAC (avcodec)", "av_aac", "AAC (libavcodec)", HB_ACODEC_FFAAC, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AAC, },
395 { { "AAC Passthru", "copy:aac", "AAC Passthru", HB_ACODEC_AAC_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AAC_PASS, },
396 { { "AC3", "ac3", "AC3 (libavcodec)", HB_ACODEC_AC3, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AC3, },
397 { { "AC3 Passthru", "copy:ac3", "AC3 Passthru", HB_ACODEC_AC3_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AC3_PASS, },
398 { { "E-AC3", "eac3", "E-AC3 (libavcodec)", HB_ACODEC_FFEAC3, HB_MUX_MASK_MP4|HB_MUX_AV_MKV, }, NULL, 0, 1, HB_GID_ACODEC_EAC3, },
399 { { "E-AC3 Passthru", "copy:eac3", "E-AC3 Passthru", HB_ACODEC_EAC3_PASS, HB_MUX_MASK_MP4|HB_MUX_AV_MKV, }, NULL, 0, 1, HB_GID_ACODEC_EAC3_PASS, },
400 { { "TrueHD Passthru", "copy:truehd","TrueHD Passthru", HB_ACODEC_TRUEHD_PASS, HB_MUX_AV_MKV, }, NULL, 0, 1, HB_GID_ACODEC_TRUEHD_PASS,},
401 { { "DTS Passthru", "copy:dts", "DTS Passthru", HB_ACODEC_DCA_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_DTS_PASS, },
402 { { "DTS-HD Passthru", "copy:dtshd", "DTS-HD Passthru", HB_ACODEC_DCA_HD_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_DTSHD_PASS, },
403 { { "MP2 Passthru", "copy:mp2", "MP2 Passthru", HB_ACODEC_MP2_PASS, HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_MP2_PASS, },
404 { { "MP3", "mp3", "MP3 (libmp3lame)", HB_ACODEC_LAME, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_MP3, },
405 { { "MP3 Passthru", "copy:mp3", "MP3 Passthru", HB_ACODEC_MP3_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_MP3_PASS, },
406 { { "Vorbis", "vorbis", "Vorbis (libvorbis)", HB_ACODEC_VORBIS, HB_MUX_MASK_WEBM|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_VORBIS, },
407 { { "FLAC 16-bit", "flac16", "FLAC 16-bit (libavcodec)", HB_ACODEC_FFFLAC, HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_FLAC, },
408 { { "FLAC 24-bit", "flac24", "FLAC 24-bit (libavcodec)", HB_ACODEC_FFFLAC24, HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_FLAC, },
409 { { "FLAC Passthru", "copy:flac", "FLAC Passthru", HB_ACODEC_FLAC_PASS, HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_FLAC_PASS, },
410 { { "Opus", "opus", "Opus (libopus)", HB_ACODEC_OPUS, HB_MUX_MASK_WEBM|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_OPUS, },
411 { { "Auto Passthru", "copy", "Auto Passthru", HB_ACODEC_AUTO_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, 1, HB_GID_ACODEC_AUTO_PASS, },
412 };
413 int hb_audio_encoders_count = sizeof(hb_audio_encoders) / sizeof(hb_audio_encoders[0]);
hb_audio_encoder_is_enabled(int encoder)414 static int hb_audio_encoder_is_enabled(int encoder)
415 {
416 if (encoder & HB_ACODEC_PASS_FLAG)
417 {
418 // Passthru encoders are always enabled
419 return 1;
420 }
421 switch (encoder)
422 {
423 #ifdef __APPLE__
424 case HB_ACODEC_CA_AAC:
425 case HB_ACODEC_CA_HAAC:
426 return 1;
427 #endif
428
429 #if HB_PROJECT_FEATURE_FFMPEG_AAC
430 case HB_ACODEC_FFAAC:
431 return avcodec_find_encoder_by_name("aac") != NULL;
432 #endif
433
434 case HB_ACODEC_FDK_AAC:
435 case HB_ACODEC_FDK_HAAC:
436 return avcodec_find_encoder_by_name("libfdk_aac") != NULL;
437
438 case HB_ACODEC_AC3:
439 return avcodec_find_encoder(AV_CODEC_ID_AC3) != NULL;
440
441 case HB_ACODEC_FFEAC3:
442 return avcodec_find_encoder(AV_CODEC_ID_EAC3) != NULL;
443
444 case HB_ACODEC_FFFLAC:
445 case HB_ACODEC_FFFLAC24:
446 return avcodec_find_encoder(AV_CODEC_ID_FLAC) != NULL;
447
448 case HB_ACODEC_OPUS:
449 return avcodec_find_encoder(AV_CODEC_ID_OPUS) != NULL;
450
451 // the following encoders are always enabled
452 case HB_ACODEC_LAME:
453 case HB_ACODEC_VORBIS:
454 case HB_ACODEC_NONE:
455 return 1;
456
457 default:
458 return 0;
459 }
460 }
461
462 typedef struct
463 {
464 hb_container_t item;
465 hb_container_t *next;
466 int enabled;
467 int gid;
468 } hb_container_internal_t;
469 hb_container_t *hb_containers_first_item = NULL;
470 hb_container_t *hb_containers_last_item = NULL;
471 hb_container_internal_t hb_containers[] =
472 {
473 // legacy muxers, back to HB 0.9.4 whenever possible (disabled)
474 { { "M4V file", "m4v", NULL, "m4v", 0, }, NULL, 0, HB_GID_MUX_MP4, },
475 { { "MP4 file", "mp4", NULL, "mp4", 0, }, NULL, 0, HB_GID_MUX_MP4, },
476 { { "MKV file", "mkv", NULL, "mkv", 0, }, NULL, 0, HB_GID_MUX_MKV, },
477 // actual muxers
478 { { "MPEG-4 (avformat)", "av_mp4", "MPEG-4 (libavformat)", "mp4", HB_MUX_AV_MP4, }, NULL, 1, HB_GID_MUX_MP4, },
479 { { "MPEG-4 (mp4v2)", "mp4v2", "MPEG-4 (libmp4v2)", "mp4", HB_MUX_MP4V2, }, NULL, 1, HB_GID_MUX_MP4, },
480 { { "Matroska (avformat)", "av_mkv", "Matroska (libavformat)", "mkv", HB_MUX_AV_MKV, }, NULL, 1, HB_GID_MUX_MKV, },
481 { { "Matroska (libmkv)", "libmkv", "Matroska (libmkv)", "mkv", HB_MUX_LIBMKV, }, NULL, 1, HB_GID_MUX_MKV, },
482 { { "WebM (avformat)", "av_webm", "WebM (libavformat)", "webm", HB_MUX_AV_WEBM, }, NULL, 1, HB_GID_MUX_WEBM, },
483 };
484 int hb_containers_count = sizeof(hb_containers) / sizeof(hb_containers[0]);
hb_container_is_enabled(int format)485 static int hb_container_is_enabled(int format)
486 {
487 switch (format)
488 {
489 case HB_MUX_AV_MP4:
490 case HB_MUX_AV_MKV:
491 case HB_MUX_AV_WEBM:
492 return 1;
493
494 default:
495 return 0;
496 }
497 }
498
hb_common_global_init(int disable_hardware)499 void hb_common_global_init(int disable_hardware)
500 {
501 static int common_init_done = 0;
502 if (common_init_done)
503 return;
504
505 int i, j;
506
507 // video framerates
508 for (i = 0; i < hb_video_rates_count; i++)
509 {
510 if (hb_video_rates[i].enabled)
511 {
512 if (hb_video_rates_first_item == NULL)
513 {
514 hb_video_rates_first_item = &hb_video_rates[i].item;
515 }
516 else
517 {
518 ((hb_rate_internal_t*)hb_video_rates_last_item)->next =
519 &hb_video_rates[i].item;
520 }
521 hb_video_rates_last_item = &hb_video_rates[i].item;
522 }
523 }
524 // fallbacks are static for now (no setup required)
525
526 // audio samplerates
527 for (i = 0; i < hb_audio_rates_count; i++)
528 {
529 if (hb_audio_rates[i].enabled)
530 {
531 if (hb_audio_rates_first_item == NULL)
532 {
533 hb_audio_rates_first_item = &hb_audio_rates[i].item;
534 }
535 else
536 {
537 ((hb_rate_internal_t*)hb_audio_rates_last_item)->next =
538 &hb_audio_rates[i].item;
539 }
540 hb_audio_rates_last_item = &hb_audio_rates[i].item;
541 }
542 }
543 // fallbacks are static for now (no setup required)
544
545 // audio bitrates
546 for (i = 0; i < hb_audio_bitrates_count; i++)
547 {
548 if (hb_audio_bitrates[i].enabled)
549 {
550 if (hb_audio_bitrates_first_item == NULL)
551 {
552 hb_audio_bitrates_first_item = &hb_audio_bitrates[i].item;
553 }
554 else
555 {
556 ((hb_rate_internal_t*)hb_audio_bitrates_last_item)->next =
557 &hb_audio_bitrates[i].item;
558 }
559 hb_audio_bitrates_last_item = &hb_audio_bitrates[i].item;
560 }
561 }
562 // fallbacks are static for now (no setup required)
563
564 // audio dithers
565 for (i = 0; i < hb_audio_dithers_count; i++)
566 {
567 if (hb_audio_dithers[i].enabled)
568 {
569 if (hb_audio_dithers_first_item == NULL)
570 {
571 hb_audio_dithers_first_item = &hb_audio_dithers[i].item;
572 }
573 else
574 {
575 ((hb_dither_internal_t*)hb_audio_dithers_last_item)->next =
576 &hb_audio_dithers[i].item;
577 }
578 hb_audio_dithers_last_item = &hb_audio_dithers[i].item;
579 }
580 }
581 // fallbacks are static for now (no setup required)
582
583 // audio mixdowns
584 for (i = 0; i < hb_audio_mixdowns_count; i++)
585 {
586 if (hb_audio_mixdowns[i].enabled)
587 {
588 if (hb_audio_mixdowns_first_item == NULL)
589 {
590 hb_audio_mixdowns_first_item = &hb_audio_mixdowns[i].item;
591 }
592 else
593 {
594 ((hb_mixdown_internal_t*)hb_audio_mixdowns_last_item)->next =
595 &hb_audio_mixdowns[i].item;
596 }
597 hb_audio_mixdowns_last_item = &hb_audio_mixdowns[i].item;
598 }
599 }
600 // fallbacks are static for now (no setup required)
601
602 // video encoders
603 for (i = 0; i < hb_video_encoders_count; i++)
604 {
605 if (hb_video_encoders[i].enabled)
606 {
607 // we still need to check
608 hb_video_encoders[i].enabled =
609 hb_video_encoder_is_enabled(hb_video_encoders[i].item.codec, disable_hardware);
610 }
611 if (hb_video_encoders[i].enabled)
612 {
613 if (hb_video_encoders_first_item == NULL)
614 {
615 hb_video_encoders_first_item = &hb_video_encoders[i].item;
616 }
617 else
618 {
619 ((hb_encoder_internal_t*)hb_video_encoders_last_item)->next =
620 &hb_video_encoders[i].item;
621 }
622 hb_video_encoders_last_item = &hb_video_encoders[i].item;
623 }
624 }
625 // setup fallbacks
626 for (i = 0; i < hb_video_encoders_count; i++)
627 {
628 if (!hb_video_encoders[i].enabled)
629 {
630 if ((hb_video_encoders[i].item.codec & HB_VCODEC_MASK) &&
631 (hb_video_encoder_is_enabled(hb_video_encoders[i].item.codec, disable_hardware)))
632 {
633 // we have a specific fallback and it's enabled
634 continue;
635 }
636 for (j = 0; j < hb_video_encoders_count; j++)
637 {
638 if (hb_video_encoders[j].enabled &&
639 hb_video_encoders[j].gid == hb_video_encoders[i].gid)
640 {
641 hb_video_encoders[i].item.codec = hb_video_encoders[j].item.codec;
642 break;
643 }
644 }
645 }
646 }
647
648 // audio encoders
649 for (i = 0; i < hb_audio_encoders_count; i++)
650 {
651 if (hb_audio_encoders[i].enabled)
652 {
653 // we still need to check
654 hb_audio_encoders[i].enabled =
655 hb_audio_encoder_is_enabled(hb_audio_encoders[i].item.codec);
656 }
657 if (hb_audio_encoders[i].enabled)
658 {
659 if (hb_audio_encoders_first_item == NULL)
660 {
661 hb_audio_encoders_first_item = &hb_audio_encoders[i].item;
662 }
663 else
664 {
665 ((hb_encoder_internal_t*)hb_audio_encoders_last_item)->next =
666 &hb_audio_encoders[i].item;
667 }
668 hb_audio_encoders_last_item = &hb_audio_encoders[i].item;
669 }
670 }
671 // setup fallbacks
672 for (i = 0; i < hb_audio_encoders_count; i++)
673 {
674 if (!hb_audio_encoders[i].enabled)
675 {
676 if ((hb_audio_encoders[i].item.codec & HB_ACODEC_MASK) &&
677 (hb_audio_encoder_is_enabled(hb_audio_encoders[i].item.codec)))
678 {
679 // we have a specific fallback and it's enabled
680 continue;
681 }
682 for (j = 0; j < hb_audio_encoders_count; j++)
683 {
684 if (hb_audio_encoders[j].enabled &&
685 hb_audio_encoders[j].gid == hb_audio_encoders[i].gid)
686 {
687 hb_audio_encoders[i].item.codec = hb_audio_encoders[j].item.codec;
688 break;
689 }
690 }
691 if (hb_audio_encoders[i].gid == HB_GID_ACODEC_AAC_HE)
692 {
693 // try to find an AAC fallback if no HE-AAC encoder is available
694 for (j = 0; j < hb_audio_encoders_count; j++)
695 {
696 if (hb_audio_encoders[j].enabled &&
697 hb_audio_encoders[j].gid == HB_GID_ACODEC_AAC)
698 {
699 hb_audio_encoders[i].item.codec = hb_audio_encoders[j].item.codec;
700 break;
701 }
702 }
703 }
704 }
705 }
706
707 // video containers
708 for (i = 0; i < hb_containers_count; i++)
709 {
710 if (hb_containers[i].enabled)
711 {
712 // we still need to check
713 hb_containers[i].enabled =
714 hb_container_is_enabled(hb_containers[i].item.format);
715 }
716 if (hb_containers[i].enabled)
717 {
718 if (hb_containers_first_item == NULL)
719 {
720 hb_containers_first_item = &hb_containers[i].item;
721 }
722 else
723 {
724 ((hb_container_internal_t*)hb_containers_last_item)->next =
725 &hb_containers[i].item;
726 }
727 hb_containers_last_item = &hb_containers[i].item;
728 }
729 }
730 // setup fallbacks
731 for (i = 0; i < hb_containers_count; i++)
732 {
733 if (!hb_containers[i].enabled)
734 {
735 if ((hb_containers[i].item.format & HB_MUX_MASK) &&
736 (hb_container_is_enabled(hb_containers[i].item.format)))
737 {
738 // we have a specific fallback and it's enabled
739 continue;
740 }
741 for (j = 0; j < hb_containers_count; j++)
742 {
743 if (hb_containers[j].enabled &&
744 hb_containers[j].gid == hb_containers[i].gid)
745 {
746 hb_containers[i].item.format = hb_containers[j].item.format;
747 break;
748 }
749 }
750 }
751 }
752
753 // we're done, yay!
754 common_init_done = 1;
755 }
756
hb_video_framerate_get_from_name(const char * name)757 int hb_video_framerate_get_from_name(const char *name)
758 {
759 if (name == NULL || *name == '\0')
760 goto fail;
761
762 int i;
763 for (i = 0; i < hb_video_rates_count; i++)
764 {
765 if (!strcasecmp(hb_video_rates[i].item.name, name))
766 {
767 return hb_video_rates[i].item.rate;
768 }
769 }
770
771 fail:
772 return -1;
773 }
774
hb_video_framerate_get_name(int framerate)775 const char* hb_video_framerate_get_name(int framerate)
776 {
777 if (framerate > hb_video_rates_first_item->rate ||
778 framerate < hb_video_rates_last_item ->rate)
779 goto fail;
780
781 const hb_rate_t *video_framerate = NULL;
782 while ((video_framerate = hb_video_framerate_get_next(video_framerate)) != NULL)
783 {
784 if (video_framerate->rate == framerate)
785 {
786 return video_framerate->name;
787 }
788 }
789
790 fail:
791 return NULL;
792 }
793
hb_video_framerate_sanitize_name(const char * name)794 const char* hb_video_framerate_sanitize_name(const char *name)
795 {
796 return hb_video_framerate_get_name(hb_video_framerate_get_from_name(name));
797 }
798
hb_video_framerate_get_limits(int * low,int * high,int * clock)799 void hb_video_framerate_get_limits(int *low, int *high, int *clock)
800 {
801 *low = hb_video_rate_min;
802 *high = hb_video_rate_max;
803 *clock = hb_video_rate_clock;
804 }
805
hb_video_framerate_get_next(const hb_rate_t * last)806 const hb_rate_t* hb_video_framerate_get_next(const hb_rate_t *last)
807 {
808 if (last == NULL)
809 {
810 return hb_video_rates_first_item;
811 }
812 return ((hb_rate_internal_t*)last)->next;
813 }
814
hb_video_framerate_get_close(hb_rational_t * framerate,double thresh)815 int hb_video_framerate_get_close(hb_rational_t *framerate, double thresh)
816 {
817 double fps_in;
818 const hb_rate_t * rate = NULL;
819 int result = -1;
820 double closest = thresh;
821
822 fps_in = (double)framerate->num / framerate->den;
823 while ((rate = hb_video_framerate_get_next(rate)) != NULL)
824 {
825 double fps = (double)hb_video_rate_clock / rate->rate;
826 if (ABS(fps - fps_in) < closest)
827 {
828 result = rate->rate;
829 closest = ABS(fps - fps_in);
830 }
831 }
832 return result;
833 }
834
hb_audio_samplerate_is_supported(int samplerate,uint32_t codec)835 int hb_audio_samplerate_is_supported(int samplerate, uint32_t codec)
836 {
837 switch (codec)
838 {
839 case HB_ACODEC_AC3:
840 case HB_ACODEC_FFEAC3:
841 case HB_ACODEC_CA_HAAC:
842 // ca_haac can't do samplerates < 32 kHz
843 // libav's E-AC-3 encoder can't do samplerates < 32 kHz
844 // AC-3 < 32 kHz suffers from poor hardware compatibility
845 if (samplerate < 32000)
846 return 0;
847 else
848 return 1;
849 case HB_ACODEC_FDK_HAAC:
850 // fdk_haac can't do samplerates < 16 kHz
851 if (samplerate < 16000)
852 return 0;
853 else
854 return 1;
855 case HB_ACODEC_OPUS:
856 switch (samplerate)
857 {
858 // Opus only supports samplerates 8kHz, 12kHz, 16kHz,
859 // 24kHz, 48kHz
860 case 8000:
861 case 12000:
862 case 16000:
863 case 24000:
864 case 48000:
865 return 1;
866 default:
867 return 0;
868 }
869 default:
870 return 1;
871 }
872 }
873
hb_audio_samplerate_get_sr_shift(int samplerate)874 int hb_audio_samplerate_get_sr_shift(int samplerate)
875 {
876 /* sr_shift: 0 -> 48000, 44100, 32000 Hz
877 * 1 -> 24000, 22050, 16000 Hz
878 * 2 -> 12000, 11025, 8000 Hz
879 *
880 * also, since samplerates are sanitized downwards:
881 *
882 * (samplerate < 32000) implies (samplerate <= 24000)
883 */
884 return ((samplerate < 16000) ? 2 : (samplerate < 32000) ? 1 : 0);
885 }
886
hb_audio_samplerate_get_from_name(const char * name)887 int hb_audio_samplerate_get_from_name(const char *name)
888 {
889 if (name == NULL || *name == '\0')
890 goto fail;
891
892 int i;
893 for (i = 0; i < hb_audio_rates_count; i++)
894 {
895 if (!strcasecmp(hb_audio_rates[i].item.name, name))
896 {
897 return hb_audio_rates[i].item.rate;
898 }
899 }
900
901 // maybe the samplerate was specified in Hz
902 i = atoi(name);
903 if (i >= hb_audio_rates_first_item->rate &&
904 i <= hb_audio_rates_last_item ->rate)
905 {
906 return hb_audio_samplerate_find_closest(i, HB_ACODEC_INVALID);
907 }
908
909 fail:
910 return -1;
911 }
912
hb_audio_samplerate_get_name(int samplerate)913 const char* hb_audio_samplerate_get_name(int samplerate)
914 {
915 if (samplerate < hb_audio_rates_first_item->rate ||
916 samplerate > hb_audio_rates_last_item ->rate)
917 goto fail;
918
919 const hb_rate_t *audio_samplerate = NULL;
920 while ((audio_samplerate = hb_audio_samplerate_get_next(audio_samplerate)) != NULL)
921 {
922 if (audio_samplerate->rate == samplerate)
923 {
924 return audio_samplerate->name;
925 }
926 }
927
928 fail:
929 return NULL;
930 }
931
hb_audio_samplerate_get_next(const hb_rate_t * last)932 const hb_rate_t* hb_audio_samplerate_get_next(const hb_rate_t *last)
933 {
934 if (last == NULL)
935 {
936 return hb_audio_rates_first_item;
937 }
938 return ((hb_rate_internal_t*)last)->next;
939 }
940
hb_audio_samplerate_get_next_for_codec(const hb_rate_t * last,uint32_t codec)941 const hb_rate_t* hb_audio_samplerate_get_next_for_codec(const hb_rate_t *last,
942 uint32_t codec)
943 {
944 while ((last = hb_audio_samplerate_get_next(last)) != NULL)
945 if (hb_audio_samplerate_is_supported(last->rate, codec))
946 return last;
947
948 // None found or end of list
949 return NULL;
950 }
951
hb_audio_samplerate_find_closest(int samplerate,uint32_t codec)952 int hb_audio_samplerate_find_closest(int samplerate, uint32_t codec)
953 {
954 const hb_rate_t * rate, * prev, * next;
955
956 rate = prev = next = hb_audio_samplerate_get_next_for_codec(NULL, codec);
957
958 if (rate == NULL)
959 {
960 // This codec doesn't support any samplerate
961 return 0;
962 }
963
964 while (rate != NULL && next->rate < samplerate)
965 {
966 rate = hb_audio_samplerate_get_next_for_codec(rate, codec);
967 if (rate != NULL)
968 {
969 prev = next;
970 next = rate;
971 }
972 }
973
974 int delta_prev = samplerate - prev->rate;
975 int delta_next = next->rate - samplerate;
976 if (delta_prev <= delta_next)
977 {
978 return prev->rate;
979 }
980 else
981 {
982 return next->rate;
983 }
984 }
985
986 // Given an input bitrate, find closest match in the set of allowed bitrates
hb_audio_bitrate_find_closest(int bitrate)987 static int hb_audio_bitrate_find_closest(int bitrate)
988 {
989 // Check if bitrate mode was disabled
990 if (bitrate <= 0)
991 return bitrate;
992
993 int closest_bitrate = hb_audio_bitrates_first_item->rate;
994 const hb_rate_t *audio_bitrate = NULL;
995 while ((audio_bitrate = hb_audio_bitrate_get_next(audio_bitrate)) != NULL)
996 {
997 if (bitrate == audio_bitrate->rate)
998 {
999 // valid bitrate
1000 closest_bitrate = audio_bitrate->rate;
1001 break;
1002 }
1003 if (bitrate > audio_bitrate->rate)
1004 {
1005 // bitrates are sanitized downwards
1006 closest_bitrate = audio_bitrate->rate;
1007 }
1008 }
1009 return closest_bitrate;
1010 }
1011
1012 // Given an input bitrate, sanitize it.
1013 // Check low and high limits and make sure it is in the set of allowed bitrates.
hb_audio_bitrate_get_best(uint32_t codec,int bitrate,int samplerate,int mixdown)1014 int hb_audio_bitrate_get_best(uint32_t codec, int bitrate, int samplerate,
1015 int mixdown)
1016 {
1017 int low, high;
1018 hb_audio_bitrate_get_limits(codec, samplerate, mixdown, &low, &high);
1019 if (bitrate > high)
1020 bitrate = high;
1021 if (bitrate < low)
1022 bitrate = low;
1023 return hb_audio_bitrate_find_closest(bitrate);
1024 }
1025
1026 // Get the default bitrate for a given codec/samplerate/mixdown triplet.
hb_audio_bitrate_get_default(uint32_t codec,int samplerate,int mixdown)1027 int hb_audio_bitrate_get_default(uint32_t codec, int samplerate, int mixdown)
1028 {
1029 if ((codec & HB_ACODEC_PASS_FLAG) || !(codec & HB_ACODEC_MASK))
1030 goto fail;
1031
1032 int bitrate, nchannels, nlfe, sr_shift;
1033 /* full-bandwidth channels, sr_shift */
1034 nlfe = hb_mixdown_get_low_freq_channel_count(mixdown);
1035 nchannels = hb_mixdown_get_discrete_channel_count(mixdown) - nlfe;
1036 sr_shift = hb_audio_samplerate_get_sr_shift(samplerate);
1037
1038 switch (codec)
1039 {
1040 case HB_ACODEC_FFFLAC:
1041 case HB_ACODEC_FFFLAC24:
1042 goto fail;
1043
1044 // 96, 224, 640 Kbps
1045 case HB_ACODEC_AC3:
1046 bitrate = (nchannels * 128) - (32 * (nchannels < 5));
1047 break;
1048
1049 // Our E-AC-3 encoder is pretty similar to our AC-3 encoder but it does
1050 // allow for higher bitrates, should some users want a bit more quality
1051 // at the expense of compression efficiency - still, let's remain
1052 // compatible with passthru over S/PDIF by default: 384, 768, 1536 Kbps
1053 case HB_ACODEC_FFEAC3:
1054 bitrate = (nchannels * 384) - (128 * (nchannels - 2) * (nchannels > 2));
1055 break;
1056
1057 case HB_ACODEC_CA_HAAC:
1058 case HB_ACODEC_FDK_HAAC:
1059 bitrate = nchannels * 32;
1060 break;
1061
1062 case HB_ACODEC_OPUS:
1063 {
1064 int coupled = mixdown_get_opus_coupled_stream_count(mixdown);
1065 int uncoupled = nchannels + nlfe - 2 * coupled;
1066
1067 bitrate = coupled * 96 + uncoupled * 64;
1068 } break;
1069
1070 default:
1071 bitrate = nchannels * 80;
1072 break;
1073 }
1074 // sample_rate adjustment
1075 bitrate >>= sr_shift;
1076 return hb_audio_bitrate_get_best(codec, bitrate, samplerate, mixdown);
1077
1078 fail:
1079 return -1;
1080 }
1081
1082 /* Get the bitrate low and high limits for a codec/samplerate/mixdown triplet.
1083 *
1084 * Encoder 1.0 channel 2.0 channels 5.1 channels 6.1 channels 7.1 channels
1085 * --------------------------------------------------------------------------------------
1086 *
1087 * ffaac
1088 * -----
1089 * supported samplerates: 8 - 48 kHz
1090 * libavcodec/aacenc.c defines a maximum bitrate:
1091 * -> 6144 * samplerate / 1024 bps (per channel, incl. LFE).
1092 * But output bitrates don't go as high as the theoretical maximums:
1093 * 12 kHz 61 (72) 123 (144)
1094 * 24 kHz 121 (144) 242 (288)
1095 * 48 kHz 236 (288) 472 (576)
1096 * Also, ffaac isn't a great encoder, so you don't want to allow too low a bitrate.
1097 * Limits: minimum of 32 Kbps per channel
1098 * maximum of 192 Kbps per channel at 32 kHz, adjusted for sr_shift
1099 * maximum of 256 Kbps per channel at 44.1-48 kHz, adjusted for sr_shift
1100 *
1101 * vorbis
1102 * ------
1103 * supported samplerates: 8 - 48 kHz
1104 * lib/modes/setup_*.h provides a range of allowed bitrates for various configurations.
1105 * for each samplerate, the highest minimums and lowest maximums are:
1106 * 8 kHz Minimum 8 Kbps, maximum 32 Kbps (per channel, incl. LFE).
1107 * 12 kHz Minimum 14 Kbps, maximum 44 Kbps (per channel, incl. LFE).
1108 * 16 kHz Minimum 16 Kbps, maximum 86 Kbps (per channel, incl. LFE).
1109 * 24 kHz Minimum 22 Kbps, maximum 86 Kbps (per channel, incl. LFE).
1110 * 32 kHz Minimum 26 Kbps, maximum 190 Kbps (per channel, incl. LFE).
1111 * 48 kHz Minimum 28 Kbps, maximum 240 Kbps (per channel, incl. LFE).
1112 * Limits: minimum of 14/22/28 Kbps per channel (8-12, 16-24, 32-48 kHz)
1113 * maximum of 32/86/190/240 Kbps per channel (8-12, 16-24, 32, 44.1-48 kHz)
1114 *
1115 * lame
1116 * ----
1117 * supported samplerates: 8 - 48 kHz
1118 * lame_init_params() allows the following bitrates:
1119 * 12 kHz Minimum 8 Kbps, maximum 64 Kbps
1120 * 24 kHz Minimum 8 Kbps, maximum 160 Kbps
1121 * 48 kHz Minimum 32 Kbps, maximum 320 Kbps
1122 * Limits: minimum of 8/8/32 Kbps (8-12, 16-24, 32-48 kHz)
1123 * maximum of 64/160/320 Kbps (8-12, 16-24, 32-48 kHz)
1124 *
1125 * ffac3
1126 * -----
1127 * supported samplerates: 32 - 48 kHz (< 32 kHz disabled for compatibility reasons)
1128 * Dolby's encoder has a min. of 224 Kbps for 5 full-bandwidth channels (5.0, 5.1)
1129 * The maximum AC3 bitrate is 640 Kbps
1130 * Limits: minimum of 224/5 Kbps per full-bandwidth channel, maximum of 640 Kbps
1131 *
1132 * ffeac3
1133 * ------
1134 * supported samplerates: 32 - 48 kHz (< 32 kHz not supported by libav encoder)
1135 * Dolby's encoder has a min. of 224 Kbps for 5 full-bandwidth channels (5.0, 5.1)
1136 * The maximum bitrate is 128 bits per sample per second
1137 * Limits: minimum of 224/5 Kbps per full-bandwidth channel
1138 * maximum of 128/1000 * samplerate Kbps
1139 *
1140 * ca_aac
1141 * ------
1142 * supported samplerates: 8 - 48 kHz
1143 * Core Audio API provides a range of allowed bitrates:
1144 * 8 kHz 8 - 24 16 - 48 40 - 112 48 - 144 56 - 160
1145 * 12 kHz 12 - 32 24 - 64 64 - 160 72 - 192 96 - 224
1146 * 16 kHz 12 - 48 24 - 96 64 - 224 72 - 288 96 - 320
1147 * 24 kHz 16 - 64 32 - 128 80 - 320 96 - 384 112 - 448
1148 * 32 kHz 24 - 96 48 - 192 128 - 448 144 - 576 192 - 640
1149 * 48 kHz 32 - 256 64 - 320 160 - 768 192 - 960 224 - 960
1150 * Limits:
1151 * 8 kHz -> minimum of 8 Kbps and maximum of 24 Kbps per full-bandwidth channel
1152 * 12 kHz -> minimum of 12 Kbps and maximum of 32 Kbps per full-bandwidth channel
1153 * 16 kHz -> minimum of 12 Kbps and maximum of 48 Kbps per full-bandwidth channel
1154 * 24 kHz -> minimum of 16 Kbps and maximum of 64 Kbps per full-bandwidth channel
1155 * 32 kHz -> minimum of 24 Kbps and maximum of 96 Kbps per full-bandwidth channel
1156 * 48 kHz -> minimum of 32 Kbps and maximum of 160 Kbps per full-bandwidth channel
1157 * 48 kHz -> maximum of +96 Kbps for Mono
1158 * Note: encCoreAudioInit() will sanitize any mistake made here.
1159 *
1160 * ca_haac
1161 * -------
1162 * supported samplerates: 32 - 48 kHz
1163 * Core Audio API provides a range of allowed bitrates:
1164 * 32 kHz 12 - 40 24 - 80 64 - 192 N/A 96 - 256
1165 * 48 kHz 16 - 40 32 - 80 80 - 192 N/A 112 - 256
1166 * Limits: minimum of 12 Kbps per full-bandwidth channel (<= 32 kHz)
1167 * minimum of 16 Kbps per full-bandwidth channel ( > 32 kHz)
1168 * maximum of 40 Kbps per full-bandwidth channel
1169 * Note: encCoreAudioInit() will sanitize any mistake made here.
1170 *
1171 * fdk_aac
1172 * -------
1173 * supported samplerates: 8 - 48 kHz
1174 * libfdk limits the bitrate to the following values:
1175 * 8 kHz 48 96 240
1176 * 12 kHz 72 144 360
1177 * 16 kHz 96 192 480
1178 * 24 kHz 144 288 720
1179 * 32 kHz 192 384 960
1180 * 48 kHz 288 576 1440
1181 * Limits: minimum of samplerate * 2/3 Kbps per full-bandwidth channel (see ca_aac)
1182 * maximum of samplerate * 6.0 Kbps per full-bandwidth channel
1183 *
1184 * fdk_haac
1185 * --------
1186 * supported samplerates: 16 - 48 kHz
1187 * libfdk limits the bitrate to the following values:
1188 * 16 kHz 8 - 48 16 - 96 45 - 199
1189 * 24 kHz 8 - 63 16 - 127 45 - 266
1190 * 32 kHz 8 - 63 16 - 127 45 - 266
1191 * 48 kHz 12 - 63 16 - 127 50 - 266
1192 * Limits: minimum of 12 Kbps per full-bandwidth channel (<= 32 kHz) (see ca_haac)
1193 * minimum of 16 Kbps per full-bandwidth channel ( > 32 kHz) (see ca_haac)
1194 * maximum of 48, 96 or 192 Kbps (1.0, 2.0, 5.1) (<= 16 kHz)
1195 * maximum of 64, 128 or 256 Kbps (1.0, 2.0, 5.1) ( > 16 kHz)
1196 */
hb_audio_bitrate_get_limits(uint32_t codec,int samplerate,int mixdown,int * low,int * high)1197 void hb_audio_bitrate_get_limits(uint32_t codec, int samplerate, int mixdown,
1198 int *low, int *high)
1199 {
1200 /*
1201 * samplerate == 0 means "auto" (same as source) and the UIs know the source
1202 * samplerate -- except where there isn't a source (audio defaults panel);
1203 * but we have enough info to return the global bitrate limits for this
1204 * mixdown, since the first/last samplerate are known to us and non-zero.
1205 */
1206 if (samplerate == 0)
1207 {
1208 int dummy;
1209 hb_audio_bitrate_get_limits(codec, hb_audio_rates_first_item->rate, mixdown, low, &dummy);
1210 hb_audio_bitrate_get_limits(codec, hb_audio_rates_last_item->rate, mixdown, &dummy, high);
1211 return;
1212 }
1213
1214 /* samplerate, sr_shift */
1215 int sr_shift;
1216 samplerate = hb_audio_samplerate_find_closest(samplerate, codec);
1217 sr_shift = hb_audio_samplerate_get_sr_shift(samplerate);
1218
1219 /* LFE, full-bandwidth channels */
1220 int lfe_count, nchannels;
1221 lfe_count = hb_mixdown_get_low_freq_channel_count(mixdown);
1222 nchannels = hb_mixdown_get_discrete_channel_count(mixdown) - lfe_count;
1223
1224 switch (codec)
1225 {
1226 // Bitrates don't apply to "lossless" audio
1227 case HB_ACODEC_FFFLAC:
1228 case HB_ACODEC_FFFLAC24:
1229 *low = *high = -1;
1230 return;
1231
1232 case HB_ACODEC_AC3:
1233 *low = 224 * nchannels / 5;
1234 *high = 640;
1235 break;
1236
1237 case HB_ACODEC_FFEAC3:
1238 *low = 224 * nchannels / 5;
1239 *high = 128 * samplerate / 1000;
1240 break;
1241
1242 case HB_ACODEC_CA_AAC:
1243 {
1244 switch (samplerate)
1245 {
1246 case 8000:
1247 *low = nchannels * 8;
1248 *high = nchannels * 24;
1249 break;
1250
1251 case 11025:
1252 case 12000:
1253 *low = nchannels * 12;
1254 *high = nchannels * 32;
1255 break;
1256
1257 case 16000:
1258 *low = nchannels * 12;
1259 *high = nchannels * 48;
1260 break;
1261
1262 case 22050:
1263 case 24000:
1264 *low = nchannels * 16;
1265 *high = nchannels * 64;
1266 break;
1267
1268 case 32000:
1269 *low = nchannels * 24;
1270 *high = nchannels * 96;
1271 break;
1272
1273 case 44100:
1274 case 48000:
1275 default:
1276 *low = nchannels * 32;
1277 *high = nchannels * (160 + (96 * (nchannels == 1)));
1278 break;
1279 } break;
1280 }
1281
1282 case HB_ACODEC_CA_HAAC:
1283 *low = nchannels * (12 + (4 * (samplerate >= 44100)));
1284 *high = nchannels * 40;
1285 break;
1286
1287 case HB_ACODEC_FDK_AAC:
1288 *low = nchannels * samplerate * 2 / 3000;
1289 *high = nchannels * samplerate * 6 / 1000;
1290 break;
1291
1292 case HB_ACODEC_FDK_HAAC:
1293 *low = (nchannels * (12 + (4 * (samplerate >= 44100))));
1294 *high = (nchannels - (nchannels > 2)) * (48 +
1295 (16 *
1296 (samplerate >= 22050)));
1297 break;
1298
1299 case HB_ACODEC_FFAAC:
1300 *low = ((nchannels + lfe_count) * 32);
1301 *high = ((nchannels + lfe_count) *
1302 ((192 + (64 * ((samplerate << sr_shift) >= 44100)))
1303 >> sr_shift));
1304 break;
1305
1306 case HB_ACODEC_LAME:
1307 *low = 8 + (24 * (sr_shift < 1));
1308 *high = 64 + (96 * (sr_shift < 2)) + (160 * (sr_shift < 1));
1309 break;
1310
1311 case HB_ACODEC_VORBIS:
1312 *low = (nchannels + lfe_count) * (14 +
1313 (8 * (sr_shift < 2)) +
1314 (6 * (sr_shift < 1)));
1315 *high = (nchannels + lfe_count) * (32 +
1316 ( 54 * (sr_shift < 2)) +
1317 (104 * (sr_shift < 1)) +
1318 ( 50 * (samplerate >= 44100)));
1319 break;
1320
1321 case HB_ACODEC_OPUS:
1322 *low = (nchannels + lfe_count) * 6;
1323 *high = (nchannels + lfe_count) * 256;
1324 break;
1325
1326 // Bitrates don't apply to passthrough audio, but may apply if we
1327 // fall back to an encoder when the source can't be passed through.
1328 default:
1329 *low = hb_audio_bitrates_first_item->rate;
1330 *high = hb_audio_bitrates_last_item ->rate;
1331 break;
1332 }
1333
1334 // sanitize max. bitrate
1335 if (*high < hb_audio_bitrates_first_item->rate)
1336 *high = hb_audio_bitrates_first_item->rate;
1337 if (*high > hb_audio_bitrates_last_item ->rate)
1338 *high = hb_audio_bitrates_last_item ->rate;
1339 }
1340
hb_audio_bitrate_get_next(const hb_rate_t * last)1341 const hb_rate_t* hb_audio_bitrate_get_next(const hb_rate_t *last)
1342 {
1343 if (last == NULL)
1344 {
1345 return hb_audio_bitrates_first_item;
1346 }
1347 return ((hb_rate_internal_t*)last)->next;
1348 }
1349
1350 // Get limits and hints for the UIs.
1351 //
1352 // granularity sets the minimum step increments that should be used
1353 // (it's ok to round up to some nice multiple if you like)
1354 //
1355 // direction says whether 'low' limit is highest or lowest
1356 // quality (direction 0 == lowest value is worst quality)
hb_video_quality_get_limits(uint32_t codec,float * low,float * high,float * granularity,int * direction)1357 void hb_video_quality_get_limits(uint32_t codec, float *low, float *high,
1358 float *granularity, int *direction)
1359 {
1360 #if HB_PROJECT_FEATURE_QSV
1361 if (codec & HB_VCODEC_QSV_MASK)
1362 {
1363 return hb_qsv_video_quality_get_limits(codec, low, high, granularity,
1364 direction);
1365 }
1366 #endif
1367
1368 switch (codec)
1369 {
1370 /*
1371 * H.264/H.265: *low
1372 * = 51 - (QP_MAX_SPEC)
1373 * = 51 - (51 + QP_BD_OFFSET)
1374 * = 0 - (QP_BD_OFFSET)
1375 * = 0 - (6*(BIT_DEPTH-8)) (libx264)
1376 * = 0 - (6*(X265_DEPTH-8)) (libx265)
1377 */
1378 case HB_VCODEC_X264_8BIT:
1379 case HB_VCODEC_X265_8BIT:
1380 case HB_VCODEC_FFMPEG_NVENC_H264:
1381 case HB_VCODEC_FFMPEG_NVENC_H265:
1382 *direction = 1;
1383 *granularity = 0.1;
1384 *low = 0.;
1385 *high = 51.;
1386 break;
1387 case HB_VCODEC_X264_10BIT:
1388 case HB_VCODEC_X265_10BIT:
1389 *direction = 1;
1390 *granularity = 0.1;
1391 *low = -12.;
1392 *high = 51.;
1393 break;
1394 case HB_VCODEC_X265_12BIT:
1395 *direction = 1;
1396 *granularity = 0.1;
1397 *low = -24.;
1398 *high = 51.;
1399 break;
1400 case HB_VCODEC_X265_16BIT:
1401 *direction = 1;
1402 *granularity = 0.1;
1403 *low = -48.;
1404 *high = 51.;
1405 break;
1406
1407 case HB_VCODEC_THEORA:
1408 *direction = 0;
1409 *granularity = 1.;
1410 *low = 0.;
1411 *high = 63.;
1412 break;
1413
1414 case HB_VCODEC_FFMPEG_VP8:
1415 case HB_VCODEC_FFMPEG_VP9:
1416 *direction = 1;
1417 *granularity = 1.;
1418 *low = 0.;
1419 *high = 63.;
1420 break;
1421
1422 case HB_VCODEC_FFMPEG_VT_H264:
1423 case HB_VCODEC_FFMPEG_VT_H265:
1424 case HB_VCODEC_FFMPEG_VT_H265_10BIT:
1425 *direction = 0;
1426 *granularity = 1.;
1427 *low = 0.;
1428 *high = 100.;
1429 break;
1430
1431 case HB_VCODEC_FFMPEG_MF_H264:
1432 case HB_VCODEC_FFMPEG_MF_H265:
1433 *direction = 0;
1434 *granularity = 1;
1435 *low = 0;
1436 *high = 100;
1437 break;
1438
1439 case HB_VCODEC_FFMPEG_MPEG2:
1440 case HB_VCODEC_FFMPEG_MPEG4:
1441 default:
1442 *direction = 1;
1443 *granularity = 1.;
1444 *low = 1.;
1445 *high = 31.;
1446 break;
1447 }
1448 }
1449
hb_video_quality_get_name(uint32_t codec)1450 const char* hb_video_quality_get_name(uint32_t codec)
1451 {
1452 #if HB_PROJECT_FEATURE_QSV
1453 if (codec & HB_VCODEC_QSV_MASK)
1454 {
1455 return hb_qsv_video_quality_get_name(codec);
1456 }
1457 #endif
1458
1459 switch (codec)
1460 {
1461 case HB_VCODEC_X264_8BIT:
1462 case HB_VCODEC_X264_10BIT:
1463 case HB_VCODEC_X265_8BIT:
1464 case HB_VCODEC_X265_10BIT:
1465 case HB_VCODEC_X265_12BIT:
1466 case HB_VCODEC_X265_16BIT:
1467 return "RF";
1468
1469 case HB_VCODEC_FFMPEG_VP8:
1470 case HB_VCODEC_FFMPEG_VP9:
1471 case HB_VCODEC_FFMPEG_NVENC_H264:
1472 case HB_VCODEC_FFMPEG_NVENC_H265:
1473 case HB_VCODEC_FFMPEG_VCE_H264:
1474 case HB_VCODEC_FFMPEG_VCE_H265:
1475 case HB_VCODEC_FFMPEG_VT_H264:
1476 case HB_VCODEC_FFMPEG_VT_H265:
1477 case HB_VCODEC_FFMPEG_VT_H265_10BIT:
1478 return "CQ";
1479
1480 case HB_VCODEC_FFMPEG_MF_H264:
1481 case HB_VCODEC_FFMPEG_MF_H265:
1482 return "Quality";
1483
1484 default:
1485 return "QP";
1486 }
1487 }
1488
hb_video_quality_is_supported(uint32_t codec)1489 int hb_video_quality_is_supported(uint32_t codec)
1490 {
1491 switch (codec)
1492 {
1493 #ifdef __APPLE__
1494 case HB_VCODEC_FFMPEG_VT_H264:
1495 return hb_vt_h264_is_constant_quality_available();
1496 case HB_VCODEC_FFMPEG_VT_H265:
1497 case HB_VCODEC_FFMPEG_VT_H265_10BIT:
1498 return hb_vt_h265_is_constant_quality_available();
1499 #endif
1500
1501 default:
1502 return 1;
1503 }
1504 }
1505
hb_video_encoder_is_supported(int encoder)1506 int hb_video_encoder_is_supported(int encoder)
1507 {
1508 const hb_encoder_t *video_encoder = NULL;
1509 while ((video_encoder = hb_video_encoder_get_next(video_encoder)) != NULL)
1510 {
1511 if (video_encoder->codec == encoder)
1512 {
1513 return 1;
1514 }
1515 }
1516 return 0;
1517 }
1518
hb_video_encoder_pix_fmt_is_supported(int encoder,int pix_fmt)1519 int hb_video_encoder_pix_fmt_is_supported(int encoder, int pix_fmt)
1520 {
1521 const int *pix_fmts = hb_video_encoder_get_pix_fmts(encoder);
1522 while (*pix_fmts != AV_PIX_FMT_NONE)
1523 {
1524 if (pix_fmt == *pix_fmts)
1525 {
1526 return 1;
1527 }
1528 pix_fmts++;
1529 }
1530 return 0;
1531 }
1532
hb_video_encoder_get_depth(int encoder)1533 int hb_video_encoder_get_depth(int encoder)
1534 {
1535 switch (encoder)
1536 {
1537 #if HB_PROJECT_FEATURE_QSV
1538 case HB_VCODEC_QSV_H265_10BIT:
1539 #endif
1540 #ifdef __APPLE__
1541 case HB_VCODEC_FFMPEG_VT_H265_10BIT:
1542 #endif
1543 case HB_VCODEC_X264_10BIT:
1544 case HB_VCODEC_X265_10BIT:
1545 return 10;
1546 case HB_VCODEC_X265_12BIT:
1547 return 12;
1548 case HB_VCODEC_X265_16BIT:
1549 return 16;
1550 default:
1551 return 8;
1552 }
1553 }
1554
hb_video_encoder_get_presets(int encoder)1555 const char* const* hb_video_encoder_get_presets(int encoder)
1556 {
1557 #if HB_PROJECT_FEATURE_QSV
1558 if (encoder & HB_VCODEC_QSV_MASK)
1559 {
1560 return hb_qsv_preset_get_names();
1561 }
1562 #endif
1563
1564 if (encoder & HB_VCODEC_FFMPEG_MASK)
1565 {
1566 return hb_av_preset_get_names(encoder);
1567 }
1568
1569 switch (encoder)
1570 {
1571 case HB_VCODEC_X264_8BIT:
1572 case HB_VCODEC_X264_10BIT:
1573 return x264_preset_names;
1574
1575 #if HB_PROJECT_FEATURE_X265
1576 case HB_VCODEC_X265_8BIT:
1577 case HB_VCODEC_X265_10BIT:
1578 case HB_VCODEC_X265_12BIT:
1579 case HB_VCODEC_X265_16BIT:
1580 return x265_preset_names;
1581 #endif
1582 default:
1583 return NULL;
1584 }
1585 }
1586
hb_video_encoder_get_tunes(int encoder)1587 const char* const* hb_video_encoder_get_tunes(int encoder)
1588 {
1589 switch (encoder)
1590 {
1591 case HB_VCODEC_X264_8BIT:
1592 case HB_VCODEC_X264_10BIT:
1593 return x264_tune_names;
1594
1595 #if HB_PROJECT_FEATURE_X265
1596 case HB_VCODEC_X265_8BIT:
1597 case HB_VCODEC_X265_10BIT:
1598 case HB_VCODEC_X265_12BIT:
1599 case HB_VCODEC_X265_16BIT:
1600 return x265_tune_names;
1601 #endif
1602 default:
1603 return NULL;
1604 }
1605 }
1606
hb_video_encoder_get_profiles(int encoder)1607 const char* const* hb_video_encoder_get_profiles(int encoder)
1608 {
1609 #if HB_PROJECT_FEATURE_QSV
1610 if (encoder & HB_VCODEC_QSV_MASK)
1611 {
1612 return hb_qsv_profile_get_names(encoder);
1613 }
1614 #endif
1615
1616 switch (encoder)
1617 {
1618 case HB_VCODEC_X264_8BIT:
1619 return hb_h264_profile_names_8bit;
1620 case HB_VCODEC_X264_10BIT:
1621 return hb_h264_profile_names_10bit;
1622
1623 case HB_VCODEC_X265_8BIT:
1624 return hb_h265_profile_names_8bit;
1625 case HB_VCODEC_X265_10BIT:
1626 return hb_h265_profile_names_10bit;
1627 case HB_VCODEC_X265_12BIT:
1628 return hb_h265_profile_names_12bit;
1629 case HB_VCODEC_X265_16BIT:
1630 return hb_h265_profile_names_16bit;
1631
1632 #if HB_PROJECT_FEATURE_VCE
1633 case HB_VCODEC_FFMPEG_VCE_H264:
1634 return hb_vce_h264_profile_names;
1635 case HB_VCODEC_FFMPEG_VCE_H265:
1636 return hb_vce_h265_profile_names;
1637 #endif
1638
1639 case HB_VCODEC_FFMPEG_NVENC_H264:
1640 case HB_VCODEC_FFMPEG_NVENC_H265:
1641 case HB_VCODEC_FFMPEG_VT_H264:
1642 case HB_VCODEC_FFMPEG_VT_H265:
1643 case HB_VCODEC_FFMPEG_VT_H265_10BIT:
1644 case HB_VCODEC_FFMPEG_MF_H264:
1645 case HB_VCODEC_FFMPEG_MF_H265:
1646 return hb_av_profile_get_names(encoder);
1647 default:
1648 return NULL;
1649 }
1650 }
1651
hb_video_encoder_get_levels(int encoder)1652 const char* const* hb_video_encoder_get_levels(int encoder)
1653 {
1654 #if HB_PROJECT_FEATURE_QSV
1655 if (encoder & HB_VCODEC_QSV_MASK)
1656 {
1657 return hb_qsv_level_get_names(encoder);
1658 }
1659 #endif
1660
1661 switch (encoder)
1662 {
1663 case HB_VCODEC_X264_8BIT:
1664 case HB_VCODEC_X264_10BIT:
1665 case HB_VCODEC_FFMPEG_NVENC_H264:
1666 case HB_VCODEC_FFMPEG_VT_H264:
1667 case HB_VCODEC_FFMPEG_MF_H264:
1668 return hb_h264_level_names;
1669
1670 #if HB_PROJECT_FEATURE_VCE
1671 case HB_VCODEC_FFMPEG_VCE_H264:
1672 return hb_vce_h264_level_names; // Not quite the same as x264
1673 #endif
1674
1675 case HB_VCODEC_X265_8BIT:
1676 case HB_VCODEC_X265_10BIT:
1677 case HB_VCODEC_X265_12BIT:
1678 case HB_VCODEC_X265_16BIT:
1679 case HB_VCODEC_FFMPEG_NVENC_H265:
1680 case HB_VCODEC_FFMPEG_VCE_H265:
1681 case HB_VCODEC_FFMPEG_MF_H265:
1682 return hb_h265_level_names;
1683
1684 #ifdef __APPLE__
1685 case HB_VCODEC_FFMPEG_VT_H265:
1686 case HB_VCODEC_FFMPEG_VT_H265_10BIT:
1687 return hb_vt_h265_level_names;
1688 #endif
1689
1690 default:
1691 return NULL;
1692 }
1693 }
1694
1695 static const enum AVPixelFormat standard_pix_fmts[] =
1696 {
1697 AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
1698 };
1699
1700 static const enum AVPixelFormat standard_10bit_pix_fmts[] =
1701 {
1702 AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
1703 };
1704
1705 static const enum AVPixelFormat standard_12bit_pix_fmts[] =
1706 {
1707 AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
1708 };
1709
hb_video_encoder_get_pix_fmts(int encoder)1710 const int* hb_video_encoder_get_pix_fmts(int encoder)
1711 {
1712 #if HB_PROJECT_FEATURE_QSV
1713 if (encoder & HB_VCODEC_QSV_MASK)
1714 {
1715 return hb_qsv_get_pix_fmts(encoder);
1716 }
1717 #endif
1718
1719 if (encoder & HB_VCODEC_FFMPEG_MASK)
1720 {
1721 return hb_av_get_pix_fmts(encoder);
1722 }
1723
1724 switch (encoder)
1725 {
1726 case HB_VCODEC_X264_10BIT:
1727 return standard_10bit_pix_fmts;
1728 #if HB_PROJECT_FEATURE_X265
1729 case HB_VCODEC_X265_10BIT:
1730 return standard_10bit_pix_fmts;
1731 case HB_VCODEC_X265_12BIT:
1732 return standard_12bit_pix_fmts;
1733 #endif
1734 default:
1735 return standard_pix_fmts;
1736 }
1737 }
1738
1739 // Get limits and hints for the UIs.
1740 //
1741 // granularity sets the minimum step increments that should be used
1742 // (it's ok to round up to some nice multiple if you like)
1743 //
1744 // direction says whether 'low' limit is highest or lowest
1745 // quality (direction 0 == lowest value is worst quality)
hb_audio_quality_get_limits(uint32_t codec,float * low,float * high,float * granularity,int * direction)1746 void hb_audio_quality_get_limits(uint32_t codec, float *low, float *high,
1747 float *granularity, int *direction)
1748 {
1749 switch (codec)
1750 {
1751 case HB_ACODEC_FFAAC:
1752 *direction = 0;
1753 *granularity = 1.;
1754 *low = 1.;
1755 *high = 10.;
1756 break;
1757
1758 case HB_ACODEC_FDK_HAAC:
1759 case HB_ACODEC_FDK_AAC:
1760 *direction = 0;
1761 *granularity = 1.;
1762 *low = 1.;
1763 *high = 5.;
1764 break;
1765
1766 case HB_ACODEC_LAME:
1767 *direction = 1;
1768 *granularity = 0.5;
1769 *low = 0.;
1770 *high = 10.;
1771 break;
1772
1773 case HB_ACODEC_VORBIS:
1774 *direction = 0;
1775 *granularity = 0.5;
1776 *low = -2.;
1777 *high = 10.;
1778 break;
1779
1780 case HB_ACODEC_CA_AAC:
1781 *direction = 0;
1782 *granularity = 9.;
1783 *low = 1.;
1784 *high = 127.;
1785 break;
1786
1787 default:
1788 *direction = 0;
1789 *granularity = 1.;
1790 *low = *high = HB_INVALID_AUDIO_QUALITY;
1791 break;
1792 }
1793 }
1794
hb_audio_quality_get_best(uint32_t codec,float quality)1795 float hb_audio_quality_get_best(uint32_t codec, float quality)
1796 {
1797 int direction;
1798 float low, high, granularity;
1799 hb_audio_quality_get_limits(codec, &low, &high, &granularity, &direction);
1800 if (quality > high)
1801 quality = high;
1802 if (quality < low)
1803 quality = low;
1804 return quality;
1805 }
1806
hb_audio_quality_get_default(uint32_t codec)1807 float hb_audio_quality_get_default(uint32_t codec)
1808 {
1809 switch (codec)
1810 {
1811 case HB_ACODEC_FFAAC:
1812 return 5.;
1813
1814 case HB_ACODEC_FDK_HAAC:
1815 case HB_ACODEC_FDK_AAC:
1816 return 3.;
1817
1818 case HB_ACODEC_LAME:
1819 return 2.;
1820
1821 case HB_ACODEC_VORBIS:
1822 return 5.;
1823
1824 case HB_ACODEC_CA_AAC:
1825 return 91.;
1826
1827 default:
1828 return HB_INVALID_AUDIO_QUALITY;
1829 }
1830 }
1831
1832 // Get limits and hints for the UIs.
1833 //
1834 // granularity sets the minimum step increments that should be used
1835 // (it's ok to round up to some nice multiple if you like)
1836 //
1837 // direction says whether 'low' limit is highest or lowest
1838 // compression level (direction 0 == lowest value is worst compression level)
hb_audio_compression_get_limits(uint32_t codec,float * low,float * high,float * granularity,int * direction)1839 void hb_audio_compression_get_limits(uint32_t codec, float *low, float *high,
1840 float *granularity, int *direction)
1841 {
1842 switch (codec)
1843 {
1844 case HB_ACODEC_FFFLAC:
1845 case HB_ACODEC_FFFLAC24:
1846 *direction = 0;
1847 *granularity = 1.;
1848 *high = 12.;
1849 *low = 0.;
1850 break;
1851
1852 case HB_ACODEC_LAME:
1853 *direction = 1;
1854 *granularity = 1.;
1855 *high = 9.;
1856 *low = 0.;
1857 break;
1858
1859 case HB_ACODEC_OPUS:
1860 *direction = 0;
1861 *granularity = 1.;
1862 *high = 10.;
1863 *low = 0.;
1864 break;
1865
1866 default:
1867 *direction = 0;
1868 *granularity = 1.;
1869 *low = *high = -1.;
1870 break;
1871 }
1872 }
1873
hb_audio_compression_get_best(uint32_t codec,float compression)1874 float hb_audio_compression_get_best(uint32_t codec, float compression)
1875 {
1876 int direction;
1877 float low, high, granularity;
1878 hb_audio_compression_get_limits(codec, &low, &high, &granularity, &direction);
1879 if( compression > high )
1880 compression = high;
1881 if( compression < low )
1882 compression = low;
1883 return compression;
1884 }
1885
hb_audio_compression_get_default(uint32_t codec)1886 float hb_audio_compression_get_default(uint32_t codec)
1887 {
1888 switch (codec)
1889 {
1890 case HB_ACODEC_FFFLAC:
1891 case HB_ACODEC_FFFLAC24:
1892 return 5.;
1893
1894 case HB_ACODEC_LAME:
1895 return 2.;
1896
1897 case HB_ACODEC_OPUS:
1898 return 10.;
1899
1900 default:
1901 return -1.;
1902 }
1903 }
1904
hb_audio_dither_get_default()1905 int hb_audio_dither_get_default()
1906 {
1907 // "auto"
1908 return hb_audio_dithers_first_item->method;
1909 }
1910
hb_audio_dither_get_default_method()1911 int hb_audio_dither_get_default_method()
1912 {
1913 /*
1914 * input could be s16 (possibly already dithered) converted to flt, so
1915 * let's use a "low-risk" dither algorithm (standard triangular).
1916 */
1917 return SWR_DITHER_TRIANGULAR;
1918 }
1919
hb_audio_dither_is_supported(uint32_t codec,int depth)1920 int hb_audio_dither_is_supported(uint32_t codec, int depth)
1921 {
1922 // Since dithering is performed by swresample, all codecs are supported
1923 switch (codec)
1924 {
1925 case HB_ACODEC_FFFLAC:
1926 if (depth == 0 || depth > 16)
1927 return 1;
1928 }
1929 return 0;
1930 }
1931
hb_audio_dither_get_from_name(const char * name)1932 int hb_audio_dither_get_from_name(const char *name)
1933 {
1934 if (name == NULL || *name == '\0')
1935 goto fail;
1936
1937 int i;
1938 for ( i = 0; i < hb_audio_dithers_count; i++)
1939 {
1940 if (!strcasecmp(hb_audio_dithers[i].item.short_name, name) ||
1941 !strcasecmp(hb_audio_dithers[i].item.description, name))
1942 {
1943 return hb_audio_dithers[i].item.method;
1944 }
1945 }
1946
1947 fail:
1948 return hb_audio_dither_get_default();
1949 }
1950
hb_audio_dither_get_description(int method)1951 const char* hb_audio_dither_get_description(int method)
1952 {
1953 if (method < hb_audio_dithers_first_item->method ||
1954 method > hb_audio_dithers_last_item ->method)
1955 goto fail;
1956
1957 const hb_dither_t *audio_dither = NULL;
1958 while ((audio_dither = hb_audio_dither_get_next(audio_dither)) != NULL)
1959 {
1960 if (audio_dither->method == method)
1961 {
1962 return audio_dither->description;
1963 }
1964 }
1965
1966 fail:
1967 return NULL;
1968 }
1969
hb_audio_dither_get_next(const hb_dither_t * last)1970 const hb_dither_t* hb_audio_dither_get_next(const hb_dither_t *last)
1971 {
1972 if (last == NULL)
1973 {
1974 return hb_audio_dithers_first_item;
1975 }
1976 return ((hb_dither_internal_t*)last)->next;
1977 }
1978
mixdown_get_opus_coupled_stream_count(int mixdown)1979 static int mixdown_get_opus_coupled_stream_count(int mixdown)
1980 {
1981 switch (mixdown)
1982 {
1983 case HB_AMIXDOWN_7POINT1:
1984 case HB_AMIXDOWN_6POINT1:
1985 return 3;
1986
1987 case HB_AMIXDOWN_5POINT1:
1988 return 2;
1989
1990 case HB_AMIXDOWN_MONO:
1991 case HB_AMIXDOWN_LEFT:
1992 case HB_AMIXDOWN_RIGHT:
1993 return 0;
1994
1995 case HB_AMIXDOWN_NONE:
1996 case HB_INVALID_AMIXDOWN:
1997 case HB_AMIXDOWN_5_2_LFE:
1998 // The 5F/2R/LFE configuration is currently not supported by Opus,
1999 // so don't set coupled streams.
2000 return 0;
2001
2002 default:
2003 return 1;
2004 }
2005 }
2006
hb_mixdown_is_supported(int mixdown,uint32_t codec,uint64_t layout)2007 int hb_mixdown_is_supported(int mixdown, uint32_t codec, uint64_t layout)
2008 {
2009 return (hb_mixdown_has_codec_support(mixdown, codec) &&
2010 hb_mixdown_has_remix_support(mixdown, layout));
2011 }
2012
hb_mixdown_has_codec_support(int mixdown,uint32_t codec)2013 int hb_mixdown_has_codec_support(int mixdown, uint32_t codec)
2014 {
2015 // Passthru, only "None" mixdown is supported
2016 if (codec & HB_ACODEC_PASS_FLAG)
2017 return (mixdown == HB_AMIXDOWN_NONE);
2018
2019 // Not passthru, "None" mixdown never supported
2020 if (mixdown == HB_AMIXDOWN_NONE)
2021 return 0;
2022
2023 switch (codec)
2024 {
2025 case HB_ACODEC_VORBIS:
2026 case HB_ACODEC_FFFLAC:
2027 case HB_ACODEC_FFFLAC24:
2028 case HB_ACODEC_OPUS:
2029 case HB_ACODEC_CA_AAC:
2030 case HB_ACODEC_CA_HAAC:
2031 case HB_ACODEC_FFAAC:
2032 return (mixdown <= HB_AMIXDOWN_7POINT1);
2033
2034 case HB_ACODEC_LAME:
2035 return (mixdown <= HB_AMIXDOWN_DOLBYPLII);
2036
2037 case HB_ACODEC_FDK_AAC:
2038 case HB_ACODEC_FDK_HAAC:
2039 return ((mixdown <= HB_AMIXDOWN_5POINT1) ||
2040 (mixdown == HB_AMIXDOWN_7POINT1));
2041
2042 default:
2043 return (mixdown <= HB_AMIXDOWN_5POINT1);
2044 }
2045 }
2046
hb_mixdown_has_remix_support(int mixdown,uint64_t layout)2047 int hb_mixdown_has_remix_support(int mixdown, uint64_t layout)
2048 {
2049 /*
2050 * Where there isn't a source (e.g. audio defaults panel), we have no input
2051 * layout; assume remix support, as the mixdown will be sanitized later on.
2052 */
2053 if (!layout)
2054 {
2055 return 1;
2056 }
2057 switch (mixdown)
2058 {
2059 // stereo + front left/right of center
2060 case HB_AMIXDOWN_5_2_LFE:
2061 return ((layout & AV_CH_FRONT_LEFT_OF_CENTER) &&
2062 (layout & AV_CH_FRONT_RIGHT_OF_CENTER) &&
2063 (layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO);
2064
2065 // 7.0 or better
2066 case HB_AMIXDOWN_7POINT1:
2067 return ((layout & AV_CH_LAYOUT_7POINT0) == AV_CH_LAYOUT_7POINT0);
2068
2069 // 6.0 or better
2070 case HB_AMIXDOWN_6POINT1:
2071 return ((layout & AV_CH_LAYOUT_7POINT0) == AV_CH_LAYOUT_7POINT0 ||
2072 (layout & AV_CH_LAYOUT_6POINT0) == AV_CH_LAYOUT_6POINT0 ||
2073 (layout & AV_CH_LAYOUT_HEXAGONAL) == AV_CH_LAYOUT_HEXAGONAL);
2074
2075 // stereo + either of front center, side or back left/right, back center
2076 case HB_AMIXDOWN_5POINT1:
2077 return ((layout & AV_CH_LAYOUT_2_1) == AV_CH_LAYOUT_2_1 ||
2078 (layout & AV_CH_LAYOUT_2_2) == AV_CH_LAYOUT_2_2 ||
2079 (layout & AV_CH_LAYOUT_QUAD) == AV_CH_LAYOUT_QUAD ||
2080 (layout & AV_CH_LAYOUT_SURROUND) == AV_CH_LAYOUT_SURROUND);
2081
2082 // stereo + either of side or back left/right, back center
2083 // also, allow Dolby Surround output if the input is already Dolby
2084 case HB_AMIXDOWN_DOLBY:
2085 case HB_AMIXDOWN_DOLBYPLII:
2086 return ((layout & AV_CH_LAYOUT_2_1) == AV_CH_LAYOUT_2_1 ||
2087 (layout & AV_CH_LAYOUT_2_2) == AV_CH_LAYOUT_2_2 ||
2088 (layout & AV_CH_LAYOUT_QUAD) == AV_CH_LAYOUT_QUAD ||
2089 (layout == AV_CH_LAYOUT_STEREO_DOWNMIX &&
2090 mixdown == HB_AMIXDOWN_DOLBY));
2091
2092 // more than 1 channel
2093 case HB_AMIXDOWN_STEREO:
2094 return (av_get_channel_layout_nb_channels(layout) > 1);
2095
2096 // regular stereo (not Dolby)
2097 case HB_AMIXDOWN_LEFT:
2098 case HB_AMIXDOWN_RIGHT:
2099 return (layout & AV_CH_LAYOUT_STEREO);
2100
2101 // mono remix always supported
2102 // HB_AMIXDOWN_NONE always supported (for Passthru)
2103 case HB_AMIXDOWN_MONO:
2104 case HB_AMIXDOWN_NONE:
2105 return 1;
2106
2107 // unknown mixdown, should never happen
2108 default:
2109 return 0;
2110 }
2111 }
2112
hb_mixdown_get_discrete_channel_count(int amixdown)2113 int hb_mixdown_get_discrete_channel_count(int amixdown)
2114 {
2115 switch (amixdown)
2116 {
2117 case HB_AMIXDOWN_5_2_LFE:
2118 case HB_AMIXDOWN_7POINT1:
2119 return 8;
2120
2121 case HB_AMIXDOWN_6POINT1:
2122 return 7;
2123
2124 case HB_AMIXDOWN_5POINT1:
2125 return 6;
2126
2127 case HB_AMIXDOWN_MONO:
2128 case HB_AMIXDOWN_LEFT:
2129 case HB_AMIXDOWN_RIGHT:
2130 return 1;
2131
2132 case HB_AMIXDOWN_NONE:
2133 return 0;
2134
2135 default:
2136 return 2;
2137 }
2138 }
2139
hb_mixdown_get_low_freq_channel_count(int amixdown)2140 int hb_mixdown_get_low_freq_channel_count(int amixdown)
2141 {
2142 switch (amixdown)
2143 {
2144 case HB_AMIXDOWN_5POINT1:
2145 case HB_AMIXDOWN_6POINT1:
2146 case HB_AMIXDOWN_7POINT1:
2147 case HB_AMIXDOWN_5_2_LFE:
2148 return 1;
2149
2150 default:
2151 return 0;
2152 }
2153 }
2154
hb_mixdown_get_best(uint32_t codec,uint64_t layout,int mixdown)2155 int hb_mixdown_get_best(uint32_t codec, uint64_t layout, int mixdown)
2156 {
2157 // Passthru, only "None" mixdown is supported
2158 if (codec & HB_ACODEC_PASS_FLAG)
2159 return HB_AMIXDOWN_NONE;
2160
2161 int best_mixdown = HB_INVALID_AMIXDOWN;
2162 const hb_mixdown_t *audio_mixdown = hb_mixdown_get_next(NULL);
2163 // test all non-None mixdowns while the value is <= the requested mixdown
2164 // HB_INVALID_AMIXDOWN means the highest supported mixdown was requested
2165 while ((audio_mixdown = hb_mixdown_get_next(audio_mixdown)) != NULL)
2166 {
2167 if ((mixdown == HB_INVALID_AMIXDOWN || audio_mixdown->amixdown <= mixdown) &&
2168 (hb_mixdown_is_supported(audio_mixdown->amixdown, codec, layout)))
2169 {
2170 best_mixdown = audio_mixdown->amixdown;
2171 }
2172 }
2173 return best_mixdown;
2174 }
2175
hb_mixdown_get_default(uint32_t codec,uint64_t layout)2176 int hb_mixdown_get_default(uint32_t codec, uint64_t layout)
2177 {
2178 int mixdown;
2179 switch (codec)
2180 {
2181 // the FLAC encoder defaults to the best mixdown up to 7.1
2182 case HB_ACODEC_FFFLAC:
2183 case HB_ACODEC_FFFLAC24:
2184 case HB_ACODEC_OPUS:
2185 case HB_ACODEC_CA_AAC:
2186 case HB_ACODEC_CA_HAAC:
2187 case HB_ACODEC_FFAAC:
2188 case HB_ACODEC_FDK_AAC:
2189 case HB_ACODEC_FDK_HAAC:
2190 mixdown = HB_AMIXDOWN_7POINT1;
2191 break;
2192
2193 // the (E-)AC-3 encoder defaults to the best mixdown up to 5.1
2194 case HB_ACODEC_AC3:
2195 case HB_ACODEC_FFEAC3:
2196 mixdown = HB_AMIXDOWN_5POINT1;
2197 break;
2198
2199 // other encoders default to the best mixdown up to DPLII
2200 default:
2201 mixdown = HB_AMIXDOWN_DOLBYPLII;
2202 break;
2203 }
2204
2205 // return the best available mixdown up to the selected default
2206 return hb_mixdown_get_best(codec, layout, mixdown);
2207 }
2208
hb_mixdown_get_from_mixdown(int mixdown)2209 hb_mixdown_t* hb_mixdown_get_from_mixdown(int mixdown)
2210 {
2211 int i;
2212 for (i = 0; i < hb_audio_mixdowns_count; i++)
2213 {
2214 if (hb_audio_mixdowns[i].item.amixdown == mixdown)
2215 {
2216 return &hb_audio_mixdowns[i].item;
2217 }
2218 }
2219
2220 return NULL;
2221 }
2222
hb_mixdown_get_from_name(const char * name)2223 int hb_mixdown_get_from_name(const char *name)
2224 {
2225 if (name == NULL || *name == '\0')
2226 goto fail;
2227
2228 int i;
2229 for (i = 0; i < hb_audio_mixdowns_count; i++)
2230 {
2231 if (!strcasecmp(hb_audio_mixdowns[i].item.name, name) ||
2232 !strcasecmp(hb_audio_mixdowns[i].item.short_name, name))
2233 {
2234 return hb_audio_mixdowns[i].item.amixdown;
2235 }
2236 }
2237
2238 fail:
2239 return HB_INVALID_AMIXDOWN;
2240 }
2241
hb_mixdown_get_name(int mixdown)2242 const char* hb_mixdown_get_name(int mixdown)
2243 {
2244 if (mixdown < hb_audio_mixdowns_first_item->amixdown ||
2245 mixdown > hb_audio_mixdowns_last_item ->amixdown)
2246 goto fail;
2247
2248 const hb_mixdown_t *audio_mixdown = NULL;
2249 while ((audio_mixdown = hb_mixdown_get_next(audio_mixdown)) != NULL)
2250 {
2251 if (audio_mixdown->amixdown == mixdown)
2252 {
2253 return audio_mixdown->name;
2254 }
2255 }
2256
2257 fail:
2258 return NULL;
2259 }
2260
hb_mixdown_get_short_name(int mixdown)2261 const char* hb_mixdown_get_short_name(int mixdown)
2262 {
2263 if (mixdown < hb_audio_mixdowns_first_item->amixdown ||
2264 mixdown > hb_audio_mixdowns_last_item ->amixdown)
2265 goto fail;
2266
2267 const hb_mixdown_t *audio_mixdown = NULL;
2268 while ((audio_mixdown = hb_mixdown_get_next(audio_mixdown)) != NULL)
2269 {
2270 if (audio_mixdown->amixdown == mixdown)
2271 {
2272 return audio_mixdown->short_name;
2273 }
2274 }
2275
2276 fail:
2277 return NULL;
2278 }
2279
hb_mixdown_sanitize_name(const char * name)2280 const char* hb_mixdown_sanitize_name(const char *name)
2281 {
2282 return hb_mixdown_get_name(hb_mixdown_get_from_name(name));
2283 }
2284
hb_mixdown_get_next(const hb_mixdown_t * last)2285 const hb_mixdown_t* hb_mixdown_get_next(const hb_mixdown_t *last)
2286 {
2287 if (last == NULL)
2288 {
2289 return hb_audio_mixdowns_first_item;
2290 }
2291 return ((hb_mixdown_internal_t*)last)->next;
2292 }
2293
hb_layout_get_name(char * name,int size,int64_t layout)2294 void hb_layout_get_name(char * name, int size, int64_t layout)
2295 {
2296 av_get_channel_layout_string(name, size, 0, layout);
2297 }
2298
hb_layout_get_discrete_channel_count(int64_t layout)2299 int hb_layout_get_discrete_channel_count(int64_t layout)
2300 {
2301 return av_get_channel_layout_nb_channels(layout);
2302 }
2303
hb_layout_get_low_freq_channel_count(int64_t layout)2304 int hb_layout_get_low_freq_channel_count(int64_t layout)
2305 {
2306 return !!(layout & AV_CH_LOW_FREQUENCY) +
2307 !!(layout & AV_CH_LOW_FREQUENCY_2);
2308 }
2309
hb_video_encoder_get_default(int muxer)2310 int hb_video_encoder_get_default(int muxer)
2311 {
2312 if (!(muxer & HB_MUX_MASK))
2313 goto fail;
2314
2315 const hb_encoder_t *video_encoder = NULL;
2316 while ((video_encoder = hb_video_encoder_get_next(video_encoder)) != NULL)
2317 {
2318 if (video_encoder->muxers & muxer)
2319 {
2320 return video_encoder->codec;
2321 }
2322 }
2323
2324 fail:
2325 return HB_VCODEC_INVALID;
2326 }
2327
hb_video_encoder_get_from_codec(int codec)2328 hb_encoder_t * hb_video_encoder_get_from_codec(int codec)
2329 {
2330 int i;
2331 for (i = 0; i < hb_video_encoders_count; i++)
2332 {
2333 if (hb_video_encoders[i].item.codec == codec)
2334 {
2335 return &hb_video_encoders[i].item;
2336 }
2337 }
2338
2339 return NULL;
2340 }
2341
hb_video_encoder_get_from_name(const char * name)2342 int hb_video_encoder_get_from_name(const char *name)
2343 {
2344 if (name == NULL || *name == '\0')
2345 goto fail;
2346
2347 int i;
2348 for (i = 0; i < hb_video_encoders_count; i++)
2349 {
2350 if (!strcasecmp(hb_video_encoders[i].item.name, name) ||
2351 !strcasecmp(hb_video_encoders[i].item.short_name, name))
2352 {
2353 return hb_video_encoders[i].item.codec;
2354 }
2355 }
2356
2357 fail:
2358 return HB_VCODEC_INVALID;
2359 }
2360
hb_video_encoder_get_name(int encoder)2361 const char* hb_video_encoder_get_name(int encoder)
2362 {
2363 if (!(encoder & HB_VCODEC_MASK))
2364 goto fail;
2365
2366 int i;
2367 for (i = 0; i < hb_video_encoders_count; i++)
2368 {
2369 if (hb_video_encoders[i].item.codec == encoder && hb_video_encoders[i].deprecated == 0)
2370 {
2371 return hb_video_encoders[i].item.name;
2372 }
2373 }
2374
2375 fail:
2376 return NULL;
2377 }
2378
hb_video_encoder_get_short_name(int encoder)2379 const char* hb_video_encoder_get_short_name(int encoder)
2380 {
2381 if (!(encoder & HB_VCODEC_MASK))
2382 goto fail;
2383
2384 int i;
2385 for (i = 0; i < hb_video_encoders_count; i++)
2386 {
2387 if (hb_video_encoders[i].item.codec == encoder && hb_video_encoders[i].deprecated == 0)
2388 {
2389 return hb_video_encoders[i].item.short_name;
2390 }
2391 }
2392
2393 fail:
2394 return NULL;
2395 }
2396
hb_video_encoder_get_long_name(int encoder)2397 const char* hb_video_encoder_get_long_name(int encoder)
2398 {
2399 if (!(encoder & HB_VCODEC_MASK))
2400 goto fail;
2401
2402 int i;
2403 for (i = 0; i < hb_video_encoders_count; i++)
2404 {
2405 if (hb_video_encoders[i].item.codec == encoder && hb_video_encoders[i].deprecated == 0)
2406 {
2407 return hb_video_encoders[i].item.long_name;
2408 }
2409 }
2410
2411 fail:
2412 return NULL;
2413 }
2414
hb_video_encoder_sanitize_name(const char * name)2415 const char* hb_video_encoder_sanitize_name(const char *name)
2416 {
2417 return hb_video_encoder_get_name(hb_video_encoder_get_from_name(name));
2418 }
2419
hb_video_encoder_get_next(const hb_encoder_t * last)2420 const hb_encoder_t* hb_video_encoder_get_next(const hb_encoder_t *last)
2421 {
2422 if (last == NULL)
2423 {
2424 return hb_video_encoders_first_item;
2425 }
2426 return ((hb_encoder_internal_t*)last)->next;
2427 }
2428
2429 // for a valid passthru, return the matching encoder for that codec (if any),
2430 // else return -1 (i.e. drop the track)
hb_audio_encoder_get_fallback_for_passthru(int passthru)2431 int hb_audio_encoder_get_fallback_for_passthru(int passthru)
2432 {
2433 int gid;
2434 const hb_encoder_t *audio_encoder = NULL;
2435 switch (passthru)
2436 {
2437 case HB_ACODEC_AAC_PASS:
2438 gid = HB_GID_ACODEC_AAC;
2439 break;
2440
2441 case HB_ACODEC_AC3_PASS:
2442 gid = HB_GID_ACODEC_AC3;
2443 break;
2444
2445 case HB_ACODEC_EAC3_PASS:
2446 gid = HB_GID_ACODEC_EAC3;
2447 break;
2448
2449 case HB_ACODEC_FLAC_PASS:
2450 gid = HB_GID_ACODEC_FLAC;
2451 break;
2452
2453 case HB_ACODEC_MP3_PASS:
2454 gid = HB_GID_ACODEC_MP3;
2455 break;
2456
2457 default:
2458 return HB_ACODEC_INVALID;
2459 break;
2460 }
2461 while ((audio_encoder = hb_audio_encoder_get_next(audio_encoder)) != NULL)
2462 {
2463 if (((hb_encoder_internal_t*)audio_encoder)->gid == gid)
2464 {
2465 return audio_encoder->codec;
2466 }
2467 }
2468
2469 // passthru tracks are often the second audio from the same source track
2470 // if we don't have an encoder matching the passthru codec, return INVALID
2471 // dropping the track, as well as ensuring that there is at least one
2472 // audio track in the output is then up to the UIs
2473 return HB_ACODEC_INVALID;
2474 }
2475
hb_audio_encoder_get_default(int muxer)2476 int hb_audio_encoder_get_default(int muxer)
2477 {
2478 if (!(muxer & HB_MUX_MASK))
2479 goto fail;
2480
2481 int codec = 0;
2482 const hb_encoder_t *audio_encoder = NULL;
2483 while ((audio_encoder = hb_audio_encoder_get_next(audio_encoder)) != NULL)
2484 {
2485 // default encoder should not be passthru
2486 if ((audio_encoder->muxers & muxer) &&
2487 (audio_encoder->codec & HB_ACODEC_PASS_FLAG) == 0)
2488 {
2489 codec = audio_encoder->codec;
2490 break;
2491 }
2492 }
2493
2494 // Lame is better than our low-end AAC encoders
2495 // if the container is MKV, use the former
2496 // AAC is still used when the container is MP4 (for better compatibility)
2497 if (codec == HB_ACODEC_FFAAC && (muxer & HB_MUX_MASK_MKV) == muxer)
2498 {
2499 return HB_ACODEC_LAME;
2500 }
2501 else
2502 {
2503 return codec;
2504 }
2505
2506 fail:
2507 return HB_ACODEC_INVALID;
2508 }
2509
hb_audio_encoder_get_from_codec(int codec)2510 hb_encoder_t* hb_audio_encoder_get_from_codec(int codec)
2511 {
2512 int i;
2513 for (i = 0; i < hb_audio_encoders_count; i++)
2514 {
2515 if (hb_audio_encoders[i].item.codec == codec)
2516 {
2517 return &hb_audio_encoders[i].item;
2518 }
2519 }
2520
2521 return NULL;
2522 }
2523
hb_audio_encoder_get_from_name(const char * name)2524 int hb_audio_encoder_get_from_name(const char *name)
2525 {
2526 if (name == NULL || *name == '\0')
2527 goto fail;
2528
2529 int i;
2530 for (i = 0; i < hb_audio_encoders_count; i++)
2531 {
2532 if (!strcasecmp(hb_audio_encoders[i].item.name, name) ||
2533 !strcasecmp(hb_audio_encoders[i].item.short_name, name))
2534 {
2535 return hb_audio_encoders[i].item.codec;
2536 }
2537 }
2538
2539 fail:
2540 return HB_ACODEC_INVALID;
2541 }
2542
hb_audio_encoder_get_name(int encoder)2543 const char* hb_audio_encoder_get_name(int encoder)
2544 {
2545 if (!(encoder & HB_ACODEC_ANY))
2546 goto fail;
2547
2548 const hb_encoder_t *audio_encoder = NULL;
2549 while ((audio_encoder = hb_audio_encoder_get_next(audio_encoder)) != NULL)
2550 {
2551 if (audio_encoder->codec == encoder)
2552 {
2553 return audio_encoder->name;
2554 }
2555 }
2556
2557 fail:
2558 return NULL;
2559 }
2560
hb_audio_encoder_get_short_name(int encoder)2561 const char* hb_audio_encoder_get_short_name(int encoder)
2562 {
2563 if (!(encoder & HB_ACODEC_ANY))
2564 goto fail;
2565
2566 const hb_encoder_t *audio_encoder = NULL;
2567 while ((audio_encoder = hb_audio_encoder_get_next(audio_encoder)) != NULL)
2568 {
2569 if (audio_encoder->codec == encoder)
2570 {
2571 return audio_encoder->short_name;
2572 }
2573 }
2574
2575 fail:
2576 return NULL;
2577 }
2578
hb_audio_encoder_get_long_name(int encoder)2579 const char* hb_audio_encoder_get_long_name(int encoder)
2580 {
2581 if (!(encoder & HB_ACODEC_ANY))
2582 goto fail;
2583
2584 const hb_encoder_t *audio_encoder = NULL;
2585 while ((audio_encoder = hb_audio_encoder_get_next(audio_encoder)) != NULL)
2586 {
2587 if (audio_encoder->codec == encoder)
2588 {
2589 return audio_encoder->long_name;
2590 }
2591 }
2592
2593 fail:
2594 return NULL;
2595 }
2596
hb_audio_encoder_sanitize_name(const char * name)2597 const char* hb_audio_encoder_sanitize_name(const char *name)
2598 {
2599 return hb_audio_encoder_get_name(hb_audio_encoder_get_from_name(name));
2600 }
2601
hb_audio_encoder_get_next(const hb_encoder_t * last)2602 const hb_encoder_t* hb_audio_encoder_get_next(const hb_encoder_t *last)
2603 {
2604 if (last == NULL)
2605 {
2606 return hb_audio_encoders_first_item;
2607 }
2608 return ((hb_encoder_internal_t*)last)->next;
2609 }
2610
hb_autopassthru_apply_settings(hb_job_t * job)2611 void hb_autopassthru_apply_settings(hb_job_t *job)
2612 {
2613 hb_audio_t *audio;
2614 int i, already_printed;
2615 for (i = already_printed = 0; i < hb_list_count(job->list_audio);)
2616 {
2617 audio = hb_list_item(job->list_audio, i);
2618 if (audio->config.out.codec == HB_ACODEC_AUTO_PASS)
2619 {
2620 if (!already_printed)
2621 hb_autopassthru_print_settings(job);
2622 already_printed = 1;
2623 audio->config.out.codec = hb_autopassthru_get_encoder(audio->config.in.codec,
2624 job->acodec_copy_mask,
2625 job->acodec_fallback,
2626 job->mux);
2627 if (audio->config.out.codec == HB_ACODEC_NONE ||
2628 audio->config.out.codec == HB_ACODEC_INVALID)
2629 {
2630 hb_log("Auto Passthru: passthru not possible and no valid fallback specified, dropping track %d",
2631 audio->config.out.track );
2632 hb_list_rem(job->list_audio, audio);
2633 hb_audio_close(&audio);
2634 continue;
2635 }
2636 if (!(audio->config.out.codec & HB_ACODEC_PASS_FLAG))
2637 {
2638 hb_log("Auto Passthru: passthru not possible for track %d, using fallback",
2639 audio->config.out.track);
2640 if (audio->config.out.mixdown <= 0)
2641 {
2642 audio->config.out.mixdown =
2643 hb_mixdown_get_default(audio->config.out.codec,
2644 audio->config.in.channel_layout);
2645 }
2646 else
2647 {
2648 audio->config.out.mixdown =
2649 hb_mixdown_get_best(audio->config.out.codec,
2650 audio->config.in.channel_layout,
2651 audio->config.out.mixdown);
2652 }
2653 if (audio->config.out.samplerate <= 0)
2654 audio->config.out.samplerate = audio->config.in.samplerate;
2655 audio->config.out.samplerate =
2656 hb_audio_samplerate_find_closest(
2657 audio->config.out.samplerate, audio->config.out.codec);
2658 int quality_not_allowed =
2659 hb_audio_quality_get_default(audio->config.out.codec)
2660 == HB_INVALID_AUDIO_QUALITY;
2661 if (audio->config.out.bitrate > 0)
2662 {
2663 // Use best bitrate
2664 audio->config.out.bitrate =
2665 hb_audio_bitrate_get_best(audio->config.out.codec,
2666 audio->config.out.bitrate,
2667 audio->config.out.samplerate,
2668 audio->config.out.mixdown);
2669 }
2670 else if (quality_not_allowed ||
2671 audio->config.out.quality != HB_INVALID_AUDIO_QUALITY)
2672 {
2673 // Use default bitrate
2674 audio->config.out.bitrate =
2675 hb_audio_bitrate_get_default(audio->config.out.codec,
2676 audio->config.out.samplerate,
2677 audio->config.out.mixdown);
2678 }
2679 else
2680 {
2681 // Use best quality
2682 audio->config.out.quality =
2683 hb_audio_quality_get_best(audio->config.out.codec,
2684 audio->config.out.quality);
2685 }
2686 if (audio->config.out.compression_level < 0)
2687 {
2688 audio->config.out.compression_level =
2689 hb_audio_compression_get_default(
2690 audio->config.out.codec);
2691 }
2692 else
2693 {
2694 audio->config.out.compression_level =
2695 hb_audio_compression_get_best(audio->config.out.codec,
2696 audio->config.out.compression_level);
2697 }
2698 }
2699 else
2700 {
2701 const hb_encoder_t *audio_encoder = NULL;
2702 while ((audio_encoder = hb_audio_encoder_get_next(audio_encoder)) != NULL)
2703 {
2704 if (audio_encoder->codec == audio->config.out.codec)
2705 {
2706 hb_log("Auto Passthru: using %s for track %d",
2707 audio_encoder->name,
2708 audio->config.out.track);
2709 break;
2710 }
2711 }
2712 }
2713 }
2714 /* Adjust output track number, in case we removed one.
2715 * Output tracks sadly still need to be in sequential order.
2716 * Note: out.track starts at 1, i starts at 0 */
2717 audio->config.out.track = ++i;
2718 }
2719 }
2720
hb_autopassthru_print_settings(hb_job_t * job)2721 void hb_autopassthru_print_settings(hb_job_t *job)
2722 {
2723 char *mask = NULL, *tmp;
2724 const char *fallback = NULL;
2725 const hb_encoder_t *audio_encoder = NULL;
2726 while ((audio_encoder = hb_audio_encoder_get_next(audio_encoder)) != NULL)
2727 {
2728 if ((audio_encoder->codec & HB_ACODEC_PASS_FLAG) &&
2729 (audio_encoder->codec != HB_ACODEC_AUTO_PASS) &&
2730 (audio_encoder->codec & (job->acodec_copy_mask &
2731 HB_ACODEC_PASS_MASK)))
2732 {
2733 if (mask != NULL)
2734 {
2735 tmp = hb_strncat_dup(mask, ", ", 2);
2736 if (tmp != NULL)
2737 {
2738 free(mask);
2739 mask = tmp;
2740 }
2741 }
2742 // passthru name without " Passthru"
2743 tmp = hb_strncat_dup(mask, audio_encoder->name,
2744 strlen(audio_encoder->name) - 9);
2745 if (tmp != NULL)
2746 {
2747 free(mask);
2748 mask = tmp;
2749 }
2750 }
2751 else if ((audio_encoder->codec & HB_ACODEC_PASS_FLAG) == 0 &&
2752 (audio_encoder->codec == job->acodec_fallback))
2753 {
2754 fallback = audio_encoder->name;
2755 }
2756 }
2757 if (mask == NULL)
2758 hb_log("Auto Passthru: no codecs allowed");
2759 else
2760 hb_log("Auto Passthru: allowed codecs are %s", mask);
2761 if (fallback == NULL)
2762 hb_log("Auto Passthru: no valid fallback specified");
2763 else
2764 hb_log("Auto Passthru: fallback is %s", fallback);
2765 }
2766
hb_autopassthru_get_encoder(int in_codec,int copy_mask,int fallback,int muxer)2767 int hb_autopassthru_get_encoder(int in_codec, int copy_mask, int fallback,
2768 int muxer)
2769 {
2770 int out_codec_result_set = 0;
2771 int fallback_result_set = 0;
2772 int out_codec_result = HB_ACODEC_INVALID;
2773 int fallback_result = HB_ACODEC_INVALID;
2774 const hb_encoder_t *audio_encoder = NULL;
2775 int out_codec = (copy_mask & in_codec) | HB_ACODEC_PASS_FLAG;
2776
2777 // sanitize fallback encoder and selected passthru
2778 // note: invalid fallbacks are caught in hb_autopassthru_apply_settings
2779 while ((audio_encoder = hb_audio_encoder_get_next(audio_encoder)) != NULL)
2780 {
2781 if (!out_codec_result_set && audio_encoder->codec == out_codec)
2782 {
2783 out_codec_result_set = 1;
2784 if (audio_encoder->muxers & muxer)
2785 out_codec_result = out_codec;
2786 }
2787 else if (!fallback_result_set && audio_encoder->codec == fallback)
2788 {
2789 fallback_result_set = 1;
2790 if ((audio_encoder->muxers & muxer) || fallback == HB_ACODEC_NONE)
2791 fallback_result = fallback;
2792 }
2793 if (out_codec_result_set && fallback_result_set)
2794 {
2795 break;
2796 }
2797 }
2798 return (out_codec_result != HB_ACODEC_INVALID) ? out_codec_result :
2799 fallback_result;
2800 }
2801
hb_audio_decoder_get_name(int codec,int codec_param)2802 const char* hb_audio_decoder_get_name(int codec, int codec_param)
2803 {
2804 if (codec & HB_ACODEC_FF_MASK)
2805 {
2806 AVCodec * codec;
2807
2808 codec = avcodec_find_decoder(codec_param);
2809 if (codec != NULL)
2810 {
2811 return codec->name;
2812 }
2813 }
2814 else
2815 {
2816 switch (codec)
2817 {
2818 case HB_ACODEC_LPCM:
2819 return "pcm_dvd";
2820 default:
2821 break;
2822 }
2823 }
2824 return "unknown";
2825 }
2826
hb_container_get_from_format(int format)2827 hb_container_t* hb_container_get_from_format(int format)
2828 {
2829 int i;
2830 for (i = 0; i < hb_containers_count; i++)
2831 {
2832 if (hb_containers[i].item.format == format)
2833 {
2834 return &hb_containers[i].item;
2835 }
2836 }
2837
2838 return NULL;
2839 }
2840
hb_container_get_from_name(const char * name)2841 int hb_container_get_from_name(const char *name)
2842 {
2843 if (name == NULL || *name == '\0')
2844 goto fail;
2845
2846 int i;
2847 for (i = 0; i < hb_containers_count; i++)
2848 {
2849 if (!strcasecmp(hb_containers[i].item.name, name) ||
2850 !strcasecmp(hb_containers[i].item.short_name, name))
2851 {
2852 return hb_containers[i].item.format;
2853 }
2854 }
2855
2856 fail:
2857 return HB_MUX_INVALID;
2858 }
2859
hb_container_get_from_extension(const char * extension)2860 int hb_container_get_from_extension(const char *extension)
2861 {
2862 if (extension == NULL || *extension == '\0')
2863 goto fail;
2864
2865 int i;
2866 for (i = 0; i < hb_containers_count; i++)
2867 {
2868 if (!strcasecmp(hb_containers[i].item.default_extension, extension))
2869 {
2870 return hb_containers[i].item.format;
2871 }
2872 }
2873
2874 fail:
2875 return HB_MUX_INVALID;
2876 }
2877
hb_container_get_name(int format)2878 const char* hb_container_get_name(int format)
2879 {
2880 if (!(format & HB_MUX_MASK))
2881 goto fail;
2882
2883 const hb_container_t *container = NULL;
2884 while ((container = hb_container_get_next(container)) != NULL)
2885 {
2886 if (container->format == format)
2887 {
2888 return container->name;
2889 }
2890 }
2891
2892 fail:
2893 return NULL;
2894 }
2895
hb_container_get_short_name(int format)2896 const char* hb_container_get_short_name(int format)
2897 {
2898 if (!(format & HB_MUX_MASK))
2899 goto fail;
2900
2901 const hb_container_t *container = NULL;
2902 while ((container = hb_container_get_next(container)) != NULL)
2903 {
2904 if (container->format == format)
2905 {
2906 return container->short_name;
2907 }
2908 }
2909
2910 fail:
2911 return NULL;
2912 }
2913
hb_container_get_long_name(int format)2914 const char* hb_container_get_long_name(int format)
2915 {
2916 if (!(format & HB_MUX_MASK))
2917 goto fail;
2918
2919 const hb_container_t *container = NULL;
2920 while ((container = hb_container_get_next(container)) != NULL)
2921 {
2922 if (container->format == format)
2923 {
2924 return container->long_name;
2925 }
2926 }
2927
2928 fail:
2929 return NULL;
2930 }
2931
hb_container_get_default_extension(int format)2932 const char* hb_container_get_default_extension(int format)
2933 {
2934 if (!(format & HB_MUX_MASK))
2935 goto fail;
2936
2937 const hb_container_t *container = NULL;
2938 while ((container = hb_container_get_next(container)) != NULL)
2939 {
2940 if (container->format == format)
2941 {
2942 return container->default_extension;
2943 }
2944 }
2945
2946 fail:
2947 return NULL;
2948 }
2949
hb_container_sanitize_name(const char * name)2950 const char* hb_container_sanitize_name(const char *name)
2951 {
2952 return hb_container_get_name(hb_container_get_from_name(name));
2953 }
2954
hb_container_get_next(const hb_container_t * last)2955 const hb_container_t* hb_container_get_next(const hb_container_t *last)
2956 {
2957 if (last == NULL)
2958 {
2959 return hb_containers_first_item;
2960 }
2961 return ((hb_container_internal_t*)last)->next;
2962 }
2963
2964 /**********************************************************************
2965 * hb_reduce
2966 **********************************************************************
2967 * Given a numerator (num) and a denominator (den), reduce them to an
2968 * equivalent fraction and store the result in x and y.
2969 *********************************************************************/
hb_reduce(int * x,int * y,int num,int den)2970 void hb_reduce( int *x, int *y, int num, int den )
2971 {
2972 // find the greatest common divisor of num & den by Euclid's algorithm
2973 int n = num, d = den;
2974 while ( d )
2975 {
2976 int t = d;
2977 d = n % d;
2978 n = t;
2979 }
2980
2981 // at this point n is the gcd. if it's non-zero remove it from num
2982 // and den. Otherwise just return the original values.
2983 if ( n )
2984 {
2985 *x = num / n;
2986 *y = den / n;
2987 }
2988 else
2989 {
2990 *x = num;
2991 *y = den;
2992 }
2993 }
2994
hb_limit_rational(int * x,int * y,int64_t num,int64_t den,int limit)2995 void hb_limit_rational( int *x, int *y, int64_t num, int64_t den, int limit )
2996 {
2997 hb_reduce64( &num, &den, num, den );
2998 if ( num < limit && den < limit )
2999 {
3000 *x = num;
3001 *y = den;
3002 return;
3003 }
3004
3005 if ( num > den )
3006 {
3007 double div = (double)limit / num;
3008 num = limit;
3009 den *= div;
3010 }
3011 else
3012 {
3013 double div = (double)limit / den;
3014 den = limit;
3015 num *= div;
3016 }
3017 *x = num;
3018 *y = den;
3019 }
3020
3021 /**********************************************************************
3022 * hb_reduce64
3023 **********************************************************************
3024 * Given a numerator (num) and a denominator (den), reduce them to an
3025 * equivalent fraction and store the result in x and y.
3026 *********************************************************************/
hb_reduce64(int64_t * x,int64_t * y,int64_t num,int64_t den)3027 void hb_reduce64( int64_t *x, int64_t *y, int64_t num, int64_t den )
3028 {
3029 // find the greatest common divisor of num & den by Euclid's algorithm
3030 int64_t n = num, d = den;
3031 while ( d )
3032 {
3033 int64_t t = d;
3034 d = n % d;
3035 n = t;
3036 }
3037
3038 // at this point n is the gcd. if it's non-zero remove it from num
3039 // and den. Otherwise just return the original values.
3040 if ( n )
3041 {
3042 num /= n;
3043 den /= n;
3044 }
3045
3046 *x = num;
3047 *y = den;
3048
3049 }
3050
hb_limit_rational64(int64_t * x,int64_t * y,int64_t num,int64_t den,int64_t limit)3051 void hb_limit_rational64( int64_t *x, int64_t *y, int64_t num, int64_t den, int64_t limit )
3052 {
3053 hb_reduce64( &num, &den, num, den );
3054 if ( num < limit && den < limit )
3055 {
3056 *x = num;
3057 *y = den;
3058 return;
3059 }
3060
3061 if ( num > den )
3062 {
3063 double div = (double)limit / num;
3064 num = limit;
3065 den *= div;
3066 }
3067 else
3068 {
3069 double div = (double)limit / den;
3070 den = limit;
3071 num *= div;
3072 }
3073 *x = num;
3074 *y = den;
3075 }
3076
3077 /**********************************************************************
3078 * hb_buffer_list implementation
3079 *********************************************************************/
hb_buffer_list_append(hb_buffer_list_t * list,hb_buffer_t * buf)3080 void hb_buffer_list_append(hb_buffer_list_t *list, hb_buffer_t *buf)
3081 {
3082 int count = 1;
3083 int size = 0;
3084 hb_buffer_t *end = buf;
3085
3086 if (buf == NULL)
3087 {
3088 return;
3089 }
3090
3091 // Input buffer may be a list of buffers, find the end.
3092 size += buf->size;
3093 while (end != NULL && end->next != NULL)
3094 {
3095 end = end->next;
3096 size += end->size;
3097 count++;
3098 }
3099 if (list->tail == NULL)
3100 {
3101 list->head = buf;
3102 list->tail = end;
3103 }
3104 else
3105 {
3106 list->tail->next = buf;
3107 list->tail = end;
3108 }
3109 list->count += count;
3110 list->size += size;
3111 }
3112
hb_buffer_list_prepend(hb_buffer_list_t * list,hb_buffer_t * buf)3113 void hb_buffer_list_prepend(hb_buffer_list_t *list, hb_buffer_t *buf)
3114 {
3115 int count = 1;
3116 int size = 0;
3117 hb_buffer_t *end = buf;
3118
3119 if (buf == NULL)
3120 {
3121 return;
3122 }
3123
3124 // Input buffer may be a list of buffers, find the end.
3125 size += buf->size;
3126 while (end != NULL && end->next != NULL)
3127 {
3128 end = end->next;
3129 size += end->size;
3130 count++;
3131 }
3132 if (list->tail == NULL)
3133 {
3134 list->head = buf;
3135 list->tail = end;
3136 }
3137 else
3138 {
3139 end->next = list->head;
3140 list->head = buf;
3141 }
3142 list->count += count;
3143 list->size += size;
3144 }
3145
hb_buffer_list_rem_head(hb_buffer_list_t * list)3146 hb_buffer_t* hb_buffer_list_rem_head(hb_buffer_list_t *list)
3147 {
3148 if (list == NULL)
3149 {
3150 return NULL;
3151 }
3152 hb_buffer_t *head = list->head;
3153 if (list->head != NULL)
3154 {
3155 if (list->head == list->tail)
3156 {
3157 list->tail = NULL;
3158 }
3159 list->head = list->head->next;
3160 list->count--;
3161 list->size -= head->size;
3162 }
3163 if (head != NULL)
3164 {
3165 head->next = NULL;
3166 }
3167 return head;
3168 }
3169
hb_buffer_list_rem_tail(hb_buffer_list_t * list)3170 hb_buffer_t* hb_buffer_list_rem_tail(hb_buffer_list_t *list)
3171 {
3172 if (list == NULL)
3173 {
3174 return NULL;
3175 }
3176 hb_buffer_t *tail = list->tail;
3177
3178 if (list->head == list->tail)
3179 {
3180 list->head = list->tail = NULL;
3181 list->count = 0;
3182 list->size = 0;
3183 }
3184 else if (list->tail != NULL)
3185 {
3186 hb_buffer_t *end = list->head;
3187 while (end->next != list->tail)
3188 {
3189 end = end->next;
3190 }
3191 end->next = NULL;
3192 list->tail = end;
3193 list->count--;
3194 list->size -= tail->size;
3195 }
3196 if (tail != NULL)
3197 {
3198 tail->next = NULL;
3199 }
3200 return tail;
3201 }
3202
hb_buffer_list_rem(hb_buffer_list_t * list,hb_buffer_t * b)3203 hb_buffer_t* hb_buffer_list_rem(hb_buffer_list_t *list, hb_buffer_t * b)
3204 {
3205 hb_buffer_t * a;
3206
3207 if (list == NULL)
3208 {
3209 return NULL;
3210 }
3211 if (b == list->head)
3212 {
3213 return hb_buffer_list_rem_head(list);
3214 }
3215 a = list->head;
3216 while (a != NULL && a->next != b)
3217 {
3218 a = a->next;
3219 }
3220 if (a == NULL)
3221 {
3222 // Buffer is not in the list
3223 return NULL;
3224 }
3225 list->count--;
3226 list->size -= b->size;
3227 a->next = b->next;
3228 if (list->tail == b)
3229 {
3230 list->tail = a;
3231 }
3232 b->next = NULL;
3233
3234 return b;
3235 }
3236
hb_buffer_list_head(hb_buffer_list_t * list)3237 hb_buffer_t* hb_buffer_list_head(hb_buffer_list_t *list)
3238 {
3239 if (list == NULL)
3240 {
3241 return NULL;
3242 }
3243 return list->head;
3244 }
3245
hb_buffer_list_tail(hb_buffer_list_t * list)3246 hb_buffer_t* hb_buffer_list_tail(hb_buffer_list_t *list)
3247 {
3248 if (list == NULL)
3249 {
3250 return NULL;
3251 }
3252 return list->tail;
3253 }
3254
hb_buffer_list_set(hb_buffer_list_t * list,hb_buffer_t * buf)3255 hb_buffer_t* hb_buffer_list_set(hb_buffer_list_t *list, hb_buffer_t *buf)
3256 {
3257 int count = 0;
3258 int size = 0;
3259
3260 if (list == NULL)
3261 {
3262 return NULL;
3263 }
3264
3265 hb_buffer_t *head = list->head;
3266 hb_buffer_t *end = buf;
3267 if (end != NULL)
3268 {
3269 count++;
3270 size += end->size;
3271 while (end->next != NULL)
3272 {
3273 end = end->next;
3274 count++;
3275 size += end->size;
3276 }
3277 }
3278 list->head = buf;
3279 list->tail = end;
3280 list->count = count;
3281 list->size = size;
3282 return head;
3283 }
3284
hb_buffer_list_clear(hb_buffer_list_t * list)3285 hb_buffer_t* hb_buffer_list_clear(hb_buffer_list_t *list)
3286 {
3287 if (list == NULL)
3288 {
3289 return NULL;
3290 }
3291 hb_buffer_t *head = list->head;
3292 list->head = list->tail = NULL;
3293 list->count = 0;
3294 list->size = 0;
3295 return head;
3296 }
3297
hb_buffer_list_close(hb_buffer_list_t * list)3298 void hb_buffer_list_close(hb_buffer_list_t *list)
3299 {
3300 hb_buffer_t *buf = hb_buffer_list_clear(list);
3301 hb_buffer_close(&buf);
3302 }
3303
hb_buffer_list_count(hb_buffer_list_t * list)3304 int hb_buffer_list_count(hb_buffer_list_t *list)
3305 {
3306 if (list == NULL) return 0;
3307 return list->count;
3308 }
3309
hb_buffer_list_size(hb_buffer_list_t * list)3310 int hb_buffer_list_size(hb_buffer_list_t *list)
3311 {
3312 return list->size;
3313 }
3314
3315 /**********************************************************************
3316 * hb_list implementation
3317 **********************************************************************
3318 * Basic and slow, but enough for what we need
3319 *********************************************************************/
3320
3321 #define HB_LIST_DEFAULT_SIZE 20
3322
3323 struct hb_list_s
3324 {
3325 /* Pointers to items in the list */
3326 void ** items;
3327
3328 /* How many (void *) allocated in 'items' */
3329 int items_alloc;
3330
3331 /* How many valid pointers in 'items' */
3332 int items_count;
3333 };
3334
3335 /**********************************************************************
3336 * hb_list_init
3337 **********************************************************************
3338 * Allocates an empty list ready for HB_LIST_DEFAULT_SIZE items
3339 *********************************************************************/
hb_list_init()3340 hb_list_t * hb_list_init()
3341 {
3342 hb_list_t * l;
3343
3344 l = calloc( sizeof( hb_list_t ), 1 );
3345 l->items = calloc( HB_LIST_DEFAULT_SIZE * sizeof( void * ), 1 );
3346 l->items_alloc = HB_LIST_DEFAULT_SIZE;
3347
3348 return l;
3349 }
3350
3351 /**********************************************************************
3352 * hb_list_count
3353 **********************************************************************
3354 * Returns the number of items currently in the list
3355 *********************************************************************/
hb_list_count(const hb_list_t * l)3356 int hb_list_count( const hb_list_t * l )
3357 {
3358 if (l == NULL) return 0;
3359 return l->items_count;
3360 }
3361
3362 /**********************************************************************
3363 * hb_list_add
3364 **********************************************************************
3365 * Adds an item at the end of the list, making it bigger if necessary.
3366 * Can safely be called with a NULL pointer to add, it will be ignored.
3367 *********************************************************************/
hb_list_add(hb_list_t * l,void * p)3368 void hb_list_add( hb_list_t * l, void * p )
3369 {
3370 if( !p )
3371 {
3372 return;
3373 }
3374
3375 if( l->items_count == l->items_alloc )
3376 {
3377 /* We need a bigger boat */
3378 l->items_alloc += HB_LIST_DEFAULT_SIZE;
3379 l->items = realloc( l->items,
3380 l->items_alloc * sizeof( void * ) );
3381 }
3382
3383 l->items[l->items_count] = p;
3384 (l->items_count)++;
3385 }
3386
3387 /**********************************************************************
3388 * hb_list_insert
3389 **********************************************************************
3390 * Adds an item at the specified position in the list, making it bigger
3391 * if necessary.
3392 * Can safely be called with a NULL pointer to add, it will be ignored.
3393 *********************************************************************/
hb_list_insert(hb_list_t * l,int pos,void * p)3394 void hb_list_insert( hb_list_t * l, int pos, void * p )
3395 {
3396 if( !p )
3397 {
3398 return;
3399 }
3400
3401 if( l->items_count == l->items_alloc )
3402 {
3403 /* We need a bigger boat */
3404 l->items_alloc += HB_LIST_DEFAULT_SIZE;
3405 l->items = realloc( l->items,
3406 l->items_alloc * sizeof( void * ) );
3407 }
3408
3409 if ( l->items_count != pos )
3410 {
3411 /* Shift all items after it sizeof( void * ) bytes earlier */
3412 memmove( &l->items[pos+1], &l->items[pos],
3413 ( l->items_count - pos ) * sizeof( void * ) );
3414 }
3415
3416
3417 l->items[pos] = p;
3418 (l->items_count)++;
3419 }
3420
3421 /**********************************************************************
3422 * hb_list_rem
3423 **********************************************************************
3424 * Remove an item from the list. Bad things will happen if called
3425 * with a NULL pointer or if the item is not in the list.
3426 *********************************************************************/
hb_list_rem(hb_list_t * l,void * p)3427 void hb_list_rem( hb_list_t * l, void * p )
3428 {
3429 int i;
3430
3431 /* Find the item in the list */
3432 for( i = 0; i < l->items_count; i++ )
3433 {
3434 if( l->items[i] == p )
3435 {
3436 /* Shift all items after it sizeof( void * ) bytes earlier */
3437 memmove( &l->items[i], &l->items[i+1],
3438 ( l->items_count - i - 1 ) * sizeof( void * ) );
3439
3440 (l->items_count)--;
3441 break;
3442 }
3443 }
3444 }
3445
3446 /**********************************************************************
3447 * hb_list_item
3448 **********************************************************************
3449 * Returns item at position i, or NULL if there are not that many
3450 * items in the list
3451 *********************************************************************/
hb_list_item(const hb_list_t * l,int i)3452 void * hb_list_item( const hb_list_t * l, int i )
3453 {
3454 if( l == NULL || i < 0 || i >= l->items_count )
3455 {
3456 return NULL;
3457 }
3458
3459 return l->items[i];
3460 }
3461
3462 /**********************************************************************
3463 * hb_list_bytes
3464 **********************************************************************
3465 * Assuming all items are of type hb_buffer_t, returns the total
3466 * number of bytes in the list
3467 *********************************************************************/
hb_list_bytes(hb_list_t * l)3468 int hb_list_bytes( hb_list_t * l )
3469 {
3470 hb_buffer_t * buf;
3471 int ret;
3472 int i;
3473
3474 ret = 0;
3475 for( i = 0; i < hb_list_count( l ); i++ )
3476 {
3477 buf = hb_list_item( l, i );
3478 ret += buf->size - buf->offset;
3479 }
3480
3481 return ret;
3482 }
3483
3484 /**********************************************************************
3485 * hb_list_seebytes
3486 **********************************************************************
3487 * Assuming all items are of type hb_buffer_t, copy <size> bytes from
3488 * the list to <dst>, keeping the list unmodified.
3489 *********************************************************************/
hb_list_seebytes(hb_list_t * l,uint8_t * dst,int size)3490 void hb_list_seebytes( hb_list_t * l, uint8_t * dst, int size )
3491 {
3492 hb_buffer_t * buf;
3493 int copied;
3494 int copying;
3495 int i;
3496
3497 for( i = 0, copied = 0; copied < size; i++ )
3498 {
3499 buf = hb_list_item( l, i );
3500 copying = MIN( buf->size - buf->offset, size - copied );
3501 memcpy( &dst[copied], &buf->data[buf->offset], copying );
3502 copied += copying;
3503 }
3504 }
3505
3506 /**********************************************************************
3507 * hb_list_getbytes
3508 **********************************************************************
3509 * Assuming all items are of type hb_buffer_t, copy <size> bytes from
3510 * the list to <dst>. What's copied is removed from the list.
3511 * The variable pointed by <pts> is set to the PTS of the buffer the
3512 * first byte has been got from.
3513 * The variable pointed by <pos> is set to the position of that byte
3514 * in that buffer.
3515 *********************************************************************/
hb_list_getbytes(hb_list_t * l,uint8_t * dst,int size,uint64_t * pts,uint64_t * pos)3516 void hb_list_getbytes( hb_list_t * l, uint8_t * dst, int size,
3517 uint64_t * pts, uint64_t * pos )
3518 {
3519 hb_buffer_t * buf;
3520 int copied;
3521 int copying;
3522 uint8_t has_pts;
3523
3524 /* So we won't have to deal with NULL pointers */
3525 uint64_t dummy1, dummy2;
3526
3527 if( !pts ) pts = &dummy1;
3528 if( !pos ) pos = &dummy2;
3529
3530 for( copied = 0, has_pts = 0; copied < size; )
3531 {
3532 buf = hb_list_item( l, 0 );
3533 copying = MIN( buf->size - buf->offset, size - copied );
3534 memcpy( &dst[copied], &buf->data[buf->offset], copying );
3535
3536 if( !has_pts )
3537 {
3538 *pts = buf->s.start;
3539 *pos = buf->offset;
3540 has_pts = 1;
3541 }
3542
3543 buf->offset += copying;
3544 if( buf->offset >= buf->size )
3545 {
3546 hb_list_rem( l, buf );
3547 hb_buffer_close( &buf );
3548 }
3549
3550 copied += copying;
3551 }
3552 }
3553
3554 /**********************************************************************
3555 * hb_list_empty
3556 **********************************************************************
3557 * Assuming all items are of type hb_buffer_t, close them all and
3558 * close the list.
3559 *********************************************************************/
hb_list_empty(hb_list_t ** _l)3560 void hb_list_empty( hb_list_t ** _l )
3561 {
3562 hb_list_t * l = *_l;
3563 hb_buffer_t * b;
3564
3565 while( ( b = hb_list_item( l, 0 ) ) )
3566 {
3567 hb_list_rem( l, b );
3568 hb_buffer_close( &b );
3569 }
3570
3571 hb_list_close( _l );
3572 }
3573
3574 /**********************************************************************
3575 * hb_list_close
3576 **********************************************************************
3577 * Free memory allocated by hb_list_init. Does NOT free contents of
3578 * items still in the list.
3579 *********************************************************************/
hb_list_close(hb_list_t ** _l)3580 void hb_list_close( hb_list_t ** _l )
3581 {
3582 hb_list_t * l = *_l;
3583
3584 if (l == NULL)
3585 {
3586 return;
3587 }
3588
3589 free( l->items );
3590 free( l );
3591
3592 *_l = NULL;
3593 }
3594
3595 int global_verbosity_level; //Necessary for hb_deep_log
3596 /**********************************************************************
3597 * hb_valog
3598 **********************************************************************
3599 * If verbose mode is one, print message with timestamp. Messages
3600 * longer than 180 characters are stripped ;p
3601 *********************************************************************/
hb_valog(hb_debug_level_t level,const char * prefix,const char * log,va_list args)3602 void hb_valog( hb_debug_level_t level, const char * prefix, const char * log, va_list args)
3603 {
3604 char * string;
3605 time_t _now;
3606 struct tm * now;
3607 char preamble[362];
3608
3609 if( global_verbosity_level < level )
3610 {
3611 /* Hiding message */
3612 return;
3613 }
3614
3615 /* Get the time */
3616 _now = time( NULL );
3617 now = localtime( &_now );
3618 if ( prefix && *prefix )
3619 {
3620 // limit the prefix length
3621 snprintf( preamble, 361, "[%02d:%02d:%02d] %s %s\n",
3622 now->tm_hour, now->tm_min, now->tm_sec, prefix, log );
3623 }
3624 else
3625 {
3626 snprintf( preamble, 361, "[%02d:%02d:%02d] %s\n",
3627 now->tm_hour, now->tm_min, now->tm_sec, log );
3628 }
3629
3630 string = hb_strdup_vaprintf(preamble, args);
3631
3632 #ifdef SYS_MINGW
3633 wchar_t *wstring; /* 360 chars + \n + \0 */
3634 int len;
3635
3636 len = strlen(string) + 1;
3637 wstring = malloc(2 * len);
3638
3639 // Convert internal utf8 to "console output code page".
3640 //
3641 // This is just bizarre windows behavior. You would expect that
3642 // printf would automatically convert a wide character string to
3643 // the current "console output code page" when using the "%ls" format
3644 // specifier. But it doesn't... so we must do it.
3645 if (!MultiByteToWideChar(CP_UTF8, 0, string, -1, wstring, len))
3646 {
3647 free(string);
3648 free(wstring);
3649 return;
3650 }
3651 free(string);
3652 string = malloc(2 * len);
3653 if (!WideCharToMultiByte(GetConsoleOutputCP(), 0, wstring, -1, string, len,
3654 NULL, NULL))
3655 {
3656 free(string);
3657 free(wstring);
3658 return;
3659 }
3660 free(wstring);
3661 #endif
3662
3663 /* Print it */
3664 fprintf( stderr, "%s", string );
3665 free(string);
3666 }
3667
3668 /**********************************************************************
3669 * hb_log
3670 **********************************************************************
3671 * If verbose mode is one, print message with timestamp. Messages
3672 * longer than 180 characters are stripped ;p
3673 *********************************************************************/
hb_log(char * log,...)3674 void hb_log( char * log, ... )
3675 {
3676 va_list args;
3677
3678 va_start( args, log );
3679 hb_valog( 0, NULL, log, args );
3680 va_end( args );
3681 }
3682
3683 /**********************************************************************
3684 * hb_deep_log
3685 **********************************************************************
3686 * If verbose mode is >= level, print message with timestamp. Messages
3687 * longer than 360 characters are stripped ;p
3688 *********************************************************************/
hb_deep_log(hb_debug_level_t level,char * log,...)3689 void hb_deep_log( hb_debug_level_t level, char * log, ... )
3690 {
3691 va_list args;
3692
3693 va_start( args, log );
3694 hb_valog( level, NULL, log, args );
3695 va_end( args );
3696 }
3697
3698 /**********************************************************************
3699 * hb_error
3700 **********************************************************************
3701 * Using whatever output is available display this error.
3702 *********************************************************************/
hb_error(char * log,...)3703 void hb_error( char * log, ... )
3704 {
3705 char string[181]; /* 180 chars + \0 */
3706 char rep_string[181];
3707 static char last_string[181];
3708 static int last_error_count = 0;
3709 static uint64_t last_series_error_time = 0;
3710 static hb_lock_t *mutex = 0;
3711 va_list args;
3712 uint64_t time_now;
3713
3714 /* Convert the message to a string */
3715 va_start( args, log );
3716 vsnprintf( string, 180, log, args );
3717 va_end( args );
3718
3719 if( !mutex )
3720 {
3721 mutex = hb_lock_init();
3722 }
3723
3724 hb_lock( mutex );
3725
3726 time_now = hb_get_date();
3727
3728 if( strcmp( string, last_string) == 0 )
3729 {
3730 /*
3731 * The last error and this one are the same, don't log it
3732 * just count it instead, unless it was more than one second
3733 * ago.
3734 */
3735 last_error_count++;
3736 if( last_series_error_time + ( 1000 * 1 ) > time_now )
3737 {
3738 hb_unlock( mutex );
3739 return;
3740 }
3741 }
3742
3743 /*
3744 * A new error, or the same one more than 10sec since the last one
3745 * did we have any of the same counted up?
3746 */
3747 if( last_error_count > 0 )
3748 {
3749 /*
3750 * Print out the last error to ensure context for the last
3751 * repeated message.
3752 */
3753 if( error_handler )
3754 {
3755 error_handler( last_string );
3756 } else {
3757 hb_log( "%s", last_string );
3758 }
3759
3760 if( last_error_count > 1 )
3761 {
3762 /*
3763 * Only print out the repeat message for more than 2 of the
3764 * same, since we just printed out two of them already.
3765 */
3766 snprintf( rep_string, 180, "Last error repeated %d times",
3767 last_error_count - 1 );
3768
3769 if( error_handler )
3770 {
3771 error_handler( rep_string );
3772 } else {
3773 hb_log( "%s", rep_string );
3774 }
3775 }
3776
3777 last_error_count = 0;
3778 }
3779
3780 last_series_error_time = time_now;
3781
3782 strcpy( last_string, string );
3783
3784 /*
3785 * Got the error in a single string, send it off to be dispatched.
3786 */
3787 if( error_handler )
3788 {
3789 error_handler( string );
3790 } else {
3791 hb_log( "%s", string );
3792 }
3793
3794 hb_unlock( mutex );
3795 }
3796
hb_register_error_handler(hb_error_handler_t * handler)3797 void hb_register_error_handler( hb_error_handler_t * handler )
3798 {
3799 error_handler = handler;
3800 }
3801
hb_update_str(char ** dst,const char * src)3802 static void hb_update_str( char **dst, const char *src )
3803 {
3804 if ( dst )
3805 {
3806 free( *dst );
3807 *dst = NULL;
3808 if ( src )
3809 {
3810 *dst = strdup( src );
3811 }
3812 }
3813 }
3814
3815 /**********************************************************************
3816 * hb_title_init
3817 **********************************************************************
3818 *
3819 *********************************************************************/
hb_title_init(char * path,int index)3820 hb_title_t * hb_title_init( char * path, int index )
3821 {
3822 hb_title_t * t;
3823
3824 t = calloc( sizeof( hb_title_t ), 1 );
3825
3826 t->index = index;
3827 t->playlist = -1;
3828 t->list_audio = hb_list_init();
3829 t->list_chapter = hb_list_init();
3830 t->list_subtitle = hb_list_init();
3831 t->list_attachment = hb_list_init();
3832 t->metadata = hb_metadata_init();
3833 t->path = strdup(path);
3834 // default to decoding mpeg2
3835 t->video_id = 0xE0;
3836 t->video_codec = WORK_DECAVCODECV;
3837 t->video_codec_param = AV_CODEC_ID_MPEG2VIDEO;
3838 t->video_timebase.num = 1;
3839 t->video_timebase.den = 90000;
3840 t->angle_count = 1;
3841 t->geometry.par.num = 0;
3842 t->geometry.par.den = 1;
3843
3844 return t;
3845 }
3846
3847 /**********************************************************************
3848 * hb_title_close
3849 **********************************************************************
3850 *
3851 *********************************************************************/
hb_title_close(hb_title_t ** _t)3852 void hb_title_close( hb_title_t ** _t )
3853 {
3854 hb_title_t * t = *_t;
3855 hb_audio_t * audio;
3856 hb_chapter_t * chapter;
3857 hb_subtitle_t * subtitle;
3858 hb_attachment_t * attachment;
3859
3860 while( ( chapter = hb_list_item( t->list_chapter, 0 ) ) )
3861 {
3862 hb_list_rem( t->list_chapter, chapter );
3863 hb_chapter_close( &chapter );
3864 }
3865 hb_list_close( &t->list_chapter );
3866
3867 while( ( audio = hb_list_item( t->list_audio, 0 ) ) )
3868 {
3869 hb_list_rem( t->list_audio, audio );
3870 hb_audio_close( &audio );
3871 }
3872 hb_list_close( &t->list_audio );
3873
3874 while( ( subtitle = hb_list_item( t->list_subtitle, 0 ) ) )
3875 {
3876 hb_list_rem( t->list_subtitle, subtitle );
3877 hb_subtitle_close( &subtitle );
3878 }
3879 hb_list_close( &t->list_subtitle );
3880
3881 while( ( attachment = hb_list_item( t->list_attachment, 0 ) ) )
3882 {
3883 hb_list_rem( t->list_attachment, attachment );
3884 hb_attachment_close( &attachment );
3885 }
3886 hb_list_close( &t->list_attachment );
3887
3888 hb_metadata_close( &t->metadata );
3889
3890 free((char*)t->name);
3891 free((char*)t->path);
3892 free(t->video_codec_name);
3893 free(t->container_name);
3894
3895 free( t );
3896 *_t = NULL;
3897 }
3898
job_setup(hb_job_t * job,hb_title_t * title)3899 static void job_setup(hb_job_t * job, hb_title_t * title)
3900 {
3901 if ( job == NULL || title == NULL )
3902 return;
3903
3904 job->title = title;
3905
3906 /* Set defaults settings */
3907 job->chapter_start = 1;
3908 job->chapter_end = hb_list_count( title->list_chapter );
3909 job->list_chapter = hb_chapter_list_copy( title->list_chapter );
3910
3911 /* Autocrop by default. Gnark gnark */
3912 memcpy( job->crop, title->crop, 4 * sizeof( int ) );
3913
3914 hb_geometry_t srcGeo, resultGeo;
3915 hb_geometry_settings_t uiGeo;
3916
3917 srcGeo = title->geometry;
3918
3919 memset(&uiGeo, 0, sizeof(uiGeo));
3920 memcpy(uiGeo.crop, title->crop, 4 * sizeof( int ));
3921 uiGeo.geometry.width = srcGeo.width - uiGeo.crop[2] - uiGeo.crop[3];
3922 uiGeo.geometry.height = srcGeo.height - uiGeo.crop[0] - uiGeo.crop[1];
3923 uiGeo.mode = HB_ANAMORPHIC_NONE;
3924 uiGeo.keep = HB_KEEP_DISPLAY_ASPECT;
3925
3926 hb_set_anamorphic_size2(&srcGeo, &uiGeo, &resultGeo);
3927 job->width = resultGeo.width;
3928 job->height = resultGeo.height;
3929 job->par = resultGeo.par;
3930
3931 job->vcodec = HB_VCODEC_FFMPEG_MPEG4;
3932 job->vquality = HB_INVALID_VIDEO_QUALITY;
3933 job->vbitrate = 1000;
3934 job->twopass = 0;
3935 job->pass_id = HB_PASS_ENCODE;
3936 job->vrate = title->vrate;
3937
3938 job->input_pix_fmt = AV_PIX_FMT_YUV420P;
3939 job->output_pix_fmt = AV_PIX_FMT_YUV420P;
3940 job->color_prim = title->color_prim;
3941 job->color_transfer = title->color_transfer;
3942 job->color_matrix = title->color_matrix;
3943 job->color_range = title->color_range;
3944 job->color_prim_override = HB_COLR_PRI_UNDEF;
3945 job->color_transfer_override = HB_COLR_TRA_UNDEF;
3946 job->color_matrix_override = HB_COLR_MAT_UNDEF;
3947 job->mastering = title->mastering;
3948 job->coll = title->coll;
3949
3950 job->mux = HB_MUX_MP4;
3951
3952 job->list_audio = hb_list_init();
3953 job->list_subtitle = hb_list_init();
3954 job->list_filter = hb_list_init();
3955
3956 job->list_attachment = hb_attachment_list_copy( title->list_attachment );
3957 job->metadata = hb_metadata_copy( title->metadata );
3958
3959 #if HB_PROJECT_FEATURE_QSV
3960 job->qsv.ctx = NULL;
3961 if (!job->indepth_scan)
3962 {
3963 job->qsv.ctx = hb_qsv_context_init();
3964 }
3965 job->qsv.enc_info.is_init_done = 0;
3966 job->qsv.decode = !!(title->video_decode_support &
3967 HB_DECODE_SUPPORT_QSV);
3968 #endif
3969 }
3970
hb_output_color_prim(hb_job_t * job)3971 int hb_output_color_prim(hb_job_t * job)
3972 {
3973 if (job->color_prim_override != HB_COLR_PRI_UNDEF)
3974 return job->color_prim_override;
3975 else
3976 return job->color_prim;
3977 }
3978
hb_output_color_transfer(hb_job_t * job)3979 int hb_output_color_transfer(hb_job_t * job)
3980 {
3981 if (job->color_transfer_override != HB_COLR_TRA_UNDEF)
3982 return job->color_transfer_override;
3983 else
3984 return job->color_transfer;
3985 }
3986
hb_output_color_matrix(hb_job_t * job)3987 int hb_output_color_matrix(hb_job_t * job)
3988 {
3989 if (job->color_matrix_override != HB_COLR_MAT_UNDEF)
3990 return job->color_matrix_override;
3991 else
3992 return job->color_matrix;
3993 }
3994
job_clean(hb_job_t * job)3995 static void job_clean( hb_job_t * job )
3996 {
3997 if (job)
3998 {
3999 hb_chapter_t *chapter;
4000 hb_audio_t *audio;
4001 hb_subtitle_t *subtitle;
4002 hb_filter_object_t *filter;
4003 hb_attachment_t *attachment;
4004
4005 free((void*)job->json);
4006 job->json = NULL;
4007 free(job->encoder_preset);
4008 job->encoder_preset = NULL;
4009 free(job->encoder_tune);
4010 job->encoder_tune = NULL;
4011 free(job->encoder_options);
4012 job->encoder_options = NULL;
4013 free(job->encoder_profile);
4014 job->encoder_profile = NULL;
4015 free(job->encoder_level);
4016 job->encoder_level = NULL;
4017 free(job->file);
4018 job->file = NULL;
4019
4020 // clean up chapter list
4021 while( ( chapter = hb_list_item( job->list_chapter, 0 ) ) )
4022 {
4023 hb_list_rem( job->list_chapter, chapter );
4024 hb_chapter_close( &chapter );
4025 }
4026 hb_list_close( &job->list_chapter );
4027
4028 // clean up audio list
4029 while( ( audio = hb_list_item( job->list_audio, 0 ) ) )
4030 {
4031 hb_list_rem( job->list_audio, audio );
4032 hb_audio_close( &audio );
4033 }
4034 hb_list_close( &job->list_audio );
4035
4036 // clean up subtitle list
4037 while( ( subtitle = hb_list_item( job->list_subtitle, 0 ) ) )
4038 {
4039 hb_list_rem( job->list_subtitle, subtitle );
4040 hb_subtitle_close( &subtitle );
4041 }
4042 hb_list_close( &job->list_subtitle );
4043
4044 // clean up filter list
4045 while( ( filter = hb_list_item( job->list_filter, 0 ) ) )
4046 {
4047 hb_list_rem( job->list_filter, filter );
4048 hb_filter_close( &filter );
4049 }
4050 hb_list_close( &job->list_filter );
4051
4052 // clean up attachment list
4053 while( ( attachment = hb_list_item( job->list_attachment, 0 ) ) )
4054 {
4055 hb_list_rem( job->list_attachment, attachment );
4056 hb_attachment_close( &attachment );
4057 }
4058 hb_list_close( &job->list_attachment );
4059
4060 // clean up metadata
4061 hb_metadata_close( &job->metadata );
4062 }
4063 }
4064
hb_find_title_by_index(hb_handle_t * h,int title_index)4065 hb_title_t * hb_find_title_by_index( hb_handle_t *h, int title_index )
4066 {
4067 hb_title_set_t *title_set = hb_get_title_set( h );
4068 int ii;
4069
4070 for (ii = 0; ii < hb_list_count(title_set->list_title); ii++)
4071 {
4072 hb_title_t *title = hb_list_item(title_set->list_title, ii);
4073 if (title_index == title->index)
4074 {
4075 return title;
4076 }
4077 }
4078 return NULL;
4079 }
4080
4081 /*
4082 * Create a pristine job structure from a title
4083 * title_index is 1 based
4084 */
hb_job_init_by_index(hb_handle_t * h,int title_index)4085 hb_job_t * hb_job_init_by_index( hb_handle_t * h, int title_index )
4086 {
4087 hb_title_t * title = hb_find_title_by_index(h, title_index);
4088 if (title == NULL)
4089 return NULL;
4090 return hb_job_init(title);
4091 }
4092
hb_job_init(hb_title_t * title)4093 hb_job_t * hb_job_init( hb_title_t * title )
4094 {
4095 hb_job_t * job;
4096
4097 if ( title == NULL )
4098 return NULL;
4099
4100 job = calloc( sizeof( hb_job_t ), 1 );
4101 job_setup(job, title);
4102
4103 return job;
4104 }
4105
4106 /**********************************************************************
4107 * hb_job_close
4108 **********************************************************************
4109 *
4110 *********************************************************************/
hb_job_close(hb_job_t ** _j)4111 void hb_job_close( hb_job_t ** _j )
4112 {
4113 if (_j && *_j)
4114 {
4115 job_clean(*_j);
4116 free( *_j );
4117 _j = NULL;
4118 }
4119 }
4120
hb_job_set_encoder_preset(hb_job_t * job,const char * preset)4121 void hb_job_set_encoder_preset(hb_job_t *job, const char *preset)
4122 {
4123 if (job != NULL)
4124 {
4125 if (preset == NULL || preset[0] == 0)
4126 {
4127 preset = NULL;
4128 }
4129 hb_update_str(&job->encoder_preset, preset);
4130 }
4131 }
4132
hb_job_set_encoder_tune(hb_job_t * job,const char * tune)4133 void hb_job_set_encoder_tune(hb_job_t *job, const char *tune)
4134 {
4135 if (job != NULL)
4136 {
4137 if (tune == NULL || tune[0] == 0)
4138 {
4139 tune = NULL;
4140 }
4141 hb_update_str(&job->encoder_tune, tune);
4142 }
4143 }
4144
hb_job_set_encoder_options(hb_job_t * job,const char * options)4145 void hb_job_set_encoder_options(hb_job_t *job, const char *options)
4146 {
4147 if (job != NULL)
4148 {
4149 if (options == NULL || options[0] == 0)
4150 {
4151 options = NULL;
4152 }
4153 hb_update_str(&job->encoder_options, options);
4154 }
4155 }
4156
hb_job_set_encoder_profile(hb_job_t * job,const char * profile)4157 void hb_job_set_encoder_profile(hb_job_t *job, const char *profile)
4158 {
4159 if (job != NULL)
4160 {
4161 if (profile == NULL || profile[0] == 0)
4162 {
4163 profile = NULL;
4164 }
4165 hb_update_str(&job->encoder_profile, profile);
4166 }
4167 }
4168
hb_job_set_encoder_level(hb_job_t * job,const char * level)4169 void hb_job_set_encoder_level(hb_job_t *job, const char *level)
4170 {
4171 if (job != NULL)
4172 {
4173 if (level == NULL || level[0] == 0)
4174 {
4175 level = NULL;
4176 }
4177 hb_update_str(&job->encoder_level, level);
4178 }
4179 }
4180
hb_job_set_file(hb_job_t * job,const char * file)4181 void hb_job_set_file(hb_job_t *job, const char *file)
4182 {
4183 if (job != NULL)
4184 {
4185 hb_update_str(&job->file, file);
4186 }
4187 }
4188
hb_filter_copy(hb_filter_object_t * filter)4189 hb_filter_object_t * hb_filter_copy( hb_filter_object_t * filter )
4190 {
4191 if( filter == NULL )
4192 return NULL;
4193
4194 hb_filter_object_t * filter_copy = malloc( sizeof( hb_filter_object_t ) );
4195 memcpy( filter_copy, filter, sizeof( hb_filter_object_t ) );
4196 if( filter->settings )
4197 filter_copy->settings = hb_value_dup(filter->settings);
4198 filter_copy->sub_filter = hb_filter_copy(filter->sub_filter);
4199 return filter_copy;
4200 }
4201
4202 /**********************************************************************
4203 * hb_filter_list_copy
4204 **********************************************************************
4205 *
4206 *********************************************************************/
hb_filter_list_copy(const hb_list_t * src)4207 hb_list_t *hb_filter_list_copy(const hb_list_t *src)
4208 {
4209 hb_list_t *list = hb_list_init();
4210 hb_filter_object_t *filter = NULL;
4211 int i;
4212
4213 if( src )
4214 {
4215 for( i = 0; i < hb_list_count(src); i++ )
4216 {
4217 if( ( filter = hb_list_item( src, i ) ) )
4218 {
4219 hb_list_add( list, hb_filter_copy(filter) );
4220 }
4221 }
4222 }
4223 return list;
4224 }
4225
hb_filter_dict_find(const hb_value_array_t * list,int filter_id)4226 hb_dict_t * hb_filter_dict_find(const hb_value_array_t * list, int filter_id)
4227 {
4228 hb_dict_t * filter = NULL;
4229 int ii;
4230
4231 if (list == NULL)
4232 {
4233 return NULL;
4234 }
4235 for (ii = 0; ii < hb_value_array_len(list); ii++)
4236 {
4237 filter = hb_value_array_get(list, ii);
4238 if (hb_dict_get_int(filter, "ID") == filter_id)
4239 {
4240 return filter;
4241 }
4242 }
4243
4244 return NULL;
4245 }
4246
hb_filter_find(const hb_list_t * list,int filter_id)4247 hb_filter_object_t * hb_filter_find(const hb_list_t *list, int filter_id)
4248 {
4249 hb_filter_object_t *filter = NULL;
4250 int ii;
4251
4252 if (list == NULL)
4253 {
4254 return NULL;
4255 }
4256 for (ii = 0; ii < hb_list_count(list); ii++)
4257 {
4258 filter = hb_list_item(list, ii);
4259 if (filter->id == filter_id)
4260 {
4261 return filter;
4262 }
4263 }
4264
4265 return NULL;
4266 }
4267
4268 /**
4269 * Gets a filter object with the given type
4270 * @param filter_id The type of filter to get.
4271 * @returns The requested filter object.
4272 */
hb_filter_get(int filter_id)4273 hb_filter_object_t * hb_filter_get( int filter_id )
4274 {
4275 hb_filter_object_t * filter;
4276 switch( filter_id )
4277 {
4278 case HB_FILTER_DETELECINE:
4279 filter = &hb_filter_detelecine;
4280 break;
4281
4282 case HB_FILTER_COMB_DETECT:
4283 filter = &hb_filter_comb_detect;
4284 break;
4285
4286 case HB_FILTER_DECOMB:
4287 filter = &hb_filter_decomb;
4288 break;
4289
4290 case HB_FILTER_DEINTERLACE:
4291 filter = &hb_filter_deinterlace;
4292 break;
4293
4294 case HB_FILTER_COLORSPACE:
4295 filter = &hb_filter_colorspace;
4296 break;
4297
4298 case HB_FILTER_VFR:
4299 filter = &hb_filter_vfr;
4300 break;
4301
4302 case HB_FILTER_DEBLOCK:
4303 filter = &hb_filter_deblock;
4304 break;
4305
4306 case HB_FILTER_DENOISE:
4307 filter = &hb_filter_denoise;
4308 break;
4309
4310 case HB_FILTER_NLMEANS:
4311 filter = &hb_filter_nlmeans;
4312 break;
4313
4314 case HB_FILTER_CHROMA_SMOOTH:
4315 filter = &hb_filter_chroma_smooth;
4316 break;
4317
4318 case HB_FILTER_RENDER_SUB:
4319 filter = &hb_filter_render_sub;
4320 break;
4321
4322 case HB_FILTER_CROP_SCALE:
4323 filter = &hb_filter_crop_scale;
4324 break;
4325
4326 case HB_FILTER_LAPSHARP:
4327 filter = &hb_filter_lapsharp;
4328 break;
4329
4330 case HB_FILTER_UNSHARP:
4331 filter = &hb_filter_unsharp;
4332 break;
4333
4334 case HB_FILTER_AVFILTER:
4335 filter = &hb_filter_avfilter;
4336 break;
4337
4338 case HB_FILTER_PAD:
4339 filter = &hb_filter_pad;
4340 break;
4341
4342 case HB_FILTER_ROTATE:
4343 filter = &hb_filter_rotate;
4344 break;
4345
4346 case HB_FILTER_GRAYSCALE:
4347 filter = &hb_filter_grayscale;
4348 break;
4349
4350 case HB_FILTER_FORMAT:
4351 filter = &hb_filter_format;
4352 break;
4353
4354 #if HB_PROJECT_FEATURE_QSV
4355 case HB_FILTER_QSV:
4356 filter = &hb_filter_qsv;
4357 break;
4358
4359 case HB_FILTER_QSV_PRE:
4360 filter = &hb_filter_qsv_pre;
4361 break;
4362
4363 case HB_FILTER_QSV_POST:
4364 filter = &hb_filter_qsv_post;
4365 break;
4366 #endif
4367
4368 case HB_FILTER_MT_FRAME:
4369 filter = &hb_filter_mt_frame;
4370 break;
4371
4372 default:
4373 filter = NULL;
4374 break;
4375 }
4376 return filter;
4377 }
4378
hb_filter_init(int filter_id)4379 hb_filter_object_t * hb_filter_init( int filter_id )
4380 {
4381 switch (filter_id)
4382 {
4383 case HB_FILTER_UNSHARP:
4384 case HB_FILTER_LAPSHARP:
4385 case HB_FILTER_CHROMA_SMOOTH:
4386 {
4387 hb_filter_object_t * wrapper;
4388
4389 wrapper = hb_filter_copy(hb_filter_get(HB_FILTER_MT_FRAME));
4390 wrapper->sub_filter = hb_filter_copy(hb_filter_get(filter_id));
4391 wrapper->id = filter_id;
4392 wrapper->name = wrapper->sub_filter->name;
4393 return wrapper;
4394 } break;
4395
4396 default:
4397 return hb_filter_copy(hb_filter_get(filter_id));
4398 }
4399 }
4400
4401 /**********************************************************************
4402 * hb_filter_close
4403 **********************************************************************
4404 *
4405 *********************************************************************/
hb_filter_close(hb_filter_object_t ** _f)4406 void hb_filter_close( hb_filter_object_t ** _f )
4407 {
4408 hb_filter_object_t * f = *_f;
4409
4410 if (f == NULL)
4411 {
4412 return;
4413 }
4414 hb_filter_close(&f->sub_filter);
4415 hb_value_free(&f->settings);
4416
4417 free( f );
4418 *_f = NULL;
4419 }
4420
4421 /**********************************************************************
4422 * hb_filter_info_close
4423 **********************************************************************
4424 *
4425 *********************************************************************/
hb_filter_info_close(hb_filter_info_t ** _fi)4426 void hb_filter_info_close( hb_filter_info_t ** _fi )
4427 {
4428 hb_filter_info_t * fi = *_fi;
4429
4430 if (fi != NULL)
4431 {
4432 free(fi->human_readable_desc);
4433 }
4434
4435 free( fi );
4436 *_fi = NULL;
4437 }
4438
append_string(char * dst,const char * src)4439 static char * append_string(char * dst, const char * src)
4440 {
4441 int dst_len = 0, src_len, len;
4442
4443 if (src == NULL)
4444 {
4445 return dst;
4446 }
4447
4448 src_len = len = strlen(src) + 1;
4449 if (dst != NULL)
4450 {
4451 dst_len = strlen(dst);
4452 len += dst_len;
4453 }
4454 char * tmp = realloc(dst, len);
4455 if (tmp == NULL)
4456 {
4457 // Failed to allocate required space
4458 return dst;
4459 }
4460 dst = tmp;
4461 memcpy(dst + dst_len, src, src_len);
4462 return dst;
4463 }
4464
stringify_array(int filter_id,hb_value_array_t * array)4465 static char * stringify_array(int filter_id, hb_value_array_t * array)
4466 {
4467 char * result = strdup("");
4468 int ii;
4469 int len = hb_value_array_len(array);
4470 int first = 1;
4471
4472 if (hb_value_array_len(array) == 0)
4473 {
4474 return result;
4475 }
4476 for (ii = 0; ii < len; ii++)
4477 {
4478 hb_value_t * val = hb_value_array_get(array, ii);
4479 char * str = hb_filter_settings_string(filter_id, val);
4480 if (str != NULL)
4481 {
4482 if (!first)
4483 {
4484 result = append_string(result, ",");
4485 }
4486 first = 0;
4487 if (hb_value_type(val) == HB_VALUE_TYPE_DICT)
4488 {
4489 result = append_string(result, str);
4490 }
4491 else if (hb_value_type(val) == HB_VALUE_TYPE_ARRAY)
4492 {
4493 result = append_string(result, "[");
4494 result = append_string(result, str);
4495 result = append_string(result, "]");
4496 }
4497 else
4498 {
4499 result = append_string(result, str);
4500 }
4501 free(str);
4502 }
4503 }
4504
4505 return result;
4506 }
4507
stringify_dict(int filter_id,hb_dict_t * dict)4508 static char * stringify_dict(int filter_id, hb_dict_t * dict)
4509 {
4510 char * result = strdup("");
4511 const char * key;
4512 char ** keys = NULL;
4513 hb_value_t * val;
4514 hb_dict_iter_t iter;
4515 int first = 1;
4516
4517 if (hb_dict_elements(dict) == 0)
4518 {
4519 return result;
4520 }
4521 // Check for dict containing rational value
4522 if (hb_dict_elements(dict) == 2)
4523 {
4524 hb_value_t *num_val = hb_dict_get(dict, "Num");
4525 hb_value_t *den_val = hb_dict_get(dict, "Den");
4526 if (num_val != NULL && den_val != NULL &&
4527 hb_value_type(num_val) == HB_VALUE_TYPE_INT &&
4528 hb_value_type(den_val) == HB_VALUE_TYPE_INT)
4529 {
4530 int num = hb_value_get_int(num_val);
4531 int den = hb_value_get_int(den_val);
4532 char * str = hb_strdup_printf("%d/%d", num, den);
4533 result = append_string(result, str);
4534 free(str);
4535 return result;
4536 }
4537 }
4538 hb_filter_object_t * filter = hb_filter_get(filter_id);
4539 if (filter != NULL)
4540 {
4541 keys = hb_filter_get_keys(filter_id);
4542 if (keys != NULL && keys[0] == NULL)
4543 {
4544 hb_str_vfree(keys);
4545 keys = NULL;
4546 }
4547 }
4548
4549 int done, ii = 0;
4550 iter = hb_dict_iter_init(dict);
4551 if (keys == NULL)
4552 {
4553 done = !hb_dict_iter_next_ex(dict, &iter, &key, NULL);
4554 }
4555 else
4556 {
4557 done = (key = keys[ii]) == NULL;
4558 }
4559 while (!done)
4560 {
4561 val = hb_dict_get(dict, key);
4562 if (val != NULL)
4563 {
4564 if (!first)
4565 {
4566 result = append_string(result, ":");
4567 }
4568 first = 0;
4569 result = append_string(result, key);
4570 int elements = 1;
4571
4572 if (hb_value_type(val) == HB_VALUE_TYPE_NULL)
4573 {
4574 elements = 0;
4575 }
4576 else if (hb_value_type(val) == HB_VALUE_TYPE_DICT)
4577 {
4578 elements = hb_dict_elements(val);
4579 }
4580 else if (hb_value_type(val) == HB_VALUE_TYPE_ARRAY)
4581 {
4582 elements = hb_value_array_len(val);
4583 }
4584 if (elements != 0)
4585 {
4586 char * str = hb_filter_settings_string(filter_id, val);
4587 if (str != NULL)
4588 {
4589 result = append_string(result, "=");
4590 if (hb_value_type(val) == HB_VALUE_TYPE_DICT)
4591 {
4592 result = append_string(result, "'");
4593 result = append_string(result, str);
4594 result = append_string(result, "'");
4595 }
4596 else if (hb_value_type(val) == HB_VALUE_TYPE_ARRAY)
4597 {
4598 result = append_string(result, "[");
4599 result = append_string(result, str);
4600 result = append_string(result, "]");
4601 }
4602 else
4603 {
4604 result = append_string(result, str);
4605 }
4606 free(str);
4607 }
4608 }
4609 }
4610 ii++;
4611 if (keys == NULL)
4612 {
4613 done = !hb_dict_iter_next_ex(dict, &iter, &key, NULL);
4614 }
4615 else
4616 {
4617 done = (key = keys[ii]) == NULL;
4618 }
4619 }
4620 hb_str_vfree(keys);
4621
4622 return result;
4623 }
4624
hb_filter_settings_string(int filter_id,hb_value_t * value)4625 char * hb_filter_settings_string(int filter_id, hb_value_t * value)
4626 {
4627 if (value == NULL || hb_value_type(value) == HB_VALUE_TYPE_NULL)
4628 {
4629 return strdup("");
4630 }
4631 if (hb_value_type(value) == HB_VALUE_TYPE_DICT)
4632 {
4633 return stringify_dict(filter_id, value);
4634 }
4635 if (hb_value_type(value) == HB_VALUE_TYPE_ARRAY)
4636 {
4637 return stringify_array(filter_id, value);
4638 }
4639 return hb_value_get_string_xform(value);
4640 }
4641
hb_filter_settings_string_json(int filter_id,const char * json)4642 char * hb_filter_settings_string_json(int filter_id, const char * json)
4643 {
4644 hb_value_t * value = hb_value_json(json);
4645 char * result = hb_filter_settings_string(filter_id, value);
4646 hb_value_free(&value);
4647
4648 return result;
4649 }
4650
hb_parse_filter_settings(const char * settings_str)4651 hb_dict_t * hb_parse_filter_settings(const char * settings_str)
4652 {
4653 hb_dict_t * dict = hb_dict_init();
4654 char ** settings_list = hb_str_vsplit(settings_str, ':');
4655 int ii;
4656
4657 for (ii = 0; settings_list[ii] != NULL; ii++)
4658 {
4659 char * key, * value;
4660 char ** settings_pair = hb_str_vsplit(settings_list[ii], '=');
4661 if (settings_pair[0] == NULL || settings_pair[1] == NULL)
4662 {
4663 // Parse error. Not key=value pair.
4664 hb_str_vfree(settings_list);
4665 hb_str_vfree(settings_pair);
4666 hb_value_free(&dict);
4667 hb_log("hb_parse_filter_settings: Error parsing (%s)",
4668 settings_str);
4669 return NULL;
4670 }
4671 key = settings_pair[0];
4672 value = settings_pair[1];
4673
4674 int last = strlen(value) - 1;
4675 // Check if value was quoted dictionary and remove quotes
4676 // and parse the sub-dictionary. This should only happen
4677 // for avfilter settings.
4678 if (last > 0 && value[0] == '\'' && value[last] == '\'')
4679 {
4680 char * str = strdup(value + 1);
4681 str[last - 1] = 0;
4682 hb_dict_t * sub_dict = hb_parse_filter_settings(str);
4683 free(str);
4684 if (sub_dict == NULL)
4685 {
4686 // Parse error. Not key=value pair.
4687 hb_str_vfree(settings_list);
4688 hb_str_vfree(settings_pair);
4689 hb_value_free(&dict);
4690 hb_log("hb_parse_filter_settings: Error parsing (%s)",
4691 settings_str);
4692 return NULL;
4693 }
4694 hb_dict_case_set(dict, key, sub_dict);
4695 }
4696 // Check if value was quoted string and remove quotes
4697 else if (last > 0 && value[0] == '"' && value[last] == '"')
4698 {
4699 char * str = strdup(value + 1);
4700 str[last - 1] = 0;
4701 hb_dict_case_set(dict, key, hb_value_string(str));
4702 free(str);
4703 }
4704 else
4705 {
4706 hb_dict_case_set(dict, key, hb_value_string(value));
4707 }
4708
4709 hb_str_vfree(settings_pair);
4710 }
4711 hb_str_vfree(settings_list);
4712
4713 return dict;
4714 }
4715
hb_parse_filter_settings_json(const char * settings_str)4716 char * hb_parse_filter_settings_json(const char * settings_str)
4717 {
4718 hb_dict_t * dict = hb_parse_filter_settings(settings_str);
4719 char * result = hb_value_get_json(dict);
4720 hb_value_free(&dict);
4721
4722 return result;
4723 }
4724
4725 /**********************************************************************
4726 * hb_chapter_copy
4727 **********************************************************************
4728 *
4729 *********************************************************************/
hb_chapter_copy(const hb_chapter_t * src)4730 hb_chapter_t *hb_chapter_copy(const hb_chapter_t *src)
4731 {
4732 hb_chapter_t *chap = NULL;
4733
4734 if ( src )
4735 {
4736 chap = calloc( 1, sizeof(*chap) );
4737 memcpy( chap, src, sizeof(*chap) );
4738 if ( src->title )
4739 {
4740 chap->title = strdup( src->title );
4741 }
4742 }
4743 return chap;
4744 }
4745
4746 /**********************************************************************
4747 * hb_chapter_list_copy
4748 **********************************************************************
4749 *
4750 *********************************************************************/
hb_chapter_list_copy(const hb_list_t * src)4751 hb_list_t *hb_chapter_list_copy(const hb_list_t *src)
4752 {
4753 hb_list_t *list = hb_list_init();
4754 hb_chapter_t *chapter = NULL;
4755 int i;
4756
4757 if( src )
4758 {
4759 for( i = 0; i < hb_list_count(src); i++ )
4760 {
4761 if( ( chapter = hb_list_item( src, i ) ) )
4762 {
4763 hb_list_add( list, hb_chapter_copy(chapter) );
4764 }
4765 }
4766 }
4767 return list;
4768 }
4769
4770 /**********************************************************************
4771 * hb_chapter_close
4772 **********************************************************************
4773 *
4774 *********************************************************************/
hb_chapter_close(hb_chapter_t ** chap)4775 void hb_chapter_close(hb_chapter_t **chap)
4776 {
4777 if ( chap && *chap )
4778 {
4779 free((*chap)->title);
4780 free(*chap);
4781 *chap = NULL;
4782 }
4783 }
4784
4785 /**********************************************************************
4786 * hb_chapter_set_title
4787 **********************************************************************
4788 *
4789 *********************************************************************/
hb_chapter_set_title(hb_chapter_t * chapter,const char * title)4790 void hb_chapter_set_title( hb_chapter_t *chapter, const char *title )
4791 {
4792 if ( chapter )
4793 {
4794 hb_update_str( &chapter->title, title );
4795 }
4796 }
4797
4798 /**********************************************************************
4799 * hb_chapter_set_title_by_index
4800 **********************************************************************
4801 * Applies information from the given job to the official job instance.
4802 * @param job Handle to hb_job_t.
4803 * @param chapter The chapter to apply the name to (1-based).
4804 * @param title to apply.
4805 *********************************************************************/
hb_chapter_set_title_by_index(hb_job_t * job,int chapter_index,const char * title)4806 void hb_chapter_set_title_by_index( hb_job_t * job, int chapter_index, const char * title )
4807 {
4808 hb_chapter_t * chapter = hb_list_item( job->list_chapter, chapter_index - 1 );
4809 hb_chapter_set_title( chapter, title );
4810 }
4811
4812 /**********************************************************************
4813 * hb_audio_copy
4814 **********************************************************************
4815 *
4816 *********************************************************************/
hb_audio_copy(const hb_audio_t * src)4817 hb_audio_t *hb_audio_copy(const hb_audio_t *src)
4818 {
4819 hb_audio_t *audio = NULL;
4820
4821 if( src )
4822 {
4823 audio = calloc(1, sizeof(*audio));
4824 memcpy(audio, src, sizeof(*audio));
4825 if ( src->config.out.name )
4826 {
4827 audio->config.out.name = strdup(src->config.out.name);
4828 }
4829 if ( src->config.in.name )
4830 {
4831 audio->config.in.name = strdup(src->config.in.name);
4832 }
4833 }
4834 return audio;
4835 }
4836
4837 /**********************************************************************
4838 * hb_audio_list_copy
4839 **********************************************************************
4840 *
4841 *********************************************************************/
hb_audio_list_copy(const hb_list_t * src)4842 hb_list_t *hb_audio_list_copy(const hb_list_t *src)
4843 {
4844 hb_list_t *list = hb_list_init();
4845 hb_audio_t *audio = NULL;
4846 int i;
4847
4848 if( src )
4849 {
4850 for( i = 0; i < hb_list_count(src); i++ )
4851 {
4852 if( ( audio = hb_list_item( src, i ) ) )
4853 {
4854 hb_list_add( list, hb_audio_copy(audio) );
4855 }
4856 }
4857 }
4858 return list;
4859 }
4860
4861 /**********************************************************************
4862 * hb_audio_close
4863 **********************************************************************
4864 *
4865 *********************************************************************/
hb_audio_close(hb_audio_t ** audio)4866 void hb_audio_close( hb_audio_t **audio )
4867 {
4868 if ( audio && *audio )
4869 {
4870 free((char*)(*audio)->config.in.name);
4871 free((char*)(*audio)->config.out.name);
4872 free(*audio);
4873 *audio = NULL;
4874 }
4875 }
4876
4877 /**********************************************************************
4878 * hb_audio_new
4879 **********************************************************************
4880 *
4881 *********************************************************************/
hb_audio_config_init(hb_audio_config_t * audiocfg)4882 void hb_audio_config_init(hb_audio_config_t * audiocfg)
4883 {
4884 /* Set read-only parameters to invalid values */
4885 audiocfg->in.codec = 0;
4886 audiocfg->in.codec_param = 0;
4887 audiocfg->in.reg_desc = 0;
4888 audiocfg->in.stream_type = 0;
4889 audiocfg->in.substream_type = 0;
4890 audiocfg->in.version = 0;
4891 audiocfg->in.flags = 0;
4892 audiocfg->in.mode = 0;
4893 audiocfg->in.samplerate = -1;
4894 audiocfg->in.sample_bit_depth = 0;
4895 audiocfg->in.samples_per_frame = -1;
4896 audiocfg->in.bitrate = -1;
4897 audiocfg->in.matrix_encoding = AV_MATRIX_ENCODING_NONE;
4898 audiocfg->in.channel_layout = 0;
4899 audiocfg->in.channel_map = NULL;
4900 audiocfg->lang.description[0] = 0;
4901 audiocfg->lang.simple[0] = 0;
4902 audiocfg->lang.iso639_2[0] = 0;
4903
4904 /* Initialize some sensible defaults */
4905 audiocfg->in.track = audiocfg->out.track = 0;
4906 audiocfg->out.codec = hb_audio_encoder_get_default(HB_MUX_MP4); // default container
4907 audiocfg->out.samplerate = -1;
4908 audiocfg->out.samples_per_frame = -1;
4909 audiocfg->out.bitrate = -1;
4910 audiocfg->out.quality = HB_INVALID_AUDIO_QUALITY;
4911 audiocfg->out.compression_level = -1;
4912 audiocfg->out.mixdown = HB_INVALID_AMIXDOWN;
4913 audiocfg->out.dynamic_range_compression = 0;
4914 audiocfg->out.gain = 0;
4915 audiocfg->out.normalize_mix_level = 0;
4916 audiocfg->out.dither_method = hb_audio_dither_get_default();
4917 audiocfg->out.name = NULL;
4918 }
4919
4920 /**********************************************************************
4921 * hb_audio_add
4922 **********************************************************************
4923 *
4924 *********************************************************************/
hb_audio_add(const hb_job_t * job,const hb_audio_config_t * audiocfg)4925 int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg)
4926 {
4927 hb_title_t *title = job->title;
4928 hb_audio_t *audio;
4929
4930 audio = hb_audio_copy( hb_list_item( title->list_audio, audiocfg->in.track ) );
4931 if( audio == NULL )
4932 {
4933 /* We fail! */
4934 return 0;
4935 }
4936
4937 if( (audiocfg->in.bitrate != -1) && (audiocfg->in.codec != 0xDEADBEEF) )
4938 {
4939 /* This most likely means the client didn't call hb_audio_config_init
4940 * so bail. */
4941 hb_audio_close(&audio);
4942 return 0;
4943 }
4944
4945 /* Set the job's "in track" to the value passed in audiocfg.
4946 * HandBrakeCLI assumes this value is preserved in the jobs
4947 * audio list, but in.track in the title's audio list is not
4948 * required to be the same. */
4949 // "track" in title->list_audio is an index into the source's tracks.
4950 // "track" in job->list_audio is an index into title->list_audio
4951 audio->config.in.track = audiocfg->in.track;
4952
4953 /* Really shouldn't ignore the passed out track, but there is currently no
4954 * way to handle duplicates or out-of-order track numbers. */
4955 audio->config.out = audiocfg->out;
4956 audio->config.out.track = hb_list_count(job->list_audio) + 1;
4957 if (audiocfg->out.name && *audiocfg->out.name)
4958 {
4959 audio->config.out.name = strdup(audiocfg->out.name);
4960 }
4961
4962 hb_list_add(job->list_audio, audio);
4963 return 1;
4964 }
4965
hb_list_audio_config_item(hb_list_t * list,int i)4966 hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i)
4967 {
4968 hb_audio_t *audio = NULL;
4969
4970 if( (audio = hb_list_item(list, i)) )
4971 return &(audio->config);
4972
4973 return NULL;
4974 }
4975
4976 /**********************************************************************
4977 * hb_subtitle_copy
4978 **********************************************************************
4979 *
4980 *********************************************************************/
hb_subtitle_copy(const hb_subtitle_t * src)4981 hb_subtitle_t *hb_subtitle_copy(const hb_subtitle_t *src)
4982 {
4983 hb_subtitle_t *subtitle = NULL;
4984
4985 if( src )
4986 {
4987 subtitle = calloc(1, sizeof(*subtitle));
4988 memcpy(subtitle, src, sizeof(*subtitle));
4989 if ( src->extradata )
4990 {
4991 subtitle->extradata = malloc( src->extradata_size );
4992 memcpy( subtitle->extradata, src->extradata, src->extradata_size );
4993 }
4994 if (src->name != NULL)
4995 {
4996 subtitle->name = strdup(src->name);
4997 }
4998 if (src->config.name != NULL)
4999 {
5000 subtitle->config.name = strdup(src->config.name);
5001 }
5002 if (src->config.src_filename)
5003 {
5004 subtitle->config.src_filename = strdup(src->config.src_filename);
5005 }
5006 }
5007 return subtitle;
5008 }
5009
5010 /**********************************************************************
5011 * hb_subtitle_list_copy
5012 **********************************************************************
5013 *
5014 *********************************************************************/
hb_subtitle_list_copy(const hb_list_t * src)5015 hb_list_t *hb_subtitle_list_copy(const hb_list_t *src)
5016 {
5017 hb_list_t *list = hb_list_init();
5018 hb_subtitle_t *subtitle = NULL;
5019 int i;
5020
5021 if( src )
5022 {
5023 for( i = 0; i < hb_list_count(src); i++ )
5024 {
5025 if( ( subtitle = hb_list_item( src, i ) ) )
5026 {
5027 hb_list_add( list, hb_subtitle_copy(subtitle) );
5028 }
5029 }
5030 }
5031 return list;
5032 }
5033
5034 /**********************************************************************
5035 * hb_subtitle_close
5036 **********************************************************************
5037 *
5038 *********************************************************************/
hb_subtitle_close(hb_subtitle_t ** _sub)5039 void hb_subtitle_close( hb_subtitle_t **_sub )
5040 {
5041 hb_subtitle_t * sub = *_sub;
5042 if ( _sub && sub )
5043 {
5044 free((char*)sub->name);
5045 free((char*)sub->config.name);
5046 free((char*)sub->config.src_filename);
5047 free(sub->extradata);
5048 free(sub);
5049 *_sub = NULL;
5050 }
5051 }
5052
5053 /**********************************************************************
5054 * hb_subtitle_add
5055 **********************************************************************
5056 *
5057 *********************************************************************/
hb_subtitle_add_ssa_header(hb_subtitle_t * subtitle,const char * font,int fs,int w,int h)5058 int hb_subtitle_add_ssa_header(hb_subtitle_t *subtitle, const char *font,
5059 int fs, int w, int h)
5060 {
5061 // Free any pre-existing extradata
5062 free(subtitle->extradata);
5063
5064 // SRT subtitles are represented internally as SSA
5065 // Create an SSA header
5066 const char * ssa_header =
5067 "[Script Info]\r\n"
5068 "ScriptType: v4.00+\r\n"
5069 "Collisions: Normal\r\n"
5070 "PlayResX: %d\r\n"
5071 "PlayResY: %d\r\n"
5072 "Timer: 100.0\r\n"
5073 "WrapStyle: 0\r\n"
5074 "\r\n"
5075 "[V4+ Styles]\r\n"
5076 "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r\n"
5077 "Style: Default,%s,%d,&H00FFFFFF,&H00FFFFFF,&H000F0F0F,&H000F0F0F,0,0,0,0,100,100,0,0.00,1,2,3,2,20,20,20,0\r\n";
5078
5079 subtitle->extradata = (uint8_t*)hb_strdup_printf(ssa_header, w, h, font, fs);
5080 if (subtitle->extradata == NULL)
5081 {
5082 hb_error("hb_subtitle_add_ssa_header: malloc failed");
5083 return 0;
5084 }
5085 subtitle->extradata_size = strlen((char*)subtitle->extradata) + 1;
5086
5087 return 1;
5088 }
5089
hb_subtitle_add(const hb_job_t * job,const hb_subtitle_config_t * subtitlecfg,int track)5090 int hb_subtitle_add(const hb_job_t * job, const hb_subtitle_config_t * subtitlecfg, int track)
5091 {
5092 hb_title_t *title = job->title;
5093 hb_subtitle_t *subtitle;
5094
5095 subtitle = hb_subtitle_copy( hb_list_item( title->list_subtitle, track ) );
5096 if( subtitle == NULL )
5097 {
5098 /* We fail! */
5099 return 0;
5100 }
5101
5102 // "track" in title->list_audio is an index into the source's tracks.
5103 // "track" in job->list_audio is an index into title->list_audio
5104 subtitle->track = track;
5105 subtitle->config = *subtitlecfg;
5106 if (subtitlecfg->name != NULL && subtitlecfg->name[0] != 0)
5107 {
5108 subtitle->config.name = strdup(subtitlecfg->name);
5109 }
5110 else
5111 {
5112 subtitle->config.name = NULL;
5113 }
5114 subtitle->config.src_filename = NULL;
5115 subtitle->out_track = hb_list_count(job->list_subtitle) + 1;
5116 hb_list_add(job->list_subtitle, subtitle);
5117 return 1;
5118 }
5119
hb_import_subtitle_add(const hb_job_t * job,const hb_subtitle_config_t * subtitlecfg,const char * lang_code,int source)5120 int hb_import_subtitle_add( const hb_job_t * job,
5121 const hb_subtitle_config_t * subtitlecfg,
5122 const char *lang_code, int source )
5123 {
5124 hb_subtitle_t *subtitle;
5125 iso639_lang_t *lang = NULL;
5126
5127 subtitle = calloc( 1, sizeof( *subtitle ) );
5128 if (subtitle == NULL)
5129 {
5130 hb_error("hb_srt_add: malloc failed");
5131 return 0;
5132 }
5133
5134 subtitle->id = (hb_list_count(job->list_subtitle) << 8) |
5135 HB_SUBTITLE_IMPORT_TAG;
5136 subtitle->format = TEXTSUB;
5137 subtitle->source = source;
5138 subtitle->codec = WORK_DECSRTSUB;
5139 subtitle->codec = source == IMPORTSRT ? WORK_DECSRTSUB :
5140 WORK_DECSSASUB;
5141 subtitle->codec_param = source == IMPORTSRT ? AV_CODEC_ID_SUBRIP :
5142 AV_CODEC_ID_ASS;
5143 subtitle->timebase.num = 1;
5144 subtitle->timebase.den = 90000;
5145
5146 lang = lang_for_code2(lang_code);
5147 if (lang == NULL)
5148 {
5149 hb_log("hb_srt_add: unknown language code (%s)", lang_code);
5150 lang = lang_for_code2("und");
5151 }
5152 snprintf(subtitle->lang, sizeof(subtitle->lang), "%s [%s]",
5153 strlen(lang->native_name) ? lang->native_name : lang->eng_name,
5154 hb_subsource_name(subtitle->source));
5155 strcpy(subtitle->iso639_2, lang->iso639_2);
5156
5157 subtitle->config = *subtitlecfg;
5158 if (subtitlecfg->name != NULL && subtitlecfg->name[0] != 0)
5159 {
5160 subtitle->config.name = strdup(subtitlecfg->name);
5161 }
5162 else
5163 {
5164 subtitle->config.name = NULL;
5165 }
5166 subtitle->config.src_filename = strdup(subtitlecfg->src_filename);
5167 hb_list_add(job->list_subtitle, subtitle);
5168
5169 return 1;
5170 }
5171
hb_srt_add(const hb_job_t * job,const hb_subtitle_config_t * subtitlecfg,const char * lang_code)5172 int hb_srt_add( const hb_job_t * job,
5173 const hb_subtitle_config_t * subtitlecfg,
5174 const char *lang_code )
5175 {
5176 return hb_import_subtitle_add(job, subtitlecfg, lang_code, IMPORTSRT);
5177 }
5178
hb_subtitle_can_force(int source)5179 int hb_subtitle_can_force( int source )
5180 {
5181 return source == VOBSUB || source == PGSSUB;
5182 }
5183
hb_subtitle_can_burn(int source)5184 int hb_subtitle_can_burn( int source )
5185 {
5186 return source == VOBSUB || source == PGSSUB || source == SSASUB ||
5187 source == CC608SUB || source == UTF8SUB || source == TX3GSUB ||
5188 source == IMPORTSRT || source == IMPORTSSA || source == DVBSUB;
5189 }
5190
hb_subtitle_can_pass(int source,int mux)5191 int hb_subtitle_can_pass( int source, int mux )
5192 {
5193 switch (mux)
5194 {
5195 case HB_MUX_AV_MKV:
5196 switch( source )
5197 {
5198 case DVBSUB:
5199 case PGSSUB:
5200 case VOBSUB:
5201 case SSASUB:
5202 case UTF8SUB:
5203 case TX3GSUB:
5204 case CC608SUB:
5205 case CC708SUB:
5206 case IMPORTSRT:
5207 case IMPORTSSA:
5208 return 1;
5209
5210 default:
5211 return 0;
5212 } break;
5213
5214 case HB_MUX_AV_MP4:
5215 switch( source )
5216 {
5217 case VOBSUB:
5218 case SSASUB:
5219 case UTF8SUB:
5220 case TX3GSUB:
5221 case CC608SUB:
5222 case CC708SUB:
5223 case IMPORTSRT:
5224 case IMPORTSSA:
5225 return 1;
5226
5227 default:
5228 return 0;
5229 } break;
5230
5231 // webm can't support subtitles unless they're burned.
5232 // there's ambiguity in the spec about WebVTT... TODO
5233 case HB_MUX_AV_WEBM:
5234 return 0;
5235 default:
5236 // Internal error. Should never get here.
5237 hb_error("internal error. Bad mux %d\n", mux);
5238 return 0;
5239 }
5240 }
5241
hb_audio_can_apply_drc(uint32_t codec,uint32_t codec_param,int encoder)5242 int hb_audio_can_apply_drc(uint32_t codec, uint32_t codec_param, int encoder)
5243 {
5244 if (encoder & HB_ACODEC_PASS_FLAG)
5245 {
5246 // can't apply DRC to passthrough audio
5247 return 0;
5248 }
5249 else if (codec & HB_ACODEC_FF_MASK)
5250 {
5251 return (codec_param == AV_CODEC_ID_AC3 ||
5252 codec_param == AV_CODEC_ID_EAC3);
5253 }
5254 else if (codec == HB_ACODEC_AC3)
5255 {
5256 return 1;
5257 }
5258 else
5259 {
5260 return 0;
5261 }
5262 }
5263
hb_audio_can_apply_drc2(hb_handle_t * h,int title_idx,int audio_idx,int encoder)5264 int hb_audio_can_apply_drc2(hb_handle_t *h, int title_idx, int audio_idx, int encoder)
5265 {
5266 hb_title_t *title = hb_find_title_by_index(h, title_idx);
5267 if (title == NULL)
5268 return 0;
5269
5270 hb_audio_t *audio = hb_list_item(title->list_audio, audio_idx);
5271 if (audio == NULL)
5272 return 0;
5273
5274 return hb_audio_can_apply_drc(audio->config.in.codec,
5275 audio->config.in.codec_param, encoder);
5276 }
5277
5278 /**********************************************************************
5279 * hb_metadata_init
5280 **********************************************************************
5281 *
5282 *********************************************************************/
hb_metadata_init()5283 hb_metadata_t *hb_metadata_init()
5284 {
5285 hb_metadata_t *metadata = calloc( 1, sizeof(*metadata) );
5286 if (metadata != NULL)
5287 {
5288 metadata->dict = hb_dict_init();
5289 }
5290 return metadata;
5291 }
5292
5293 /**********************************************************************
5294 * hb_metadata_copy
5295 **********************************************************************
5296 *
5297 *********************************************************************/
hb_metadata_copy(const hb_metadata_t * src)5298 hb_metadata_t *hb_metadata_copy( const hb_metadata_t *src )
5299 {
5300 hb_metadata_t *metadata = NULL;
5301
5302 if ( src )
5303 {
5304 metadata = calloc( 1, sizeof(*metadata) );
5305 if (src->dict != NULL)
5306 {
5307 metadata->dict = hb_value_dup(src->dict);
5308 }
5309 if ( src->list_coverart )
5310 {
5311 int ii;
5312 for ( ii = 0; ii < hb_list_count( src->list_coverart ); ii++ )
5313 {
5314 hb_coverart_t *art = hb_list_item( src->list_coverart, ii );
5315 hb_metadata_add_coverart(
5316 metadata, art->data, art->size, art->type );
5317 }
5318 }
5319 }
5320 return metadata;
5321 }
5322
5323 /**********************************************************************
5324 * hb_metadata_close
5325 **********************************************************************
5326 *
5327 *********************************************************************/
hb_metadata_close(hb_metadata_t ** _m)5328 void hb_metadata_close( hb_metadata_t **_m )
5329 {
5330 if ( _m && *_m )
5331 {
5332 hb_metadata_t *m = *_m;
5333 hb_coverart_t *art;
5334
5335 if (m->dict != NULL)
5336 {
5337 hb_value_free(&m->dict);
5338 }
5339
5340 if ( m->list_coverart )
5341 {
5342 while( ( art = hb_list_item( m->list_coverart, 0 ) ) )
5343 {
5344 hb_list_rem( m->list_coverart, art );
5345 free( art->data );
5346 free( art );
5347 }
5348 hb_list_close( &m->list_coverart );
5349 }
5350
5351 free( m );
5352 *_m = NULL;
5353 }
5354 }
5355
5356 /**********************************************************************
5357 * hb_metadata_set_*
5358 **********************************************************************
5359 *
5360 *********************************************************************/
hb_update_meta_dict(hb_dict_t * dict,const char * key,const char * value)5361 void hb_update_meta_dict(hb_dict_t * dict, const char * key, const char * value)
5362 {
5363 if (value != NULL)
5364 {
5365 hb_dict_set_string(dict, key, value);
5366 }
5367 else
5368 {
5369 hb_dict_remove(dict, key);
5370 }
5371 }
5372
hb_metadata_add_coverart(hb_metadata_t * metadata,const uint8_t * data,int size,int type)5373 void hb_metadata_add_coverart( hb_metadata_t *metadata, const uint8_t *data, int size, int type )
5374 {
5375 if ( metadata )
5376 {
5377 if ( metadata->list_coverart == NULL )
5378 {
5379 metadata->list_coverart = hb_list_init();
5380 }
5381 hb_coverart_t *art = calloc( 1, sizeof(hb_coverart_t) );
5382 art->data = malloc( size );
5383 memcpy( art->data, data, size );
5384 art->size = size;
5385 art->type = type;
5386 hb_list_add( metadata->list_coverart, art );
5387 }
5388 }
5389
hb_metadata_rem_coverart(hb_metadata_t * metadata,int idx)5390 void hb_metadata_rem_coverart( hb_metadata_t *metadata, int idx )
5391 {
5392 if ( metadata )
5393 {
5394 hb_coverart_t *art = hb_list_item( metadata->list_coverart, idx );
5395 if ( art )
5396 {
5397 hb_list_rem( metadata->list_coverart, art );
5398 free( art->data );
5399 free( art );
5400 }
5401 }
5402 }
5403
hb_strdup_vaprintf(const char * fmt,va_list args)5404 char * hb_strdup_vaprintf( const char * fmt, va_list args )
5405 {
5406 int len;
5407 int size = 256;
5408 char * str;
5409 char * tmp;
5410 va_list copy;
5411
5412 str = malloc( size );
5413 if ( str == NULL )
5414 return NULL;
5415
5416 while (1)
5417 {
5418 // vsnprintf modifies it's va_list. Since we may need to do this
5419 // more than once, use a copy of the va_list.
5420 va_copy(copy, args);
5421
5422 /* Try to print in the allocated space. */
5423 len = vsnprintf( str, size, fmt, copy );
5424
5425 /* If that worked, return the string. */
5426 if ( len > -1 && len < size )
5427 {
5428 return str;
5429 }
5430
5431 /* Else try again with more space. */
5432 if ( len > -1 ) /* glibc 2.1 */
5433 size = len + 1; /* precisely what is needed */
5434 else /* glibc 2.0 */
5435 size *= 2; /* twice the old size */
5436 tmp = realloc( str, size );
5437 if ( tmp == NULL )
5438 {
5439 free( str );
5440 return NULL;
5441 }
5442 else
5443 str = tmp;
5444 }
5445
5446 return str;
5447 }
5448
hb_strdup_printf(const char * fmt,...)5449 char * hb_strdup_printf( const char * fmt, ... )
5450 {
5451 char * str;
5452 va_list args;
5453
5454 va_start( args, fmt );
5455 str = hb_strdup_vaprintf( fmt, args );
5456 va_end( args );
5457
5458 return str;
5459 }
5460
hb_strncat_dup(const char * s1,const char * s2,size_t n)5461 char * hb_strncat_dup( const char * s1, const char * s2, size_t n )
5462 {
5463 size_t len;
5464 char * str;
5465
5466 len = 0;
5467 if( s1 )
5468 len += strlen( s1 );
5469 if( s2 )
5470 len += MAX( strlen( s2 ), n );
5471 if( !len )
5472 return NULL;
5473
5474 str = malloc( len + 1 );
5475 if( !str )
5476 return NULL;
5477
5478 if( s1 )
5479 strcpy( str, s1 );
5480 else
5481 strcpy( str, "" );
5482
5483 if (s2)
5484 {
5485 strncat( str, s2, n );
5486 }
5487
5488 return str;
5489 }
5490
5491 /**********************************************************************
5492 * hb_attachment_copy
5493 **********************************************************************
5494 *
5495 *********************************************************************/
hb_attachment_copy(const hb_attachment_t * src)5496 hb_attachment_t *hb_attachment_copy(const hb_attachment_t *src)
5497 {
5498 hb_attachment_t *attachment = NULL;
5499
5500 if( src )
5501 {
5502 attachment = calloc(1, sizeof(*attachment));
5503 memcpy(attachment, src, sizeof(*attachment));
5504 if ( src->name )
5505 {
5506 attachment->name = strdup( src->name );
5507 }
5508 if ( src->data )
5509 {
5510 attachment->data = malloc( src->size );
5511 memcpy( attachment->data, src->data, src->size );
5512 }
5513 }
5514 return attachment;
5515 }
5516
5517 /**********************************************************************
5518 * hb_attachment_list_copy
5519 **********************************************************************
5520 *
5521 *********************************************************************/
hb_attachment_list_copy(const hb_list_t * src)5522 hb_list_t *hb_attachment_list_copy(const hb_list_t *src)
5523 {
5524 hb_list_t *list = hb_list_init();
5525 hb_attachment_t *attachment = NULL;
5526 int i;
5527
5528 if( src )
5529 {
5530 for( i = 0; i < hb_list_count(src); i++ )
5531 {
5532 if( ( attachment = hb_list_item( src, i ) ) )
5533 {
5534 hb_list_add( list, hb_attachment_copy(attachment) );
5535 }
5536 }
5537 }
5538 return list;
5539 }
5540
5541 /**********************************************************************
5542 * hb_attachment_close
5543 **********************************************************************
5544 *
5545 *********************************************************************/
hb_attachment_close(hb_attachment_t ** attachment)5546 void hb_attachment_close( hb_attachment_t **attachment )
5547 {
5548 if ( attachment && *attachment )
5549 {
5550 free((*attachment)->data);
5551 free((*attachment)->name);
5552 free(*attachment);
5553 *attachment = NULL;
5554 }
5555 }
5556
5557 /**********************************************************************
5558 * hb_yuv2rgb
5559 **********************************************************************
5560 * Converts a YCrCb pixel to an RGB pixel.
5561 *
5562 * This conversion is lossy (due to rounding and clamping).
5563 *
5564 * Algorithm:
5565 * http://en.wikipedia.org/w/index.php?title=YCbCr&oldid=361987695#Technical_details
5566 *********************************************************************/
hb_yuv2rgb(int yuv)5567 int hb_yuv2rgb(int yuv)
5568 {
5569 double y, Cr, Cb;
5570 int r, g, b;
5571
5572 y = (yuv >> 16) & 0xff;
5573 Cr = (yuv >> 8) & 0xff;
5574 Cb = (yuv ) & 0xff;
5575
5576 r = 1.164 * (y - 16) + 1.596 * (Cr - 128);
5577 g = 1.164 * (y - 16) - 0.392 * (Cb - 128) - 0.813 * (Cr - 128);
5578 b = 1.164 * (y - 16) + 2.017 * (Cb - 128);
5579
5580 r = (r < 0) ? 0 : r;
5581 g = (g < 0) ? 0 : g;
5582 b = (b < 0) ? 0 : b;
5583
5584 r = (r > 255) ? 255 : r;
5585 g = (g > 255) ? 255 : g;
5586 b = (b > 255) ? 255 : b;
5587
5588 return (r << 16) | (g << 8) | b;
5589 }
5590
5591 /**********************************************************************
5592 * hb_rgb2yuv
5593 **********************************************************************
5594 * Converts an RGB pixel to a limited range Bt.601 YCrCb pixel.
5595 *
5596 * This conversion is lossy (due to rounding and clamping).
5597 *
5598 * Algorithm:
5599 * http://en.wikipedia.org/w/index.php?title=YCbCr&oldid=361987695#Technical_details
5600 *********************************************************************/
hb_rgb2yuv(int rgb)5601 int hb_rgb2yuv(int rgb)
5602 {
5603 double r, g, b;
5604 int y, Cr, Cb;
5605
5606 r = (rgb >> 16) & 0xff;
5607 g = (rgb >> 8) & 0xff;
5608 b = (rgb ) & 0xff;
5609
5610 y = 16. + ( 0.257 * r) + (0.504 * g) + (0.098 * b);
5611 Cb = 128. + (-0.148 * r) - (0.291 * g) + (0.439 * b);
5612 Cr = 128. + ( 0.439 * r) - (0.368 * g) - (0.071 * b);
5613
5614 y = (y < 0) ? 0 : y;
5615 Cb = (Cb < 0) ? 0 : Cb;
5616 Cr = (Cr < 0) ? 0 : Cr;
5617
5618 y = (y > 255) ? 255 : y;
5619 Cb = (Cb > 255) ? 255 : Cb;
5620 Cr = (Cr > 255) ? 255 : Cr;
5621
5622 return (y << 16) | (Cr << 8) | Cb;
5623 }
5624
hb_rgb2yuv_bt709(int rgb)5625 int hb_rgb2yuv_bt709(int rgb)
5626 {
5627 double r, g, b;
5628 int y, Cr, Cb;
5629
5630 r = (rgb >> 16) & 0xff;
5631 g = (rgb >> 8) & 0xff;
5632 b = (rgb ) & 0xff;
5633
5634 y = 16. + ( 0.1826 * r) + (0.6142 * g) + (0.0620 * b);
5635 Cb = 128. + (-0.1006 * r) - (0.3386 * g) + (0.4392 * b);
5636 Cr = 128. + ( 0.4392 * r) - (0.3986 * g) - (0.0403 * b);
5637
5638 y = (y < 0) ? 0 : y;
5639 Cb = (Cb < 0) ? 0 : Cb;
5640 Cr = (Cr < 0) ? 0 : Cr;
5641
5642 y = (y > 255) ? 255 : y;
5643 Cb = (Cb > 255) ? 255 : Cb;
5644 Cr = (Cr > 255) ? 255 : Cr;
5645
5646 return (y << 16) | (Cr << 8) | Cb;
5647 }
5648
hb_subsource_name(int source)5649 const char * hb_subsource_name( int source )
5650 {
5651 switch (source)
5652 {
5653 case VOBSUB:
5654 return "VOBSUB";
5655 case IMPORTSRT:
5656 return "SRT";
5657 case CC608SUB:
5658 return "CC608";
5659 case CC708SUB:
5660 return "CC708";
5661 case UTF8SUB:
5662 return "UTF-8";
5663 case TX3GSUB:
5664 return "TX3G";
5665 case IMPORTSSA:
5666 case SSASUB:
5667 return "SSA";
5668 case PGSSUB:
5669 return "PGS";
5670 case DVBSUB:
5671 return "DVB";
5672 default:
5673 return "Unknown";
5674 }
5675 }
5676
hb_hexdump(hb_debug_level_t level,const char * label,const uint8_t * data,int len)5677 void hb_hexdump( hb_debug_level_t level, const char * label, const uint8_t * data, int len )
5678 {
5679 int ii;
5680 char line[80], ascii[19], *p;
5681
5682 ascii[18] = 0;
5683 ascii[0] = '|';
5684 ascii[17] = '|';
5685 memset(&ascii[1], '.', 16);
5686 p = line;
5687 if( label )
5688 hb_deep_log(level, "++++ %s ++++", label);
5689 else
5690 hb_deep_log(level, "++++++++++++");
5691 for( ii = 0; ii < len; ii++ )
5692 {
5693 if( ( ii & 0x0f ) == 0x0f )
5694 {
5695 p += sprintf( p, "%02x", data[ii] );
5696 hb_deep_log( level, " %-50s%20s", line, ascii );
5697 memset(&ascii[1], '.', 16);
5698 p = line;
5699 }
5700 else if( ( ii & 0x07 ) == 0x07 )
5701 {
5702 p += sprintf( p, "%02x ", data[ii] );
5703 }
5704 else
5705 {
5706 p += sprintf( p, "%02x ", data[ii] );
5707 }
5708 if( isgraph( data[ii] ) )
5709 ascii[(ii & 0x0f) + 1] = data[ii];
5710 else
5711 ascii[(ii & 0x0f) + 1] = '.';
5712 }
5713 if( p != line )
5714 {
5715 hb_deep_log( level, " %-50s%20s", line, ascii );
5716 }
5717 }
5718
hb_str_vlen(char ** strv)5719 int hb_str_vlen(char **strv)
5720 {
5721 int i;
5722 if (strv == NULL)
5723 return 0;
5724 for (i = 0; strv[i]; i++);
5725 return i;
5726 }
5727
strchr_quote(const char * pos,char c,char q)5728 static const char* strchr_quote(const char *pos, char c, char q)
5729 {
5730 if (pos == NULL)
5731 return NULL;
5732
5733 while (*pos != 0 && *pos != c)
5734 {
5735 if (*pos == q)
5736 {
5737 pos = strchr_quote(pos+1, q, 0);
5738 if (pos == NULL)
5739 return NULL;
5740 pos++;
5741 }
5742 else if (*pos == '\\' && *(pos+1) != 0)
5743 pos += 2;
5744 else
5745 pos++;
5746 }
5747 if (*pos != c)
5748 return NULL;
5749 return pos;
5750 }
5751
strndup_quote(const char * str,char q,int len)5752 static char *strndup_quote(const char *str, char q, int len)
5753 {
5754 if (str == NULL)
5755 return NULL;
5756
5757 char * res;
5758 int str_len = strlen( str );
5759 int src = 0, dst = 0;
5760 res = malloc( len > str_len ? str_len + 1 : len + 1 );
5761 if ( res == NULL ) return res;
5762
5763 while (str[src] != 0 && src < len)
5764 {
5765 if (str[src] == q)
5766 src++;
5767 else
5768 res[dst++] = str[src++];
5769 }
5770 res[dst] = '\0';
5771 return res;
5772 }
5773
hb_str_vsplit(const char * str,char delem)5774 char** hb_str_vsplit( const char *str, char delem )
5775 {
5776 const char * pos;
5777 const char * end;
5778 char ** ret;
5779 int count, i;
5780 char quote = '"';
5781
5782 if (delem == '"')
5783 {
5784 quote = '\'';
5785 }
5786 if ( str == NULL || str[0] == 0 )
5787 {
5788 ret = malloc( sizeof(char*) );
5789 if ( ret == NULL ) return ret;
5790 *ret = NULL;
5791 return ret;
5792 }
5793
5794 // Find number of elements in the string
5795 count = 1;
5796 pos = str;
5797 while ( ( pos = strchr_quote( pos, delem, quote ) ) != NULL )
5798 {
5799 count++;
5800 pos++;
5801 }
5802
5803 ret = calloc( ( count + 1 ), sizeof(char*) );
5804 if ( ret == NULL ) return ret;
5805
5806 pos = str;
5807 for ( i = 0; i < count - 1; i++ )
5808 {
5809 end = strchr_quote( pos, delem, quote );
5810 ret[i] = strndup_quote(pos, quote, end - pos);
5811 pos = end + 1;
5812 }
5813 ret[i] = strndup_quote(pos, quote, strlen(pos));
5814
5815 return ret;
5816 }
5817
hb_str_vfree(char ** strv)5818 void hb_str_vfree( char **strv )
5819 {
5820 int i;
5821
5822 if (strv == NULL)
5823 return;
5824
5825 for ( i = 0; strv[i]; i++ )
5826 {
5827 free( strv[i] );
5828 }
5829 free( strv );
5830 }
5831
hb_chapter_queue_init(void)5832 hb_chapter_queue_t * hb_chapter_queue_init(void)
5833 {
5834 hb_chapter_queue_t * q;
5835
5836 q = calloc(1, sizeof(*q));
5837 if (q != NULL)
5838 {
5839 q->list_chapter = hb_list_init();
5840 if (q->list_chapter == NULL)
5841 {
5842 free(q);
5843 q = NULL;
5844 }
5845 }
5846 return q;
5847 }
5848
hb_chapter_queue_close(hb_chapter_queue_t ** _q)5849 void hb_chapter_queue_close(hb_chapter_queue_t **_q)
5850 {
5851 hb_chapter_queue_t * q = *_q;
5852 hb_chapter_queue_item_t * item;
5853
5854 if (q == NULL)
5855 {
5856 return;
5857 }
5858 while ((item = hb_list_item(q->list_chapter, 0)) != NULL)
5859 {
5860 hb_list_rem(q->list_chapter, item);
5861 free(item);
5862 }
5863 hb_list_close(&q->list_chapter);
5864 free(q);
5865 *_q = NULL;
5866 }
5867
hb_chapter_enqueue(hb_chapter_queue_t * q,hb_buffer_t * buf)5868 void hb_chapter_enqueue(hb_chapter_queue_t *q, hb_buffer_t *buf)
5869 {
5870 /*
5871 * Chapter markers are sometimes so close we can get a new
5872 * one before the previous goes through the encoding queue.
5873 *
5874 * Dropping markers can cause weird side-effects downstream,
5875 * including but not limited to missing chapters in the
5876 * output, so we need to save it somehow.
5877 */
5878 hb_chapter_queue_item_t *item = malloc(sizeof(hb_chapter_queue_item_t));
5879 if (item != NULL)
5880 {
5881 item->start = buf->s.start;
5882 item->new_chap = buf->s.new_chap;
5883 // Make sure work_loop doesn't also copy the chapter mark
5884 buf->s.new_chap = 0;
5885 hb_list_add(q->list_chapter, item);
5886 }
5887 }
5888
hb_chapter_dequeue(hb_chapter_queue_t * q,hb_buffer_t * buf)5889 void hb_chapter_dequeue(hb_chapter_queue_t *q, hb_buffer_t *buf)
5890 {
5891 hb_chapter_queue_item_t *item = hb_list_item(q->list_chapter, 0);
5892 if (item != NULL)
5893 {
5894 if (buf->s.start < item->start)
5895 {
5896 // Have not reached the next chapter yet.
5897 return;
5898 }
5899
5900 // we're done with this chapter
5901 hb_list_rem(q->list_chapter, item);
5902 buf->s.new_chap = item->new_chap;
5903 free(item);
5904 }
5905 }
5906
hb_get_bit_depth(int format)5907 int hb_get_bit_depth(int format)
5908 {
5909 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
5910 int i, min, max;
5911
5912 if (!desc || !desc->nb_components) {
5913 return -1;
5914 }
5915
5916 min = INT_MAX, max = -INT_MAX;
5917 for (i = 0; i < desc->nb_components; i++) {
5918 min = FFMIN(desc->comp[i].depth, min);
5919 max = FFMAX(desc->comp[i].depth, max);
5920 }
5921
5922 return max;
5923 }
5924
pix_fmt_is_supported(hb_job_t * job,int pix_fmt)5925 static int pix_fmt_is_supported(hb_job_t * job, int pix_fmt)
5926 {
5927 int title_bit_depth = hb_get_bit_depth(job->title->pix_fmt);
5928 int pix_fmt_bit_depth = hb_get_bit_depth(pix_fmt);
5929
5930 if (pix_fmt_bit_depth > title_bit_depth)
5931 {
5932 return 0;
5933 }
5934
5935 if (job->title->video_decode_support & HB_DECODE_SUPPORT_QSV)
5936 {
5937 // Allow formats supported by QSV pipeline via system memory
5938 // at that stage only, video memory formats will be reassigned later if allowed
5939 if (pix_fmt != AV_PIX_FMT_YUV420P10 &&
5940 pix_fmt != AV_PIX_FMT_YUV420P)
5941 {
5942 return 0;
5943 }
5944 }
5945 else
5946 {
5947 // Allow biplanar formats only if
5948 // hardware decoding is enabled.
5949 if (pix_fmt == AV_PIX_FMT_P010LE ||
5950 pix_fmt == AV_PIX_FMT_NV12)
5951 {
5952 return 0;
5953 }
5954 }
5955
5956 for (int i = 0; i < hb_list_count(job->list_filter); i++)
5957 {
5958 hb_filter_object_t *filter = hb_list_item(job->list_filter, i);
5959
5960 switch (filter->id)
5961 {
5962 case HB_FILTER_DETELECINE:
5963 case HB_FILTER_COMB_DETECT:
5964 case HB_FILTER_DECOMB:
5965 case HB_FILTER_DENOISE:
5966 case HB_FILTER_NLMEANS:
5967 case HB_FILTER_CHROMA_SMOOTH:
5968 case HB_FILTER_LAPSHARP:
5969 case HB_FILTER_UNSHARP:
5970 case HB_FILTER_GRAYSCALE:
5971 if (pix_fmt != AV_PIX_FMT_YUV420P)
5972 {
5973 return 0;
5974 }
5975 case HB_FILTER_RENDER_SUB:
5976 if (pix_fmt != AV_PIX_FMT_YUV420P &&
5977 pix_fmt != AV_PIX_FMT_YUV420P10 &&
5978 pix_fmt != AV_PIX_FMT_YUV420P12)
5979 {
5980 return 0;
5981 }
5982 }
5983 }
5984
5985 return 1;
5986 }
5987
5988 static const enum AVPixelFormat pipeline_pix_fmts[] =
5989 {
5990 AV_PIX_FMT_YUV420P12, AV_PIX_FMT_P010LE, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
5991 };
5992
hb_get_best_pix_fmt(hb_job_t * job)5993 int hb_get_best_pix_fmt(hb_job_t * job)
5994 {
5995 const int *pix_fmts = pipeline_pix_fmts;
5996
5997 while (*pix_fmts != AV_PIX_FMT_NONE)
5998 {
5999 if (pix_fmt_is_supported(job, *pix_fmts))
6000 {
6001 return *pix_fmts;
6002 }
6003 pix_fmts++;
6004 }
6005
6006 return AV_PIX_FMT_YUV420P;
6007 }
6008