/src/vlc/modules/codec/avcodec/encoder.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * encoder.c: video and audio encoder using the libavcodec library |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 1999-2004 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Gildas Bazin <gbazin@videolan.org> |
8 | | * Christophe Massiot <massiot@via.ecp.fr> |
9 | | * Part of the file Copyright (C) FFmpeg Project Developers |
10 | | * (mpeg4_default matrixes) |
11 | | * |
12 | | * This program is free software; you can redistribute it and/or modify it |
13 | | * under the terms of the GNU Lesser General Public License as published by |
14 | | * the Free Software Foundation; either version 2.1 of the License, or |
15 | | * (at your option) any later version. |
16 | | * |
17 | | * This program is distributed in the hope that it will be useful, |
18 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | | * GNU Lesser General Public License for more details. |
21 | | * |
22 | | * You should have received a copy of the GNU Lesser General Public License |
23 | | * along with this program; if not, write to the Free Software Foundation, |
24 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
25 | | *****************************************************************************/ |
26 | | |
27 | | /***************************************************************************** |
28 | | * Preamble |
29 | | *****************************************************************************/ |
30 | | #ifdef HAVE_CONFIG_H |
31 | | # include "config.h" |
32 | | #endif |
33 | | |
34 | | #include <math.h> |
35 | | |
36 | | #include <vlc_common.h> |
37 | | #include <vlc_configuration.h> |
38 | | #include <vlc_aout.h> |
39 | | #include <vlc_sout.h> |
40 | | #include <vlc_codec.h> |
41 | | #include <vlc_dialog.h> |
42 | | #include <vlc_avcodec.h> |
43 | | #include <vlc_cpu.h> |
44 | | |
45 | | #include <libavcodec/avcodec.h> |
46 | | #include <libavutil/channel_layout.h> |
47 | | |
48 | | #include "avcodec.h" |
49 | | #include "avcommon.h" |
50 | | |
51 | | #define API_CHANNEL_LAYOUT_STRUCT (LIBAVCODEC_VERSION_CHECK(59, 24, 100)) // AVCodecContext.ch_layout |
52 | | |
53 | 0 | #define HURRY_UP_GUARD1 VLC_TICK_FROM_MS(450) |
54 | 0 | #define HURRY_UP_GUARD2 VLC_TICK_FROM_MS(300) |
55 | 0 | #define HURRY_UP_GUARD3 VLC_TICK_FROM_MS(100) |
56 | | |
57 | | #if LIBAVCODEC_VERSION_CHECK(59, 0, 100) |
58 | 0 | # define AVC_MAYBE_CONST const |
59 | | #else |
60 | | # define AVC_MAYBE_CONST |
61 | | #endif |
62 | | |
63 | | /***************************************************************************** |
64 | | * Local prototypes |
65 | | *****************************************************************************/ |
66 | | static block_t *EncodeVideo( encoder_t *, picture_t * ); |
67 | | static block_t *EncodeAudio( encoder_t *, block_t * ); |
68 | | |
69 | | struct thread_context_t; |
70 | | |
71 | | /***************************************************************************** |
72 | | * thread_context_t : for multithreaded encoding |
73 | | *****************************************************************************/ |
74 | | struct thread_context_t |
75 | | { |
76 | | struct vlc_object_t obj; |
77 | | |
78 | | AVCodecContext *p_context; |
79 | | int (* pf_func)(AVCodecContext *c, void *arg); |
80 | | void *arg; |
81 | | int i_ret; |
82 | | |
83 | | vlc_mutex_t lock; |
84 | | vlc_cond_t cond; |
85 | | bool b_work, b_done; |
86 | | }; |
87 | | |
88 | | /***************************************************************************** |
89 | | * encoder_sys_t : libavcodec encoder descriptor |
90 | | *****************************************************************************/ |
91 | | typedef struct |
92 | | { |
93 | | /* |
94 | | * libavcodec properties |
95 | | */ |
96 | | AVC_MAYBE_CONST AVCodec *p_codec; |
97 | | AVCodecContext *p_context; |
98 | | |
99 | | /* |
100 | | * Common buffer mainly for audio as frame size in there needs usually be constant |
101 | | */ |
102 | | uint8_t *p_buffer; |
103 | | size_t i_buffer_out; |
104 | | uint8_t *p_interleave_buf; |
105 | | |
106 | | /* |
107 | | * Video properties |
108 | | */ |
109 | | vlc_tick_t i_last_ref_pts; |
110 | | vlc_tick_t i_buggy_pts_detect; |
111 | | vlc_tick_t i_last_pts; |
112 | | bool b_inited; |
113 | | |
114 | | /* |
115 | | * Audio properties |
116 | | */ |
117 | | size_t i_sample_bytes; |
118 | | size_t i_frame_size; |
119 | | size_t i_samples_delay; //How much samples in delay buffer |
120 | | bool b_planar; |
121 | | bool b_variable; //Encoder can be fed with any size frames not just frame_size |
122 | | vlc_tick_t i_pts; |
123 | | date_t buffer_date; |
124 | | |
125 | | /* Multichannel (>2) channel reordering */ |
126 | | uint8_t i_channels_to_reorder; |
127 | | uint8_t pi_reorder_layout[AOUT_CHAN_MAX]; |
128 | | |
129 | | /* Encoding settings */ |
130 | | int i_key_int; |
131 | | int i_b_frames; |
132 | | int i_vtolerance; |
133 | | int i_qmin; |
134 | | int i_qmax; |
135 | | int i_hq; |
136 | | int i_rc_buffer_size; |
137 | | float f_rc_buffer_aggressivity; |
138 | | bool b_pre_me; |
139 | | bool b_hurry_up; |
140 | | bool b_interlace, b_interlace_me; |
141 | | float f_i_quant_factor; |
142 | | bool b_mpeg4_matrix; |
143 | | bool b_trellis; |
144 | | int i_quality; /* for VBR */ |
145 | | float f_lumi_masking, f_dark_masking, f_p_masking, f_border_masking; |
146 | | int i_aac_profile; /* AAC profile to use.*/ |
147 | | |
148 | | AVFrame *frame; |
149 | | } encoder_sys_t; |
150 | | |
151 | | |
152 | | /* Taken from audio.c*/ |
153 | | static const uint64_t pi_channels_map[][2] = |
154 | | { |
155 | | { AV_CH_FRONT_LEFT, AOUT_CHAN_LEFT }, |
156 | | { AV_CH_FRONT_RIGHT, AOUT_CHAN_RIGHT }, |
157 | | { AV_CH_FRONT_CENTER, AOUT_CHAN_CENTER }, |
158 | | { AV_CH_LOW_FREQUENCY, AOUT_CHAN_LFE }, |
159 | | { AV_CH_BACK_LEFT, AOUT_CHAN_REARLEFT }, |
160 | | { AV_CH_BACK_RIGHT, AOUT_CHAN_REARRIGHT }, |
161 | | { AV_CH_FRONT_LEFT_OF_CENTER, 0 }, |
162 | | { AV_CH_FRONT_RIGHT_OF_CENTER, 0 }, |
163 | | { AV_CH_BACK_CENTER, AOUT_CHAN_REARCENTER }, |
164 | | { AV_CH_SIDE_LEFT, AOUT_CHAN_MIDDLELEFT }, |
165 | | { AV_CH_SIDE_RIGHT, AOUT_CHAN_MIDDLERIGHT }, |
166 | | { AV_CH_TOP_CENTER, 0 }, |
167 | | { AV_CH_TOP_FRONT_LEFT, 0 }, |
168 | | { AV_CH_TOP_FRONT_CENTER, 0 }, |
169 | | { AV_CH_TOP_FRONT_RIGHT, 0 }, |
170 | | { AV_CH_TOP_BACK_LEFT, 0 }, |
171 | | { AV_CH_TOP_BACK_CENTER, 0 }, |
172 | | { AV_CH_TOP_BACK_RIGHT, 0 }, |
173 | | { AV_CH_STEREO_LEFT, 0 }, |
174 | | { AV_CH_STEREO_RIGHT, 0 }, |
175 | | }; |
176 | | |
177 | | #if !API_CHANNEL_LAYOUT_STRUCT |
178 | | static const uint32_t channel_mask[][2] = { |
179 | | {0,0}, |
180 | | {AOUT_CHAN_CENTER, AV_CH_LAYOUT_MONO}, |
181 | | {AOUT_CHANS_STEREO, AV_CH_LAYOUT_STEREO}, |
182 | | {AOUT_CHANS_2_1, AV_CH_LAYOUT_2POINT1}, |
183 | | {AOUT_CHANS_4_0, AV_CH_LAYOUT_4POINT0}, |
184 | | {AOUT_CHANS_4_1, AV_CH_LAYOUT_4POINT1}, |
185 | | {AOUT_CHANS_5_1, AV_CH_LAYOUT_5POINT1_BACK}, |
186 | | {AOUT_CHANS_7_0, AV_CH_LAYOUT_7POINT0}, |
187 | | {AOUT_CHANS_7_1, AV_CH_LAYOUT_7POINT1}, |
188 | | {AOUT_CHANS_8_1, AV_CH_LAYOUT_OCTAGONAL}, |
189 | | }; |
190 | | #endif |
191 | | |
192 | | static const char *const ppsz_enc_options[] = { |
193 | | "keyint", "bframes", "vt", "qmin", "qmax", "codec", "hq", |
194 | | "rc-buffer-size", "rc-buffer-aggressivity", "pre-me", "hurry-up", |
195 | | "interlace", "interlace-me", "i-quant-factor", "noise-reduction", "mpeg4-matrix", |
196 | | "trellis", "qscale", "strict", "lumi-masking", "dark-masking", |
197 | | "p-masking", "border-masking", |
198 | | "aac-profile", "options", |
199 | | NULL |
200 | | }; |
201 | | |
202 | | static const uint16_t mpa_bitrate_tab[2][15] = |
203 | | { |
204 | | {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, |
205 | | {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} |
206 | | }; |
207 | | |
208 | | static const uint16_t mpa_freq_tab[6] = |
209 | | { 44100, 48000, 32000, 22050, 24000, 16000 }; |
210 | | |
211 | | static const uint16_t mpeg4_default_intra_matrix[64] = { |
212 | | 8, 17, 18, 19, 21, 23, 25, 27, |
213 | | 17, 18, 19, 21, 23, 25, 27, 28, |
214 | | 20, 21, 22, 23, 24, 26, 28, 30, |
215 | | 21, 22, 23, 24, 26, 28, 30, 32, |
216 | | 22, 23, 24, 26, 28, 30, 32, 35, |
217 | | 23, 24, 26, 28, 30, 32, 35, 38, |
218 | | 25, 26, 28, 30, 32, 35, 38, 41, |
219 | | 27, 28, 30, 32, 35, 38, 41, 45, |
220 | | }; |
221 | | |
222 | | static const uint16_t mpeg4_default_non_intra_matrix[64] = { |
223 | | 16, 17, 18, 19, 20, 21, 22, 23, |
224 | | 17, 18, 19, 20, 21, 22, 23, 24, |
225 | | 18, 19, 20, 21, 22, 23, 24, 25, |
226 | | 19, 20, 21, 22, 23, 24, 26, 27, |
227 | | 20, 21, 22, 23, 25, 26, 27, 28, |
228 | | 21, 22, 23, 24, 26, 27, 28, 30, |
229 | | 22, 23, 24, 26, 27, 28, 30, 31, |
230 | | 23, 24, 25, 27, 28, 30, 31, 33, |
231 | | }; |
232 | | |
233 | | static const int DEFAULT_ALIGN = 0; |
234 | | |
235 | | static void probe_video_frame_rate( encoder_t *p_enc, AVCodecContext *p_context, AVC_MAYBE_CONST AVCodec *p_codec ) |
236 | 0 | { |
237 | | /* if we don't have i_frame_rate_base, we are probing and just checking if we can find codec |
238 | | * so set fps to requested fps if asked by user or input fps is available */ |
239 | 0 | p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base ? p_enc->fmt_in.video.i_frame_rate_base : 1; |
240 | | |
241 | | // MP4V doesn't like CLOCK_FREQ denominator in time_base, so use 1/25 as default for that |
242 | 0 | if( p_enc->fmt_in.video.i_frame_rate_base ) |
243 | 0 | p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate; |
244 | 0 | else if( p_enc->fmt_out.i_codec == VLC_CODEC_MP4V ) |
245 | 0 | p_context->time_base.den = 25; |
246 | 0 | else |
247 | 0 | p_context->time_base.den = CLOCK_FREQ; |
248 | |
|
249 | 0 | msg_Dbg( p_enc, "Time base for probing set to %d/%d", p_context->time_base.num, p_context->time_base.den ); |
250 | |
|
251 | 0 | const AVRational *supported_framerates; |
252 | 0 | #if LIBAVCODEC_VERSION_CHECK( 61, 13, 100 ) |
253 | 0 | if (avcodec_get_supported_config(p_context, p_codec, AV_CODEC_CONFIG_FRAME_RATE, 0, |
254 | 0 | (const void **)&supported_framerates, NULL) < 0) |
255 | 0 | supported_framerates = NULL; |
256 | | #else |
257 | | supported_framerates = p_codec->supported_framerates; |
258 | | #endif |
259 | |
|
260 | 0 | if( supported_framerates ) |
261 | 0 | { |
262 | | /* We are finding fps values so 1/time_base */ |
263 | 0 | AVRational target = { |
264 | 0 | .num = p_context->time_base.den, |
265 | 0 | .den = p_context->time_base.num |
266 | 0 | }; |
267 | 0 | int idx = av_find_nearest_q_idx(target, supported_framerates); |
268 | |
|
269 | 0 | p_context->time_base.num = supported_framerates[idx].den ? |
270 | 0 | supported_framerates[idx].den : 1; |
271 | 0 | p_context->time_base.den = supported_framerates[idx].den ? |
272 | 0 | supported_framerates[idx].num : CLOCK_FREQ; |
273 | | |
274 | | /* If we have something reasonable on supported framerates, use that*/ |
275 | 0 | if( p_context->time_base.den && p_context->time_base.den < CLOCK_FREQ ) |
276 | 0 | { |
277 | 0 | p_enc->fmt_out.video.i_frame_rate_base = |
278 | 0 | p_enc->fmt_in.video.i_frame_rate_base = |
279 | 0 | p_context->time_base.num; |
280 | 0 | p_enc->fmt_out.video.i_frame_rate = |
281 | 0 | p_enc->fmt_in.video.i_frame_rate = |
282 | 0 | p_context->time_base.den; |
283 | 0 | } |
284 | 0 | } |
285 | 0 | msg_Dbg( p_enc, "Time base set to %d/%d", p_context->time_base.num, p_context->time_base.den ); |
286 | 0 | } |
287 | | |
288 | | static void add_av_option_int( encoder_t *p_enc, AVDictionary** pp_dict, const char* psz_name, int i_value ) |
289 | 0 | { |
290 | 0 | char buff[32]; |
291 | 0 | if ( snprintf( buff, sizeof(buff), "%d", i_value ) < 0 ) |
292 | 0 | return; |
293 | 0 | if( av_dict_set( pp_dict, psz_name, buff, 0 ) < 0 ) |
294 | 0 | msg_Warn( p_enc, "Failed to set encoder option %s", psz_name ); |
295 | 0 | } |
296 | | |
297 | | static void add_av_option_float( encoder_t *p_enc, AVDictionary** pp_dict, const char* psz_name, float f_value ) |
298 | 0 | { |
299 | 0 | char buff[128]; |
300 | 0 | if ( snprintf( buff, sizeof(buff), "%f", f_value ) < 0 ) |
301 | 0 | return; |
302 | 0 | if( av_dict_set( pp_dict, psz_name, buff, 0 ) < 0 ) |
303 | 0 | msg_Warn( p_enc, "Failed to set encoder option %s", psz_name ); |
304 | 0 | } |
305 | | |
306 | | /***************************************************************************** |
307 | | * InitVideoEnc: probe the encoder |
308 | | *****************************************************************************/ |
309 | | int InitVideoEnc( vlc_object_t *p_this ) |
310 | 0 | { |
311 | 0 | encoder_t *p_enc = (encoder_t *)p_this; |
312 | 0 | encoder_sys_t *p_sys; |
313 | 0 | AVCodecContext *p_context; |
314 | 0 | AVC_MAYBE_CONST AVCodec *p_codec = NULL; |
315 | 0 | enum AVCodecID i_codec_id; |
316 | 0 | const char *psz_namecodec; |
317 | 0 | float f_val; |
318 | 0 | char *psz_val; |
319 | |
|
320 | 0 | static const struct vlc_encoder_operations audio_ops = |
321 | 0 | { |
322 | 0 | .close = EndVideoEnc, |
323 | 0 | .encode_audio = EncodeAudio, |
324 | 0 | }; |
325 | |
|
326 | 0 | static const struct vlc_encoder_operations video_ops = |
327 | 0 | { |
328 | 0 | .close = EndVideoEnc, |
329 | 0 | .encode_video = EncodeVideo, |
330 | 0 | }; |
331 | |
|
332 | 0 | const struct vlc_encoder_operations *encoder_ops; |
333 | |
|
334 | 0 | msg_Dbg( p_this, "using %s %s", AVPROVIDER(LIBAVCODEC), LIBAVCODEC_IDENT ); |
335 | | |
336 | | /* Initialization must be done before avcodec_find_encoder() */ |
337 | 0 | vlc_init_avcodec(p_this); |
338 | |
|
339 | 0 | config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg ); |
340 | |
|
341 | 0 | switch( p_enc->fmt_out.i_cat ) |
342 | 0 | { |
343 | 0 | case VIDEO_ES: |
344 | 0 | encoder_ops = &video_ops; |
345 | 0 | if( p_enc->fmt_out.i_codec == VLC_CODEC_MP1V ) |
346 | 0 | { |
347 | 0 | i_codec_id = AV_CODEC_ID_MPEG1VIDEO; |
348 | 0 | psz_namecodec = "MPEG-1 video"; |
349 | 0 | break; |
350 | 0 | } |
351 | 0 | if( GetFfmpegCodec( &p_enc->fmt_out, &i_codec_id, &psz_namecodec ) ) |
352 | 0 | break; |
353 | 0 | bool uv_flipped; |
354 | 0 | if( FindFfmpegChroma( p_enc->fmt_out.i_codec, &uv_flipped ) != AV_PIX_FMT_NONE ) |
355 | 0 | { |
356 | 0 | i_codec_id = AV_CODEC_ID_RAWVIDEO; |
357 | 0 | psz_namecodec = "Raw video"; |
358 | 0 | break; |
359 | 0 | } |
360 | 0 | return VLC_EGENERIC; |
361 | | |
362 | 0 | case AUDIO_ES: |
363 | 0 | encoder_ops = &audio_ops; |
364 | 0 | if( GetFfmpegCodec( &p_enc->fmt_out, &i_codec_id, &psz_namecodec ) ) |
365 | 0 | break; |
366 | | /* fall through */ |
367 | 0 | default: |
368 | | /* We don't support subtitle encoding */ |
369 | 0 | return VLC_EGENERIC; |
370 | 0 | } |
371 | | |
372 | 0 | char *psz_encoder = var_GetString( p_this, ENC_CFG_PREFIX "codec" ); |
373 | 0 | if( psz_encoder && *psz_encoder ) |
374 | 0 | { |
375 | 0 | p_codec = avcodec_find_encoder_by_name( psz_encoder ); |
376 | 0 | if( !p_codec ) |
377 | 0 | { |
378 | 0 | msg_Err( p_this, "Encoder `%s' not found", psz_encoder ); |
379 | 0 | free( psz_encoder ); |
380 | 0 | return VLC_EGENERIC; |
381 | 0 | } |
382 | 0 | else if( p_codec->id != i_codec_id ) |
383 | 0 | { |
384 | 0 | msg_Err( p_this, "Encoder `%s' can't handle %4.4s", |
385 | 0 | psz_encoder, (char*)&p_enc->fmt_out.i_codec ); |
386 | 0 | free( psz_encoder ); |
387 | 0 | return VLC_EGENERIC; |
388 | 0 | } |
389 | 0 | } |
390 | 0 | free( psz_encoder ); |
391 | 0 | if( !p_codec ) |
392 | 0 | p_codec = avcodec_find_encoder( i_codec_id ); |
393 | 0 | if( !p_codec ) |
394 | 0 | { |
395 | 0 | msg_Err( p_enc, "cannot find encoder %s\n" |
396 | 0 | "*** Your Libav/FFmpeg installation is crippled. ***\n" |
397 | 0 | "*** Please check with your Libav/FFmpeg packager. ***\n" |
398 | 0 | "*** This is NOT a VLC media player issue. ***", psz_namecodec ); |
399 | |
|
400 | 0 | #if !defined(_WIN32) |
401 | 0 | vlc_dialog_display_error( p_enc, _("Streaming / Transcoding failed"), _( |
402 | | /* I have had enough of all these MPEG-3 transcoding bug reports. |
403 | | * Downstream packager, you had better not patch this out, or I will be really |
404 | | * annoyed. Think about it - you don't want to fork the VLC translation files, |
405 | | * do you? -- Courmisch, 2008-10-22 */ |
406 | 0 | "It seems your Libav/FFmpeg (libavcodec) installation lacks the following encoder:\n" |
407 | 0 | "%s.\n" |
408 | 0 | "If you don't know how to fix this, ask for support from your distribution.\n" |
409 | 0 | "\n" |
410 | 0 | "This is not an error inside VLC media player.\n" |
411 | 0 | "Do not contact the VideoLAN project about this issue.\n"), |
412 | 0 | psz_namecodec ); |
413 | 0 | #endif |
414 | |
|
415 | 0 | return VLC_EGENERIC; |
416 | 0 | } |
417 | | |
418 | | /* Allocate the memory needed to store the encoder's structure */ |
419 | 0 | if( ( p_sys = calloc( 1, sizeof(encoder_sys_t) ) ) == NULL ) |
420 | 0 | return VLC_ENOMEM; |
421 | 0 | p_enc->p_sys = p_sys; |
422 | 0 | p_sys->i_samples_delay = 0; |
423 | 0 | p_sys->p_codec = p_codec; |
424 | 0 | p_sys->b_planar = false; |
425 | 0 | p_sys->i_last_pts = VLC_TICK_INVALID; |
426 | |
|
427 | 0 | p_sys->p_buffer = NULL; |
428 | 0 | p_sys->p_interleave_buf = NULL; |
429 | 0 | p_sys->i_buffer_out = 0; |
430 | |
|
431 | 0 | p_context = avcodec_alloc_context3(p_codec); |
432 | 0 | if( unlikely(p_context == NULL) ) |
433 | 0 | { |
434 | 0 | free( p_sys ); |
435 | 0 | return VLC_ENOMEM; |
436 | 0 | } |
437 | 0 | p_sys->p_context = p_context; |
438 | 0 | p_sys->p_context->codec_id = p_sys->p_codec->id; |
439 | 0 | p_context->thread_type = 0; |
440 | 0 | p_context->debug = var_InheritInteger( p_enc, "avcodec-debug" ); |
441 | 0 | p_context->opaque = (void *)p_this; |
442 | |
|
443 | 0 | p_sys->i_key_int = var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" ); |
444 | 0 | p_sys->i_b_frames = var_GetInteger( p_enc, ENC_CFG_PREFIX "bframes" ); |
445 | 0 | p_sys->i_vtolerance = var_GetInteger( p_enc, ENC_CFG_PREFIX "vt" ) * 1000; |
446 | 0 | p_sys->b_interlace = var_GetBool( p_enc, ENC_CFG_PREFIX "interlace" ); |
447 | 0 | p_sys->b_interlace_me = var_GetBool( p_enc, ENC_CFG_PREFIX "interlace-me" ); |
448 | 0 | p_sys->b_pre_me = var_GetBool( p_enc, ENC_CFG_PREFIX "pre-me" ); |
449 | 0 | p_sys->b_hurry_up = var_GetBool( p_enc, ENC_CFG_PREFIX "hurry-up" ); |
450 | |
|
451 | 0 | p_sys->i_rc_buffer_size = var_GetInteger( p_enc, ENC_CFG_PREFIX "rc-buffer-size" ); |
452 | 0 | p_sys->f_rc_buffer_aggressivity = var_GetFloat( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity" ); |
453 | 0 | p_sys->f_i_quant_factor = var_GetFloat( p_enc, ENC_CFG_PREFIX "i-quant-factor" ); |
454 | 0 | p_sys->b_mpeg4_matrix = var_GetBool( p_enc, ENC_CFG_PREFIX "mpeg4-matrix" ); |
455 | |
|
456 | 0 | f_val = var_GetFloat( p_enc, ENC_CFG_PREFIX "qscale" ); |
457 | |
|
458 | 0 | p_sys->i_quality = 0; |
459 | 0 | if( f_val < .01f || f_val > 255.f ) |
460 | 0 | f_val = 0.f; |
461 | 0 | else |
462 | 0 | p_sys->i_quality = lroundf(FF_QP2LAMBDA * f_val); |
463 | |
|
464 | 0 | psz_val = var_GetString( p_enc, ENC_CFG_PREFIX "hq" ); |
465 | 0 | p_sys->i_hq = FF_MB_DECISION_RD; |
466 | 0 | if( psz_val && *psz_val ) |
467 | 0 | { |
468 | 0 | if( !strcmp( psz_val, "rd" ) ) |
469 | 0 | p_sys->i_hq = FF_MB_DECISION_RD; |
470 | 0 | else if( !strcmp( psz_val, "bits" ) ) |
471 | 0 | p_sys->i_hq = FF_MB_DECISION_BITS; |
472 | 0 | else if( !strcmp( psz_val, "simple" ) ) |
473 | 0 | p_sys->i_hq = FF_MB_DECISION_SIMPLE; |
474 | 0 | else |
475 | 0 | p_sys->i_hq = FF_MB_DECISION_RD; |
476 | 0 | } |
477 | 0 | else |
478 | 0 | p_sys->i_hq = FF_MB_DECISION_RD; |
479 | 0 | free( psz_val ); |
480 | |
|
481 | 0 | p_sys->i_qmin = var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ); |
482 | 0 | p_sys->i_qmax = var_GetInteger( p_enc, ENC_CFG_PREFIX "qmax" ); |
483 | 0 | p_sys->b_trellis = var_GetBool( p_enc, ENC_CFG_PREFIX "trellis" ); |
484 | |
|
485 | 0 | p_context->strict_std_compliance = var_GetInteger( p_enc, ENC_CFG_PREFIX "strict" ); |
486 | |
|
487 | 0 | p_sys->f_lumi_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "lumi-masking" ); |
488 | 0 | p_sys->f_dark_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "dark-masking" ); |
489 | 0 | p_sys->f_p_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "p-masking" ); |
490 | 0 | p_sys->f_border_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "border-masking" ); |
491 | |
|
492 | 0 | psz_val = var_GetString( p_enc, ENC_CFG_PREFIX "aac-profile" ); |
493 | | /* libavcodec uses faac encoder atm, and it has issues with |
494 | | * other than low-complexity profile, so default to that */ |
495 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_LOW); |
496 | 0 | if( psz_val && *psz_val ) |
497 | 0 | { |
498 | 0 | if( !strncmp( psz_val, "main", 4 ) ) |
499 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_MAIN); |
500 | 0 | else if( !strncmp( psz_val, "low", 3 ) ) |
501 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_LOW); |
502 | 0 | else if( !strncmp( psz_val, "ssr", 3 ) ) |
503 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_SSR); |
504 | 0 | else if( !strncmp( psz_val, "ltp", 3 ) ) |
505 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_LTP); |
506 | | /* These require libavcodec with libfdk-aac */ |
507 | 0 | else if( !strncmp( psz_val, "hev2", 4 ) ) |
508 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_HE_V2); |
509 | 0 | else if( !strncmp( psz_val, "hev1", 4 ) ) |
510 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_HE); |
511 | 0 | else if( !strncmp( psz_val, "ld", 2 ) ) |
512 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_LD); |
513 | 0 | else if( !strncmp( psz_val, "eld", 3 ) ) |
514 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_ELD); |
515 | 0 | else |
516 | 0 | { |
517 | 0 | msg_Warn( p_enc, "unknown AAC profile requested, setting it to low" ); |
518 | 0 | p_sys->i_aac_profile = AVPROFILE(AAC_LOW); |
519 | 0 | } |
520 | 0 | } |
521 | 0 | free( psz_val ); |
522 | 0 | AVDictionary *options = NULL; |
523 | |
|
524 | 0 | if( p_enc->fmt_in.i_cat == VIDEO_ES ) |
525 | 0 | { |
526 | 0 | if( !p_enc->fmt_in.video.i_visible_width || !p_enc->fmt_in.video.i_visible_height ) |
527 | 0 | { |
528 | 0 | msg_Warn( p_enc, "invalid size %ix%i", p_enc->fmt_in.video.i_visible_width, |
529 | 0 | p_enc->fmt_in.video.i_visible_height ); |
530 | 0 | avcodec_free_context( &p_context ); |
531 | 0 | free( p_sys ); |
532 | 0 | return VLC_EGENERIC; |
533 | 0 | } |
534 | | |
535 | 0 | p_context->codec_type = AVMEDIA_TYPE_VIDEO; |
536 | |
|
537 | 0 | p_context->coded_width = p_enc->fmt_in.video.i_width; |
538 | 0 | p_context->coded_height = p_enc->fmt_in.video.i_height; |
539 | 0 | p_context->width = p_enc->fmt_in.video.i_visible_width; |
540 | 0 | p_context->height = p_enc->fmt_in.video.i_visible_height; |
541 | |
|
542 | 0 | probe_video_frame_rate( p_enc, p_context, p_codec ); |
543 | 0 | set_video_color_settings( &p_enc->fmt_in.video, p_context ); |
544 | | |
545 | | /* Defaults from ffmpeg.c */ |
546 | 0 | p_context->qblur = 0.5; |
547 | 0 | p_context->qcompress = 0.5; |
548 | 0 | p_context->b_quant_offset = 1.25; |
549 | 0 | p_context->b_quant_factor = 1.25; |
550 | 0 | p_context->i_quant_offset = 0.0; |
551 | 0 | p_context->i_quant_factor = -0.8; |
552 | |
|
553 | 0 | p_context->lumi_masking = p_sys->f_lumi_masking; |
554 | 0 | p_context->dark_masking = p_sys->f_dark_masking; |
555 | 0 | p_context->p_masking = p_sys->f_p_masking; |
556 | 0 | add_av_option_float( p_enc, &options, "border_mask", p_sys->f_border_masking ); |
557 | |
|
558 | 0 | if( p_sys->i_key_int > 0 ) |
559 | 0 | p_context->gop_size = p_sys->i_key_int; |
560 | 0 | p_context->max_b_frames = |
561 | 0 | VLC_CLIP( p_sys->i_b_frames, 0, FF_MAX_B_FRAMES ); |
562 | 0 | if( !p_context->max_b_frames && |
563 | 0 | ( p_enc->fmt_out.i_codec == VLC_CODEC_MPGV || |
564 | 0 | p_enc->fmt_out.i_codec == VLC_CODEC_MP2V ) ) |
565 | 0 | p_context->flags |= AV_CODEC_FLAG_LOW_DELAY; |
566 | |
|
567 | 0 | av_reduce( &p_context->sample_aspect_ratio.num, |
568 | 0 | &p_context->sample_aspect_ratio.den, |
569 | 0 | p_enc->fmt_in.video.i_sar_num, |
570 | 0 | p_enc->fmt_in.video.i_sar_den, 1 << 30 ); |
571 | | |
572 | |
|
573 | 0 | p_enc->fmt_in.i_codec = |
574 | 0 | p_enc->fmt_in.video.i_chroma = VLC_CODEC_I420; |
575 | | |
576 | | /* Very few application support YUV in TIFF, not even VLC */ |
577 | 0 | if( p_enc->fmt_out.i_codec == VLC_CODEC_TIFF ) |
578 | 0 | { |
579 | 0 | p_enc->fmt_in.i_codec = |
580 | 0 | p_enc->fmt_in.video.i_chroma = VLC_CODEC_RGB24; |
581 | 0 | } |
582 | |
|
583 | 0 | bool uv_flipped; |
584 | 0 | p_context->pix_fmt = FindFfmpegChroma( p_enc->fmt_in.video.i_chroma, &uv_flipped ); |
585 | 0 | assert(!uv_flipped); // I420/RGB24 should not be flipped |
586 | |
|
587 | 0 | const enum AVPixelFormat *pix_fmts; |
588 | 0 | #if LIBAVCODEC_VERSION_CHECK( 61, 13, 100 ) |
589 | 0 | if (avcodec_get_supported_config(p_context, p_codec, AV_CODEC_CONFIG_PIX_FORMAT, 0, |
590 | 0 | (const void **)&pix_fmts, NULL) < 0) |
591 | 0 | pix_fmts = NULL; |
592 | | #else |
593 | | pix_fmts = p_codec->pix_fmts; |
594 | | #endif |
595 | |
|
596 | 0 | if( pix_fmts ) |
597 | 0 | { |
598 | 0 | static const enum AVPixelFormat vlc_pix_fmts[] = { |
599 | 0 | AV_PIX_FMT_YUV420P, |
600 | 0 | AV_PIX_FMT_NV12, |
601 | 0 | AV_PIX_FMT_RGB24, |
602 | 0 | }; |
603 | 0 | bool found = false; |
604 | 0 | const enum AVPixelFormat *p = pix_fmts; |
605 | 0 | for( ; !found && *p != AV_PIX_FMT_NONE; p++ ) |
606 | 0 | { |
607 | 0 | for( size_t i = 0; i < ARRAY_SIZE(vlc_pix_fmts); ++i ) |
608 | 0 | { |
609 | 0 | if( *p == vlc_pix_fmts[i] ) |
610 | 0 | { |
611 | 0 | found = true; |
612 | 0 | p_context->pix_fmt = *p; |
613 | 0 | break; |
614 | 0 | } |
615 | 0 | } |
616 | 0 | } |
617 | 0 | if (!found) p_context->pix_fmt = pix_fmts[0]; |
618 | 0 | GetVlcChroma( &p_enc->fmt_in.video, p_context->pix_fmt ); |
619 | 0 | p_enc->fmt_in.i_codec = p_enc->fmt_in.video.i_chroma; |
620 | 0 | } |
621 | | |
622 | |
|
623 | 0 | if ( p_sys->f_i_quant_factor != 0.f ) |
624 | 0 | p_context->i_quant_factor = p_sys->f_i_quant_factor; |
625 | |
|
626 | 0 | int nr = var_GetInteger( p_enc, ENC_CFG_PREFIX "noise-reduction" ); |
627 | 0 | add_av_option_int( p_enc, &options, "noise_reduction", nr ); |
628 | |
|
629 | 0 | if ( p_sys->b_mpeg4_matrix ) |
630 | 0 | { |
631 | 0 | p_context->intra_matrix = av_malloc( sizeof(mpeg4_default_intra_matrix) ); |
632 | 0 | if ( p_context->intra_matrix ) |
633 | 0 | memcpy( p_context->intra_matrix, mpeg4_default_intra_matrix, |
634 | 0 | sizeof(mpeg4_default_intra_matrix)); |
635 | 0 | p_context->inter_matrix = av_malloc( sizeof(mpeg4_default_non_intra_matrix) ); |
636 | 0 | if ( p_context->inter_matrix ) |
637 | 0 | memcpy( p_context->inter_matrix, mpeg4_default_non_intra_matrix, |
638 | 0 | sizeof(mpeg4_default_non_intra_matrix)); |
639 | 0 | } |
640 | |
|
641 | 0 | if ( p_sys->b_pre_me ) |
642 | 0 | { |
643 | 0 | add_av_option_int( p_enc, &options, "mepre", 1 ); |
644 | 0 | p_context->me_pre_cmp = FF_CMP_CHROMA; |
645 | 0 | } |
646 | |
|
647 | 0 | if ( p_sys->b_interlace ) |
648 | 0 | { |
649 | 0 | if ( p_context->height <= 280 ) |
650 | 0 | { |
651 | 0 | if ( p_context->height != 16 || p_context->width != 16 ) |
652 | 0 | msg_Warn( p_enc, |
653 | 0 | "disabling interlaced video because height=%d <= 280", |
654 | 0 | p_context->height ); |
655 | 0 | } |
656 | 0 | else |
657 | 0 | { |
658 | 0 | p_context->flags |= AV_CODEC_FLAG_INTERLACED_DCT; |
659 | 0 | if ( p_sys->b_interlace_me ) |
660 | 0 | p_context->flags |= AV_CODEC_FLAG_INTERLACED_ME; |
661 | 0 | } |
662 | 0 | } |
663 | |
|
664 | 0 | p_context->trellis = p_sys->b_trellis; |
665 | |
|
666 | 0 | if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax ) |
667 | 0 | p_context->flags |= AV_CODEC_FLAG_QSCALE; |
668 | | /* These codecs cause libavcodec to exit if thread_count is > 1. |
669 | | See libavcodec/mpegvideo_enc.c:MPV_encode_init and |
670 | | libavcodec/svq3.c , WMV2 calls MPV_encode_init also. |
671 | | */ |
672 | 0 | if ( i_codec_id == AV_CODEC_ID_FLV1 || |
673 | 0 | i_codec_id == AV_CODEC_ID_H261 || |
674 | 0 | i_codec_id == AV_CODEC_ID_LJPEG || |
675 | 0 | i_codec_id == AV_CODEC_ID_MJPEG || |
676 | 0 | i_codec_id == AV_CODEC_ID_H263 || |
677 | 0 | i_codec_id == AV_CODEC_ID_H263P || |
678 | 0 | i_codec_id == AV_CODEC_ID_MSMPEG4V1 || |
679 | 0 | i_codec_id == AV_CODEC_ID_MSMPEG4V2 || |
680 | 0 | i_codec_id == AV_CODEC_ID_MSMPEG4V3 || |
681 | 0 | i_codec_id == AV_CODEC_ID_WMV1 || |
682 | 0 | i_codec_id == AV_CODEC_ID_WMV2 || |
683 | 0 | i_codec_id == AV_CODEC_ID_RV10 || |
684 | 0 | i_codec_id == AV_CODEC_ID_RV20 || |
685 | 0 | i_codec_id == AV_CODEC_ID_SVQ3 ) |
686 | 0 | p_enc->i_threads = 1; |
687 | |
|
688 | 0 | if( p_sys->i_vtolerance > 0 ) |
689 | 0 | p_context->bit_rate_tolerance = p_sys->i_vtolerance; |
690 | | |
691 | | /* usually if someone sets bitrate, he likes more to get that bitrate |
692 | | * over quality should help 'normal' user to get asked bitrate |
693 | | */ |
694 | 0 | if( p_enc->fmt_out.i_bitrate > 0 && p_sys->i_qmax == 0 && p_sys->i_qmin == 0 ) |
695 | 0 | { |
696 | 0 | p_sys->i_qmax = 51; |
697 | 0 | p_sys->i_qmin = 3; |
698 | 0 | } |
699 | |
|
700 | 0 | if( p_sys->i_qmin > 0 ) |
701 | 0 | { |
702 | 0 | p_context->qmin = p_sys->i_qmin; |
703 | 0 | p_context->mb_lmin = p_sys->i_qmin * FF_QP2LAMBDA; |
704 | 0 | add_av_option_int( p_enc, &options, "lmin", p_context->mb_lmin); |
705 | 0 | } |
706 | 0 | if( p_sys->i_qmax > 0 ) |
707 | 0 | { |
708 | 0 | p_context->qmax = p_sys->i_qmax; |
709 | 0 | p_context->mb_lmax = p_sys->i_qmax * FF_QP2LAMBDA; |
710 | 0 | add_av_option_int( p_enc, &options, "lmax", p_context->mb_lmax); |
711 | 0 | } |
712 | 0 | p_context->max_qdiff = 3; |
713 | |
|
714 | 0 | p_context->mb_decision = p_sys->i_hq; |
715 | |
|
716 | 0 | if( p_sys->i_quality && !p_enc->fmt_out.i_bitrate ) |
717 | 0 | { |
718 | 0 | p_context->flags |= AV_CODEC_FLAG_QSCALE; |
719 | 0 | p_context->global_quality = p_sys->i_quality; |
720 | 0 | } |
721 | 0 | else |
722 | 0 | { |
723 | 0 | av_dict_set(&options, "qsquish", "1.0", 0); |
724 | | /* Default to 1/2 second buffer for given bitrate unless defined otherwise*/ |
725 | 0 | if( !p_sys->i_rc_buffer_size ) |
726 | 0 | { |
727 | 0 | p_sys->i_rc_buffer_size = p_enc->fmt_out.i_bitrate * 8 / 2; |
728 | 0 | } |
729 | 0 | msg_Dbg( p_enc, "rc buffer size %d bits", p_sys->i_rc_buffer_size ); |
730 | | /* Set maxrate/minrate to bitrate to try to get CBR */ |
731 | 0 | p_context->rc_max_rate = p_enc->fmt_out.i_bitrate; |
732 | 0 | p_context->rc_min_rate = p_enc->fmt_out.i_bitrate; |
733 | 0 | p_context->rc_buffer_size = p_sys->i_rc_buffer_size; |
734 | | /* This is from ffmpeg's ffmpeg.c : */ |
735 | 0 | p_context->rc_initial_buffer_occupancy |
736 | 0 | = p_sys->i_rc_buffer_size * 3/4; |
737 | 0 | add_av_option_float( p_enc, &options, "rc_buffer_aggressivity", p_sys->f_rc_buffer_aggressivity ); |
738 | 0 | } |
739 | 0 | } |
740 | 0 | else if( p_enc->fmt_in.i_cat == AUDIO_ES ) |
741 | 0 | { |
742 | 0 | const enum AVSampleFormat *sample_fmts; |
743 | 0 | #if LIBAVCODEC_VERSION_CHECK( 61, 13, 100 ) |
744 | 0 | if (avcodec_get_supported_config(p_context, p_codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, |
745 | 0 | (const void **)&sample_fmts, NULL) < 0) |
746 | 0 | sample_fmts = NULL; |
747 | | #else |
748 | | sample_fmts = p_codec->sample_fmts; |
749 | | #endif |
750 | |
|
751 | 0 | p_context->codec_type = AVMEDIA_TYPE_AUDIO; |
752 | 0 | p_context->sample_fmt = sample_fmts ? sample_fmts[0] : AV_SAMPLE_FMT_S16; |
753 | | |
754 | | /* Try to match avcodec input format to vlc format so we could avoid one |
755 | | format conversion */ |
756 | 0 | if( GetVlcAudioFormat( p_context->sample_fmt ) != p_enc->fmt_in.i_codec |
757 | 0 | && sample_fmts ) |
758 | 0 | { |
759 | 0 | msg_Dbg( p_enc, "Trying to find more suitable sample format instead of %s", av_get_sample_fmt_name( p_context->sample_fmt ) ); |
760 | 0 | for( unsigned int i=0; sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++ ) |
761 | 0 | { |
762 | 0 | if( GetVlcAudioFormat( sample_fmts[i] ) == p_enc->fmt_in.i_codec ) |
763 | 0 | { |
764 | 0 | p_context->sample_fmt = sample_fmts[i]; |
765 | 0 | msg_Dbg( p_enc, "Using %s as new sample format", av_get_sample_fmt_name( p_context->sample_fmt ) ); |
766 | 0 | break; |
767 | 0 | } |
768 | 0 | } |
769 | 0 | } |
770 | 0 | p_sys->b_planar = av_sample_fmt_is_planar( p_context->sample_fmt ); |
771 | | // Try if we can use interleaved format for codec input as VLC doesn't really do planar audio yet |
772 | | // FIXME: Remove when planar/interleaved audio in vlc is equally supported |
773 | 0 | if( p_sys->b_planar && sample_fmts ) |
774 | 0 | { |
775 | 0 | msg_Dbg( p_enc, "Trying to find packet sample format instead of planar %s", av_get_sample_fmt_name( p_context->sample_fmt ) ); |
776 | 0 | for( unsigned int i=0; sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++ ) |
777 | 0 | { |
778 | 0 | if( !av_sample_fmt_is_planar( sample_fmts[i] ) ) |
779 | 0 | { |
780 | 0 | p_context->sample_fmt = sample_fmts[i]; |
781 | 0 | msg_Dbg( p_enc, "Changing to packet format %s as new sample format", av_get_sample_fmt_name( p_context->sample_fmt ) ); |
782 | 0 | break; |
783 | 0 | } |
784 | 0 | } |
785 | 0 | } |
786 | 0 | msg_Dbg( p_enc, "Ended up using %s as sample format", av_get_sample_fmt_name( p_context->sample_fmt ) ); |
787 | 0 | p_enc->fmt_in.i_codec = GetVlcAudioFormat( p_context->sample_fmt ); |
788 | 0 | p_sys->b_planar = av_sample_fmt_is_planar( p_context->sample_fmt ); |
789 | |
|
790 | 0 | p_context->sample_rate = p_enc->fmt_out.audio.i_rate; |
791 | 0 | date_Init( &p_sys->buffer_date, p_enc->fmt_out.audio.i_rate, 1 ); |
792 | 0 | p_context->time_base.num = 1; |
793 | 0 | p_context->time_base.den = p_context->sample_rate; |
794 | | |
795 | | /* Setup Channel ordering for audio |
796 | | * as VLC channel order isn't same as libavcodec expects |
797 | | */ |
798 | |
|
799 | 0 | p_sys->i_channels_to_reorder = 0; |
800 | | |
801 | | /* Create channel layout for avcodec |
802 | | * Copied from audio.c |
803 | | */ |
804 | 0 | uint32_t pi_order_dst[AOUT_CHAN_MAX] = { 0 }; |
805 | 0 | uint32_t order_mask = 0; |
806 | 0 | int i_channels_src = 0; |
807 | |
|
808 | 0 | msg_Dbg( p_enc, "Creating channel order for reordering"); |
809 | 0 | #if API_CHANNEL_LAYOUT_STRUCT && LIBAVUTIL_VERSION_CHECK(57, 24, 100) |
810 | 0 | av_channel_layout_default( &p_context->ch_layout, p_enc->fmt_out.audio.i_channels ); |
811 | 0 | uint64_t channel_mask = p_context->ch_layout.u.mask; |
812 | | #else |
813 | | p_context->channels = p_enc->fmt_out.audio.i_channels; |
814 | | p_context->channel_layout = channel_mask[p_context->channels][1]; |
815 | | uint64_t channel_mask = p_context->channel_layout; |
816 | | #endif |
817 | 0 | for( unsigned i = 0; i < ARRAY_SIZE(pi_channels_map); i++ ) |
818 | 0 | { |
819 | 0 | if( channel_mask & pi_channels_map[i][0] ) |
820 | 0 | { |
821 | 0 | msg_Dbg( p_enc, "%d %"PRIx64" mapped to %"PRIx64"", i_channels_src, pi_channels_map[i][0], pi_channels_map[i][1]); |
822 | 0 | pi_order_dst[i_channels_src++] = pi_channels_map[i][1]; |
823 | 0 | order_mask |= pi_channels_map[i][1]; |
824 | 0 | } |
825 | 0 | } |
826 | 0 | if( i_channels_src != p_enc->fmt_out.audio.i_channels ) |
827 | 0 | msg_Err( p_enc, "Channel layout not understood" ); |
828 | |
|
829 | 0 | p_sys->i_channels_to_reorder = |
830 | 0 | aout_CheckChannelReorder( NULL, pi_order_dst, order_mask, |
831 | 0 | p_sys->pi_reorder_layout ); |
832 | |
|
833 | 0 | if ( p_enc->fmt_out.i_codec == VLC_CODEC_MP4A ) |
834 | 0 | { |
835 | | /* XXX: FAAC does resample only when setting the INPUT samplerate |
836 | | * to the desired value (-R option of the faac frontend) |
837 | | p_enc->fmt_in.audio.i_rate = p_context->sample_rate;*/ |
838 | | /* vlc should default to low-complexity profile, faac encoder |
839 | | * has bug and aac audio has issues otherwise atm */ |
840 | 0 | p_context->profile = p_sys->i_aac_profile; |
841 | 0 | } |
842 | 0 | } |
843 | | |
844 | | /* Misc parameters */ |
845 | 0 | p_context->bit_rate = p_enc->fmt_out.i_bitrate; |
846 | | |
847 | | /* Set reasonable defaults to VP8, based on |
848 | | libvpx-720p preset from libvpx ffmpeg-patch */ |
849 | 0 | if( i_codec_id == AV_CODEC_ID_VP8 ) |
850 | 0 | { |
851 | | /* Lets give bitrate tolerance */ |
852 | 0 | p_context->bit_rate_tolerance = __MAX(2 * (int)p_enc->fmt_out.i_bitrate, p_sys->i_vtolerance ); |
853 | | /* default to 120 frames between keyframe */ |
854 | 0 | if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" ) ) |
855 | 0 | p_context->gop_size = 120; |
856 | | /* Don't set rc-values atm, they were from time before |
857 | | libvpx was officially in FFmpeg */ |
858 | | //p_context->rc_max_rate = 24 * 1000 * 1000; //24M |
859 | | //p_context->rc_min_rate = 40 * 1000; // 40k |
860 | | /* seems that FFmpeg presets have 720p as divider for buffers */ |
861 | 0 | if( p_enc->fmt_out.video.i_visible_height >= 720 ) |
862 | 0 | { |
863 | | /* Check that we don't overrun users qmin/qmax values */ |
864 | 0 | if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ) ) |
865 | 0 | { |
866 | 0 | p_context->qmin = 10; |
867 | 0 | p_context->mb_lmin = 10 * FF_QP2LAMBDA; |
868 | 0 | add_av_option_int( p_enc, &options, "lmin", p_context->mb_lmin ); |
869 | 0 | } |
870 | |
|
871 | 0 | if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmax" ) ) |
872 | 0 | { |
873 | 0 | p_context->qmax = 42; |
874 | 0 | p_context->mb_lmax = 42 * FF_QP2LAMBDA; |
875 | 0 | add_av_option_int( p_enc, &options, "lmax", p_context->mb_lmax ); |
876 | 0 | } |
877 | |
|
878 | 0 | } else if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ) ) |
879 | 0 | { |
880 | 0 | p_context->qmin = 1; |
881 | 0 | p_context->mb_lmin = FF_QP2LAMBDA; |
882 | 0 | add_av_option_int( p_enc, &options, "lmin", p_context->mb_lmin ); |
883 | 0 | } |
884 | | |
885 | |
|
886 | | #if 0 /* enable when/if vp8 encoder is accepted in libavcodec */ |
887 | | p_context->lag = 16; |
888 | | p_context->level = 216; |
889 | | p_context->profile = 0; |
890 | | p_context->rc_buffer_aggressivity = 0.95; |
891 | | p_context->token_partitions = 4; |
892 | | p_context->mb_static_threshold = 0; |
893 | | #endif |
894 | 0 | } |
895 | |
|
896 | 0 | if( i_codec_id == AV_CODEC_ID_RAWVIDEO ) |
897 | 0 | { |
898 | | /* XXX: hack: Force same codec (will be handled by transcode) */ |
899 | 0 | p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec; |
900 | |
|
901 | 0 | bool uv_flipped; |
902 | 0 | p_context->pix_fmt = FindFfmpegChroma( p_enc->fmt_in.video.i_chroma, &uv_flipped ); |
903 | 0 | if (unlikely(uv_flipped)) |
904 | 0 | msg_Warn(p_enc, "VLC chroma needs UV planes swapping %4.4s", |
905 | 0 | (char*)&p_enc->fmt_in.video.i_chroma); |
906 | 0 | } |
907 | | |
908 | | /* Make sure we get extradata filled by the encoder */ |
909 | 0 | p_context->extradata_size = 0; |
910 | 0 | p_context->extradata = NULL; |
911 | 0 | p_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; |
912 | |
|
913 | 0 | if( p_enc->i_threads >= 1) |
914 | 0 | p_context->thread_count = p_enc->i_threads; |
915 | 0 | else |
916 | 0 | p_context->thread_count = vlc_GetCPUCount(); |
917 | |
|
918 | 0 | int ret; |
919 | 0 | char *psz_opts = var_InheritString(p_enc, ENC_CFG_PREFIX "options"); |
920 | 0 | if (psz_opts) { |
921 | 0 | vlc_av_get_options(psz_opts, &options); |
922 | 0 | free(psz_opts); |
923 | 0 | } |
924 | |
|
925 | 0 | vlc_avcodec_lock(); |
926 | 0 | ret = avcodec_open2( p_context, p_codec, options ? &options : NULL ); |
927 | 0 | vlc_avcodec_unlock(); |
928 | |
|
929 | 0 | AVDictionaryEntry *t = NULL; |
930 | 0 | while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) { |
931 | 0 | msg_Err(p_enc, "Unknown option \"%s\"", t->key); |
932 | 0 | } |
933 | |
|
934 | 0 | if( ret ) |
935 | 0 | { |
936 | 0 | if( p_enc->fmt_in.i_cat != AUDIO_ES || |
937 | 0 | (p_enc->fmt_out.audio.i_channels <= 2 && i_codec_id != AV_CODEC_ID_MP2 |
938 | 0 | && i_codec_id != AV_CODEC_ID_MP3) ) |
939 | 0 | errmsg: |
940 | 0 | { |
941 | 0 | static const char types[][12] = { |
942 | 0 | [UNKNOWN_ES] = N_("unknown"), [VIDEO_ES] = N_("video"), |
943 | 0 | [AUDIO_ES] = N_("audio"), [SPU_ES] = N_("subpicture"), |
944 | 0 | }; |
945 | 0 | const char *type = types[0]; |
946 | 0 | union |
947 | 0 | { |
948 | 0 | vlc_fourcc_t value; |
949 | 0 | char txt[4]; |
950 | 0 | } fcc = { .value = p_enc->fmt_out.i_codec }; |
951 | |
|
952 | 0 | if (likely((unsigned)p_enc->fmt_in.i_cat < ARRAY_SIZE(types))) |
953 | 0 | type = types[p_enc->fmt_in.i_cat]; |
954 | 0 | msg_Err( p_enc, "cannot open %4.4s %s encoder", fcc.txt, type ); |
955 | 0 | vlc_dialog_display_error( p_enc, _("Streaming / Transcoding failed"), |
956 | 0 | _("VLC could not open the %4.4s %s encoder."), |
957 | 0 | fcc.txt, vlc_gettext(type) ); |
958 | 0 | av_dict_free(&options); |
959 | 0 | goto error; |
960 | 0 | } |
961 | | |
962 | 0 | if( p_enc->fmt_out.audio.i_channels > 2 ) |
963 | 0 | { |
964 | 0 | #if API_CHANNEL_LAYOUT_STRUCT && LIBAVUTIL_VERSION_CHECK(57, 24, 100) |
965 | 0 | av_channel_layout_default( &p_context->ch_layout, 2 ); |
966 | | #else |
967 | | p_context->channels = 2; |
968 | | p_context->channel_layout = channel_mask[p_context->channels][1]; |
969 | | #endif |
970 | | |
971 | | /* Change fmt_in in order to ask for a channels conversion */ |
972 | 0 | p_enc->fmt_in.audio.i_channels = |
973 | 0 | p_enc->fmt_out.audio.i_channels = 2; |
974 | 0 | p_enc->fmt_in.audio.i_physical_channels = |
975 | 0 | p_enc->fmt_out.audio.i_physical_channels = AOUT_CHANS_STEREO; |
976 | 0 | p_sys->i_channels_to_reorder = 0; |
977 | 0 | msg_Warn( p_enc, "stereo mode selected (codec limitation)" ); |
978 | 0 | } |
979 | |
|
980 | 0 | if( i_codec_id == AV_CODEC_ID_MP2 || i_codec_id == AV_CODEC_ID_MP3 ) |
981 | 0 | { |
982 | 0 | int i_frequency, i; |
983 | 0 | es_format_t *fmt = &p_enc->fmt_out; |
984 | |
|
985 | 0 | for ( i_frequency = 0; i_frequency < 6; i_frequency++ ) |
986 | 0 | if ( fmt->audio.i_rate == mpa_freq_tab[i_frequency] ) |
987 | 0 | break; |
988 | |
|
989 | 0 | if ( i_frequency == 6 ) |
990 | 0 | { |
991 | 0 | msg_Warn( p_enc, "MPEG audio doesn't support frequency=%d", |
992 | 0 | fmt->audio.i_rate ); |
993 | | /* Fallback to 44100 hz */ |
994 | 0 | p_context->sample_rate = p_enc->fmt_in.audio.i_rate = |
995 | 0 | p_enc->fmt_out.audio.i_rate = 44100; |
996 | 0 | } |
997 | |
|
998 | 0 | for ( i = 1; i < 14; i++ ) |
999 | 0 | if (fmt->i_bitrate/1000 <= mpa_bitrate_tab[i_frequency / 3][i]) |
1000 | 0 | break; |
1001 | |
|
1002 | 0 | if (fmt->i_bitrate / 1000 != mpa_bitrate_tab[i_frequency / 3][i]) |
1003 | 0 | { |
1004 | 0 | msg_Warn( p_enc, |
1005 | 0 | "MPEG audio doesn't support bitrate=%d, using %d", |
1006 | 0 | fmt->i_bitrate, |
1007 | 0 | mpa_bitrate_tab[i_frequency / 3][i] * 1000 ); |
1008 | 0 | fmt->i_bitrate = mpa_bitrate_tab[i_frequency / 3][i] * 1000; |
1009 | 0 | p_context->bit_rate = fmt->i_bitrate; |
1010 | 0 | } |
1011 | 0 | } |
1012 | |
|
1013 | 0 | p_context->codec = NULL; |
1014 | 0 | vlc_avcodec_lock(); |
1015 | 0 | ret = avcodec_open2( p_context, p_codec, options ? &options : NULL ); |
1016 | 0 | vlc_avcodec_unlock(); |
1017 | 0 | if( ret ) |
1018 | 0 | goto errmsg; |
1019 | 0 | } |
1020 | | |
1021 | 0 | av_dict_free(&options); |
1022 | |
|
1023 | 0 | if( i_codec_id == AV_CODEC_ID_FLAC ) |
1024 | 0 | { |
1025 | 0 | p_enc->fmt_out.i_extra = 4 + 1 + 3 + p_context->extradata_size; |
1026 | 0 | p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra ); |
1027 | 0 | if( p_enc->fmt_out.p_extra ) |
1028 | 0 | { |
1029 | 0 | uint8_t *p = p_enc->fmt_out.p_extra; |
1030 | 0 | p[0] = 0x66; /* f */ |
1031 | 0 | p[1] = 0x4C; /* L */ |
1032 | 0 | p[2] = 0x61; /* a */ |
1033 | 0 | p[3] = 0x43; /* C */ |
1034 | 0 | p[4] = 0x80; /* streaminfo block, last block before audio */ |
1035 | 0 | p[5] = ( p_context->extradata_size >> 16 ) & 0xff; |
1036 | 0 | p[6] = ( p_context->extradata_size >> 8 ) & 0xff; |
1037 | 0 | p[7] = ( p_context->extradata_size ) & 0xff; |
1038 | 0 | memcpy( &p[8], p_context->extradata, p_context->extradata_size ); |
1039 | 0 | } |
1040 | 0 | else |
1041 | 0 | { |
1042 | 0 | p_enc->fmt_out.i_extra = 0; |
1043 | 0 | } |
1044 | 0 | } |
1045 | 0 | else |
1046 | 0 | { |
1047 | 0 | p_enc->fmt_out.i_extra = p_context->extradata_size; |
1048 | 0 | if( p_enc->fmt_out.i_extra ) |
1049 | 0 | { |
1050 | 0 | p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra ); |
1051 | 0 | if ( p_enc->fmt_out.p_extra == NULL ) |
1052 | 0 | { |
1053 | 0 | goto error; |
1054 | 0 | } |
1055 | 0 | memcpy( p_enc->fmt_out.p_extra, p_context->extradata, |
1056 | 0 | p_enc->fmt_out.i_extra ); |
1057 | 0 | } |
1058 | 0 | } |
1059 | | |
1060 | 0 | p_context->flags &= ~AV_CODEC_FLAG_GLOBAL_HEADER; |
1061 | |
|
1062 | 0 | if( p_enc->fmt_in.i_cat == AUDIO_ES ) |
1063 | 0 | { |
1064 | 0 | p_enc->fmt_in.i_codec = GetVlcAudioFormat( p_sys->p_context->sample_fmt ); |
1065 | 0 | p_enc->fmt_in.audio.i_bitspersample = aout_BitsPerSample( p_enc->fmt_in.i_codec ); |
1066 | |
|
1067 | 0 | p_sys->i_sample_bytes = (p_enc->fmt_in.audio.i_bitspersample / 8); |
1068 | 0 | p_sys->i_frame_size = p_context->frame_size > 1 ? |
1069 | 0 | p_context->frame_size : |
1070 | 0 | 16384; // AV_INPUT_BUFFER_MIN_SIZE |
1071 | 0 | p_sys->i_buffer_out = av_samples_get_buffer_size(NULL, |
1072 | 0 | p_enc->fmt_out.audio.i_channels, p_sys->i_frame_size, |
1073 | 0 | p_sys->p_context->sample_fmt, DEFAULT_ALIGN); |
1074 | 0 | p_sys->p_buffer = av_malloc( p_sys->i_buffer_out ); |
1075 | 0 | if ( unlikely( p_sys->p_buffer == NULL ) ) |
1076 | 0 | { |
1077 | 0 | goto error; |
1078 | 0 | } |
1079 | 0 | p_enc->fmt_out.audio.i_frame_length = p_context->frame_size; |
1080 | 0 | p_enc->fmt_out.audio.i_blockalign = p_context->block_align; |
1081 | 0 | p_enc->fmt_out.audio.i_bitspersample = aout_BitsPerSample( p_enc->fmt_out.i_codec ); |
1082 | | //b_variable tells if we can feed any size frames to encoder |
1083 | 0 | p_sys->b_variable = p_context->frame_size ? false : true; |
1084 | | |
1085 | |
|
1086 | 0 | if( p_sys->b_planar ) |
1087 | 0 | { |
1088 | 0 | p_sys->p_interleave_buf = av_malloc( p_sys->i_buffer_out ); |
1089 | 0 | if( unlikely( p_sys->p_interleave_buf == NULL ) ) |
1090 | 0 | goto error; |
1091 | 0 | } |
1092 | 0 | } |
1093 | | |
1094 | 0 | p_sys->frame = av_frame_alloc(); |
1095 | 0 | if( !p_sys->frame ) |
1096 | 0 | { |
1097 | 0 | goto error; |
1098 | 0 | } |
1099 | 0 | msg_Dbg( p_enc, "found encoder %s", psz_namecodec ); |
1100 | |
|
1101 | 0 | assert(encoder_ops != NULL); |
1102 | 0 | p_enc->ops = encoder_ops; |
1103 | | |
1104 | |
|
1105 | 0 | return VLC_SUCCESS; |
1106 | 0 | error: |
1107 | 0 | free( p_enc->fmt_out.p_extra ); |
1108 | 0 | av_free( p_sys->p_buffer ); |
1109 | 0 | av_free( p_sys->p_interleave_buf ); |
1110 | 0 | avcodec_free_context( &p_context ); |
1111 | 0 | free( p_sys ); |
1112 | 0 | return VLC_ENOMEM; |
1113 | 0 | } |
1114 | | |
1115 | | typedef struct |
1116 | | { |
1117 | | block_t self; |
1118 | | AVPacket *packet; |
1119 | | } vlc_av_packet_t; |
1120 | | |
1121 | | static void vlc_av_packet_Release(block_t *block) |
1122 | 0 | { |
1123 | 0 | vlc_av_packet_t *b = (void *) block; |
1124 | |
|
1125 | 0 | av_packet_free( &b->packet ); |
1126 | 0 | free(b); |
1127 | 0 | } |
1128 | | |
1129 | | static const struct vlc_block_callbacks vlc_av_packet_cbs = |
1130 | | { |
1131 | | vlc_av_packet_Release, |
1132 | | }; |
1133 | | |
1134 | | static block_t *vlc_av_packet_Wrap(AVPacket *packet, AVCodecContext *context ) |
1135 | 0 | { |
1136 | 0 | if ( packet->data == NULL && |
1137 | 0 | packet->flags == 0 && |
1138 | 0 | packet->pts == AV_NOPTS_VALUE && |
1139 | 0 | packet->dts == AV_NOPTS_VALUE ) |
1140 | 0 | return NULL; /* totally empty AVPacket */ |
1141 | | |
1142 | 0 | vlc_av_packet_t *b = malloc( sizeof( *b ) ); |
1143 | 0 | if( unlikely(b == NULL) ) |
1144 | 0 | return NULL; |
1145 | | |
1146 | 0 | block_t *p_block = &b->self; |
1147 | |
|
1148 | 0 | block_Init( p_block, &vlc_av_packet_cbs, packet->data, packet->size ); |
1149 | 0 | p_block->i_nb_samples = 0; |
1150 | 0 | p_block->cbs = &vlc_av_packet_cbs; |
1151 | 0 | b->packet = packet; |
1152 | |
|
1153 | 0 | p_block->i_length = FROM_AVSCALE(packet->duration, context->time_base); |
1154 | 0 | if( unlikely( packet->flags & AV_PKT_FLAG_CORRUPT ) ) |
1155 | 0 | p_block->i_flags |= BLOCK_FLAG_CORRUPTED; |
1156 | 0 | if( packet->flags & AV_PKT_FLAG_KEY ) |
1157 | 0 | p_block->i_flags |= BLOCK_FLAG_TYPE_I; |
1158 | 0 | p_block->i_pts = VLC_TICK_0 + FROM_AVSCALE(packet->pts, context->time_base); |
1159 | 0 | p_block->i_dts = VLC_TICK_0 + FROM_AVSCALE(packet->dts, context->time_base); |
1160 | |
|
1161 | 0 | uint8_t *av_packet_sidedata = av_packet_get_side_data(packet, AV_PKT_DATA_QUALITY_STATS, NULL); |
1162 | 0 | if( av_packet_sidedata ) |
1163 | 0 | { |
1164 | 0 | switch ( av_packet_sidedata[4] ) |
1165 | 0 | { |
1166 | 0 | case AV_PICTURE_TYPE_I: |
1167 | 0 | case AV_PICTURE_TYPE_SI: |
1168 | 0 | p_block->i_flags |= BLOCK_FLAG_TYPE_I; |
1169 | 0 | break; |
1170 | 0 | case AV_PICTURE_TYPE_P: |
1171 | 0 | case AV_PICTURE_TYPE_SP: |
1172 | 0 | p_block->i_flags |= BLOCK_FLAG_TYPE_P; |
1173 | 0 | break; |
1174 | 0 | case AV_PICTURE_TYPE_B: |
1175 | 0 | case AV_PICTURE_TYPE_BI: |
1176 | 0 | p_block->i_flags |= BLOCK_FLAG_TYPE_B; |
1177 | 0 | break; |
1178 | 0 | default: |
1179 | 0 | p_block->i_flags |= BLOCK_FLAG_TYPE_PB; |
1180 | 0 | } |
1181 | |
|
1182 | 0 | } |
1183 | | |
1184 | 0 | return p_block; |
1185 | 0 | } |
1186 | | |
1187 | | static void check_hurry_up( encoder_sys_t *p_sys, AVFrame *frame, encoder_t *p_enc ) |
1188 | 0 | { |
1189 | 0 | vlc_tick_t current_date = vlc_tick_now(); |
1190 | |
|
1191 | 0 | if ( current_date + HURRY_UP_GUARD3 > FROM_AV_TS(frame->pts) ) |
1192 | 0 | { |
1193 | 0 | p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE; |
1194 | 0 | p_sys->p_context->trellis = 0; |
1195 | 0 | msg_Dbg( p_enc, "hurry up mode 3" ); |
1196 | 0 | } |
1197 | 0 | else |
1198 | 0 | { |
1199 | 0 | p_sys->p_context->mb_decision = p_sys->i_hq; |
1200 | |
|
1201 | 0 | if ( current_date + HURRY_UP_GUARD2 > FROM_AV_TS(frame->pts) ) |
1202 | 0 | { |
1203 | 0 | p_sys->p_context->trellis = 0; |
1204 | 0 | msg_Dbg( p_enc, "hurry up mode 2" ); |
1205 | 0 | } |
1206 | 0 | else |
1207 | 0 | { |
1208 | 0 | p_sys->p_context->trellis = p_sys->b_trellis; |
1209 | 0 | } |
1210 | 0 | } |
1211 | |
|
1212 | 0 | if ( current_date + HURRY_UP_GUARD1 > FROM_AV_TS(frame->pts) ) |
1213 | 0 | { |
1214 | 0 | frame->pict_type = AV_PICTURE_TYPE_P; |
1215 | | /* msg_Dbg( p_enc, "hurry up mode 1 %lld", current_date + HURRY_UP_GUARD1 - frame.pts ); */ |
1216 | 0 | } |
1217 | 0 | } |
1218 | | |
1219 | | static block_t *encode_avframe( encoder_t *p_enc, encoder_sys_t *p_sys, AVFrame *frame ) |
1220 | 0 | { |
1221 | 0 | AVPacket *av_pkt = av_packet_alloc(); |
1222 | |
|
1223 | 0 | if( !av_pkt ) |
1224 | 0 | return NULL; |
1225 | | |
1226 | 0 | int ret = avcodec_send_frame( p_sys->p_context, frame ); |
1227 | 0 | if( frame && ret != 0 && ret != AVERROR(EAGAIN) ) |
1228 | 0 | { |
1229 | 0 | msg_Warn( p_enc, "cannot send one frame to encoder %d", ret ); |
1230 | 0 | av_packet_free( &av_pkt ); |
1231 | 0 | return NULL; |
1232 | 0 | } |
1233 | 0 | ret = avcodec_receive_packet( p_sys->p_context, av_pkt ); |
1234 | 0 | if( ret != 0 && ret != AVERROR(EAGAIN) ) |
1235 | 0 | { |
1236 | 0 | msg_Warn( p_enc, "cannot encode one frame" ); |
1237 | 0 | av_packet_free( &av_pkt ); |
1238 | 0 | return NULL; |
1239 | 0 | } |
1240 | | |
1241 | 0 | block_t *p_block = vlc_av_packet_Wrap( av_pkt, p_sys->p_context ); |
1242 | 0 | if( unlikely(p_block == NULL) ) |
1243 | 0 | { |
1244 | 0 | av_packet_free( &av_pkt ); |
1245 | 0 | return NULL; |
1246 | 0 | } |
1247 | 0 | return p_block; |
1248 | 0 | } |
1249 | | |
1250 | | /**************************************************************************** |
1251 | | * EncodeVideo: the whole thing |
1252 | | ****************************************************************************/ |
1253 | | static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict ) |
1254 | 0 | { |
1255 | 0 | encoder_sys_t *p_sys = p_enc->p_sys; |
1256 | 0 | int i_plane; |
1257 | |
|
1258 | 0 | AVFrame *frame = NULL; |
1259 | 0 | if( likely(p_pict) ) { |
1260 | 0 | frame = p_sys->frame; |
1261 | 0 | av_frame_unref( frame ); |
1262 | |
|
1263 | 0 | for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ ) |
1264 | 0 | { |
1265 | 0 | p_sys->frame->data[i_plane] = p_pict->p[i_plane].p_pixels; |
1266 | 0 | p_sys->frame->linesize[i_plane] = p_pict->p[i_plane].i_pitch; |
1267 | 0 | } |
1268 | | |
1269 | | /* Let libavcodec select the frame type */ |
1270 | 0 | frame->pict_type = 0; |
1271 | |
|
1272 | 0 | frame->repeat_pict = p_pict->i_nb_fields - 2; |
1273 | 0 | #if LIBAVUTIL_VERSION_CHECK( 58, 7, 100 ) |
1274 | 0 | if (p_pict->b_progressive) |
1275 | 0 | frame->flags &= ~AV_FRAME_FLAG_INTERLACED; |
1276 | 0 | else |
1277 | 0 | frame->flags |= AV_FRAME_FLAG_INTERLACED; |
1278 | 0 | if (p_pict->b_top_field_first) |
1279 | 0 | frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; |
1280 | 0 | else |
1281 | 0 | frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; |
1282 | | #else |
1283 | | frame->interlaced_frame = !p_pict->b_progressive; |
1284 | | frame->top_field_first = !!p_pict->b_top_field_first; |
1285 | | #endif |
1286 | |
|
1287 | 0 | frame->format = p_sys->p_context->pix_fmt; |
1288 | 0 | frame->width = p_sys->p_context->width; |
1289 | 0 | frame->height = p_sys->p_context->height; |
1290 | | |
1291 | | /* Set the pts of the frame being encoded |
1292 | | * avcodec likes pts to be in time_base units |
1293 | | * frame number */ |
1294 | 0 | if( likely( p_pict->date != VLC_TICK_INVALID ) ) |
1295 | 0 | frame->pts = TO_AVSCALE( p_pict->date - VLC_TICK_0, |
1296 | 0 | p_sys->p_context->time_base ); |
1297 | 0 | else |
1298 | 0 | frame->pts = AV_NOPTS_VALUE; |
1299 | |
|
1300 | 0 | if ( p_sys->b_hurry_up && frame->pts != AV_NOPTS_VALUE ) |
1301 | 0 | check_hurry_up( p_sys, frame, p_enc ); |
1302 | |
|
1303 | 0 | if ( ( frame->pts != AV_NOPTS_VALUE ) && ( frame->pts != VLC_TICK_INVALID ) ) |
1304 | 0 | { |
1305 | 0 | if ( p_sys->i_last_pts == FROM_AV_TS(frame->pts) ) |
1306 | 0 | { |
1307 | 0 | msg_Warn( p_enc, "almost fed libavcodec with two frames with " |
1308 | 0 | "the same PTS (%"PRId64 ")", frame->pts ); |
1309 | 0 | return NULL; |
1310 | 0 | } |
1311 | 0 | else if ( p_sys->i_last_pts > FROM_AV_TS(frame->pts) ) |
1312 | 0 | { |
1313 | 0 | msg_Warn( p_enc, "almost fed libavcodec with a frame in the " |
1314 | 0 | "past (current: %"PRId64 ", last: %"PRId64")", |
1315 | 0 | frame->pts, p_sys->i_last_pts ); |
1316 | 0 | return NULL; |
1317 | 0 | } |
1318 | 0 | else |
1319 | 0 | p_sys->i_last_pts = FROM_AV_TS(frame->pts); |
1320 | 0 | } |
1321 | | |
1322 | 0 | frame->quality = p_sys->i_quality; |
1323 | 0 | } |
1324 | | |
1325 | 0 | block_t *p_block = encode_avframe( p_enc, p_sys, frame ); |
1326 | |
|
1327 | 0 | return p_block; |
1328 | 0 | } |
1329 | | |
1330 | | static block_t *handle_delay_buffer( encoder_t *p_enc, encoder_sys_t *p_sys, unsigned int buffer_delay, |
1331 | | block_t *p_aout_buf, size_t leftover_samples ) |
1332 | 0 | { |
1333 | 0 | block_t *p_block = NULL; |
1334 | | //How much we need to copy from new packet |
1335 | 0 | const size_t leftover = leftover_samples * p_enc->fmt_out.audio.i_channels * p_sys->i_sample_bytes; |
1336 | |
|
1337 | 0 | av_frame_unref( p_sys->frame ); |
1338 | 0 | p_sys->frame->format = p_sys->p_context->sample_fmt; |
1339 | 0 | p_sys->frame->nb_samples = leftover_samples + p_sys->i_samples_delay; |
1340 | 0 | #if API_CHANNEL_LAYOUT_STRUCT && LIBAVUTIL_VERSION_CHECK(57, 24, 100) |
1341 | 0 | av_channel_layout_copy(&p_sys->frame->ch_layout, &p_sys->p_context->ch_layout); |
1342 | | #else |
1343 | | p_sys->frame->channel_layout = p_sys->p_context->channel_layout; |
1344 | | p_sys->frame->channels = p_sys->p_context->channels; |
1345 | | #endif |
1346 | |
|
1347 | 0 | if( likely( date_Get( &p_sys->buffer_date ) != VLC_TICK_INVALID) ) |
1348 | 0 | { |
1349 | | /* Convert to AV timing */ |
1350 | 0 | p_sys->frame->pts = date_Get( &p_sys->buffer_date ) - VLC_TICK_0; |
1351 | 0 | p_sys->frame->pts = TO_AVSCALE( p_sys->frame->pts, p_sys->p_context->time_base ); |
1352 | 0 | date_Increment( &p_sys->buffer_date, p_sys->frame->nb_samples ); |
1353 | 0 | } |
1354 | 0 | else p_sys->frame->pts = AV_NOPTS_VALUE; |
1355 | |
|
1356 | 0 | if( likely( p_aout_buf ) ) |
1357 | 0 | { |
1358 | |
|
1359 | 0 | p_aout_buf->i_nb_samples -= leftover_samples; |
1360 | 0 | memcpy( p_sys->p_buffer+buffer_delay, p_aout_buf->p_buffer, leftover ); |
1361 | | |
1362 | | // We need to deinterleave from p_aout_buf to p_buffer the leftover bytes |
1363 | 0 | if( p_sys->b_planar ) |
1364 | 0 | aout_Deinterleave( p_sys->p_interleave_buf, p_sys->p_buffer, |
1365 | 0 | p_sys->i_frame_size, p_enc->fmt_out.audio.i_channels, p_enc->fmt_in.i_codec ); |
1366 | 0 | else |
1367 | 0 | memcpy( p_sys->p_buffer + buffer_delay, p_aout_buf->p_buffer, leftover); |
1368 | |
|
1369 | 0 | p_aout_buf->p_buffer += leftover; |
1370 | 0 | p_aout_buf->i_buffer -= leftover; |
1371 | 0 | p_aout_buf->i_pts = date_Get( &p_sys->buffer_date ); |
1372 | 0 | } |
1373 | |
|
1374 | 0 | if(unlikely( ( (leftover + buffer_delay) < p_sys->i_buffer_out ) && |
1375 | 0 | !(p_sys->p_codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME ))) |
1376 | 0 | { |
1377 | 0 | msg_Dbg( p_enc, "No small last frame support, padding"); |
1378 | 0 | size_t padding_size = p_sys->i_buffer_out - (leftover+buffer_delay); |
1379 | 0 | memset( p_sys->p_buffer + (leftover+buffer_delay), 0, padding_size ); |
1380 | 0 | buffer_delay += padding_size; |
1381 | 0 | } |
1382 | 0 | if( avcodec_fill_audio_frame( p_sys->frame, p_enc->fmt_out.audio.i_channels, |
1383 | 0 | p_sys->p_context->sample_fmt, p_sys->b_planar ? p_sys->p_interleave_buf : p_sys->p_buffer, |
1384 | 0 | p_sys->i_buffer_out, |
1385 | 0 | DEFAULT_ALIGN) < 0 ) |
1386 | 0 | { |
1387 | 0 | msg_Err( p_enc, "filling error on fillup" ); |
1388 | 0 | p_sys->frame->nb_samples = 0; |
1389 | 0 | } |
1390 | | |
1391 | |
|
1392 | 0 | p_sys->i_samples_delay = 0; |
1393 | |
|
1394 | 0 | p_block = encode_avframe( p_enc, p_sys, p_sys->frame ); |
1395 | |
|
1396 | 0 | return p_block; |
1397 | 0 | } |
1398 | | |
1399 | | /**************************************************************************** |
1400 | | * EncodeAudio: the whole thing |
1401 | | ****************************************************************************/ |
1402 | | static block_t *EncodeAudio( encoder_t *p_enc, block_t *p_aout_buf ) |
1403 | 0 | { |
1404 | 0 | encoder_sys_t *p_sys = p_enc->p_sys; |
1405 | |
|
1406 | 0 | block_t *p_block, *p_chain = NULL; |
1407 | 0 | size_t buffer_delay = 0, i_samples_left = 0; |
1408 | | |
1409 | | |
1410 | | //i_bytes_left is amount of bytes we get |
1411 | 0 | i_samples_left = p_aout_buf ? p_aout_buf->i_nb_samples : 0; |
1412 | 0 | buffer_delay = p_sys->i_samples_delay * p_sys->i_sample_bytes * p_enc->fmt_out.audio.i_channels; |
1413 | | |
1414 | | //p_sys->i_buffer_out = p_sys->i_frame_size * chan * p_sys->i_sample_bytes |
1415 | | //Calculate how many bytes we would need from current buffer to fill frame |
1416 | 0 | size_t leftover_samples = __MAX(0,__MIN((ssize_t)i_samples_left, (ssize_t)(p_sys->i_frame_size - p_sys->i_samples_delay))); |
1417 | |
|
1418 | 0 | if( p_aout_buf && ( p_aout_buf->i_pts != VLC_TICK_INVALID ) ) |
1419 | 0 | { |
1420 | 0 | date_Set( &p_sys->buffer_date, p_aout_buf->i_pts ); |
1421 | | /* take back amount we have leftover from previous buffer*/ |
1422 | 0 | if( p_sys->i_samples_delay > 0 ) |
1423 | 0 | date_Decrement( &p_sys->buffer_date, p_sys->i_samples_delay ); |
1424 | 0 | } |
1425 | | /* Handle reordering here so we have p_sys->p_buffer always in correct |
1426 | | * order already */ |
1427 | 0 | if( p_aout_buf && p_sys->i_channels_to_reorder > 0 ) |
1428 | 0 | { |
1429 | 0 | aout_ChannelReorder( p_aout_buf->p_buffer, p_aout_buf->i_buffer, |
1430 | 0 | p_sys->i_channels_to_reorder, p_sys->pi_reorder_layout, |
1431 | 0 | p_enc->fmt_in.i_codec ); |
1432 | 0 | } |
1433 | | |
1434 | | // Check if we have enough samples in delay_buffer and current p_aout_buf to fill frame |
1435 | | // Or if we are cleaning up |
1436 | 0 | if( ( buffer_delay > 0 ) && |
1437 | 0 | ( ( p_aout_buf && ( leftover_samples <= p_aout_buf->i_nb_samples ) && |
1438 | 0 | ( (leftover_samples + p_sys->i_samples_delay ) >= p_sys->i_frame_size ) |
1439 | 0 | ) || |
1440 | 0 | ( !p_aout_buf ) |
1441 | 0 | ) |
1442 | 0 | ) |
1443 | 0 | { |
1444 | 0 | p_chain = handle_delay_buffer( p_enc, p_sys, buffer_delay, p_aout_buf, leftover_samples ); |
1445 | 0 | buffer_delay = 0; |
1446 | 0 | if( unlikely( !p_chain ) ) |
1447 | 0 | return NULL; |
1448 | 0 | } |
1449 | | |
1450 | 0 | if( unlikely( !p_aout_buf ) ) |
1451 | 0 | { |
1452 | 0 | msg_Dbg(p_enc,"Flushing.."); |
1453 | 0 | do { |
1454 | 0 | p_block = encode_avframe( p_enc, p_sys, NULL ); |
1455 | 0 | if( likely( p_block ) ) |
1456 | 0 | { |
1457 | 0 | block_ChainAppend( &p_chain, p_block ); |
1458 | 0 | } |
1459 | 0 | } while( p_block ); |
1460 | 0 | return p_chain; |
1461 | 0 | } |
1462 | | |
1463 | | |
1464 | 0 | while( ( p_aout_buf->i_nb_samples >= p_sys->i_frame_size ) || |
1465 | 0 | ( p_sys->b_variable && p_aout_buf->i_nb_samples ) ) |
1466 | 0 | { |
1467 | 0 | av_frame_unref( p_sys->frame ); |
1468 | |
|
1469 | 0 | if( p_sys->b_variable ) |
1470 | 0 | p_sys->frame->nb_samples = p_aout_buf->i_nb_samples; |
1471 | 0 | else |
1472 | 0 | p_sys->frame->nb_samples = p_sys->i_frame_size; |
1473 | 0 | p_sys->frame->format = p_sys->p_context->sample_fmt; |
1474 | 0 | #if API_CHANNEL_LAYOUT_STRUCT && LIBAVUTIL_VERSION_CHECK(57, 24, 100) |
1475 | 0 | av_channel_layout_copy(&p_sys->frame->ch_layout, &p_sys->p_context->ch_layout); |
1476 | | #else |
1477 | | p_sys->frame->channel_layout = p_sys->p_context->channel_layout; |
1478 | | p_sys->frame->channels = p_sys->p_context->channels; |
1479 | | #endif |
1480 | |
|
1481 | 0 | if( likely(date_Get( &p_sys->buffer_date ) != VLC_TICK_INVALID) ) |
1482 | 0 | { |
1483 | | /* Convert to AV timing */ |
1484 | 0 | p_sys->frame->pts = date_Get( &p_sys->buffer_date ) - VLC_TICK_0; |
1485 | 0 | p_sys->frame->pts = TO_AVSCALE( p_sys->frame->pts, p_sys->p_context->time_base ); |
1486 | 0 | } |
1487 | 0 | else p_sys->frame->pts = AV_NOPTS_VALUE; |
1488 | |
|
1489 | 0 | const int in_bytes = p_sys->frame->nb_samples * |
1490 | 0 | p_enc->fmt_out.audio.i_channels* p_sys->i_sample_bytes; |
1491 | |
|
1492 | 0 | if( p_sys->b_planar ) |
1493 | 0 | { |
1494 | 0 | aout_Deinterleave( p_sys->p_buffer, p_aout_buf->p_buffer, |
1495 | 0 | p_sys->frame->nb_samples, p_enc->fmt_out.audio.i_channels, p_enc->fmt_in.i_codec ); |
1496 | |
|
1497 | 0 | } |
1498 | 0 | else |
1499 | 0 | { |
1500 | 0 | memcpy(p_sys->p_buffer, p_aout_buf->p_buffer, in_bytes); |
1501 | 0 | } |
1502 | |
|
1503 | 0 | if( avcodec_fill_audio_frame( p_sys->frame, p_enc->fmt_out.audio.i_channels, |
1504 | 0 | p_sys->p_context->sample_fmt, |
1505 | 0 | p_sys->p_buffer, |
1506 | 0 | p_sys->i_buffer_out, |
1507 | 0 | DEFAULT_ALIGN) < 0 ) |
1508 | 0 | { |
1509 | 0 | msg_Err( p_enc, "filling error on encode" ); |
1510 | 0 | p_sys->frame->nb_samples = 0; |
1511 | 0 | } |
1512 | |
|
1513 | 0 | p_aout_buf->p_buffer += in_bytes; |
1514 | 0 | p_aout_buf->i_buffer -= in_bytes; |
1515 | 0 | p_aout_buf->i_nb_samples -= p_sys->frame->nb_samples; |
1516 | 0 | if( likely(date_Get( &p_sys->buffer_date ) != VLC_TICK_INVALID) ) |
1517 | 0 | date_Increment( &p_sys->buffer_date, p_sys->frame->nb_samples ); |
1518 | |
|
1519 | 0 | p_block = encode_avframe( p_enc, p_sys, p_sys->frame ); |
1520 | 0 | if( likely( p_block ) ) |
1521 | 0 | block_ChainAppend( &p_chain, p_block ); |
1522 | 0 | } |
1523 | | |
1524 | | // We have leftover samples that don't fill frame_size, and libavcodec doesn't seem to like |
1525 | | // that frame has more data than p_sys->i_frame_size most of the cases currently. |
1526 | 0 | if( p_aout_buf->i_nb_samples > 0 ) |
1527 | 0 | { |
1528 | 0 | memcpy( p_sys->p_buffer + buffer_delay, p_aout_buf->p_buffer, |
1529 | 0 | p_aout_buf->i_nb_samples * p_sys->i_sample_bytes * p_enc->fmt_out.audio.i_channels); |
1530 | 0 | p_sys->i_samples_delay += p_aout_buf->i_nb_samples; |
1531 | 0 | } |
1532 | |
|
1533 | 0 | return p_chain; |
1534 | 0 | } |
1535 | | |
1536 | | /***************************************************************************** |
1537 | | * EndVideoEnc: libavcodec encoder destruction |
1538 | | *****************************************************************************/ |
1539 | | void EndVideoEnc( encoder_t *p_enc ) |
1540 | 0 | { |
1541 | 0 | encoder_sys_t *p_sys = p_enc->p_sys; |
1542 | |
|
1543 | 0 | av_frame_free( &p_sys->frame ); |
1544 | |
|
1545 | 0 | vlc_avcodec_lock(); |
1546 | 0 | avcodec_free_context( &p_sys->p_context ); |
1547 | 0 | vlc_avcodec_unlock(); |
1548 | | |
1549 | |
|
1550 | 0 | av_free( p_sys->p_interleave_buf ); |
1551 | 0 | av_free( p_sys->p_buffer ); |
1552 | |
|
1553 | 0 | free( p_sys ); |
1554 | 0 | } |