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