encoder.c 46.8 KB
Newer Older
gbazin's avatar
   
gbazin committed
1
/*****************************************************************************
2
 * encoder.c: video and audio encoder using the libavcodec library
gbazin's avatar
   
gbazin committed
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
4
 * Copyright (C) 1999-2004 VLC authors and VideoLAN
gbazin's avatar
gbazin committed
5
 * $Id$
gbazin's avatar
   
gbazin committed
6
7
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
 *          Gildas Bazin <gbazin@videolan.org>
9
 *          Christophe Massiot <massiot@via.ecp.fr>
10
 * Part of the file Copyright (C) FFmpeg Project Developers
11
 * (mpeg4_default matrixes)
gbazin's avatar
   
gbazin committed
12
 *
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
13
14
15
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
gbazin's avatar
   
gbazin committed
16
17
18
19
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
20
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
gbazin's avatar
   
gbazin committed
22
 *
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
23
24
25
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
gbazin's avatar
   
gbazin committed
26
27
28
29
30
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
31
32
33
34
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

35
#include <vlc_common.h>
zorglub's avatar
zorglub committed
36
37
38
#include <vlc_aout.h>
#include <vlc_sout.h>
#include <vlc_codec.h>
39
#include <vlc_dialog.h>
40
#include <vlc_avcodec.h>
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
41
#include <vlc_cpu.h>
gbazin's avatar
   
gbazin committed
42

43
#define HAVE_MMX 1
44
#include <libavcodec/avcodec.h>
gbazin's avatar
   
gbazin committed
45

46
#include "avcodec.h"
47
#include "avcommon.h"
gbazin's avatar
   
gbazin committed
48

49
50
51
52
#if LIBAVUTIL_VERSION_CHECK( 52,2,6,0,0 )
# include <libavutil/channel_layout.h>
#endif

53
54
55
#define HURRY_UP_GUARD1 (450000)
#define HURRY_UP_GUARD2 (300000)
#define HURRY_UP_GUARD3 (100000)
gbazin's avatar
   
gbazin committed
56

57
58
#define MAX_FRAME_DELAY (FF_MAX_B_FRAMES + 2)

59
60
#define RAW_AUDIO_FRAME_SIZE (2048)

gbazin's avatar
   
gbazin committed
61
62
63
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
64
65
int  OpenEncoder ( vlc_object_t * );
void CloseEncoder( vlc_object_t * );
gbazin's avatar
   
gbazin committed
66
67

static block_t *EncodeVideo( encoder_t *, picture_t * );
68
static block_t *EncodeAudio( encoder_t *, block_t * );
gbazin's avatar
   
gbazin committed
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
struct thread_context_t;

/*****************************************************************************
 * thread_context_t : for multithreaded encoding
 *****************************************************************************/
struct thread_context_t
{
    VLC_COMMON_MEMBERS

    AVCodecContext  *p_context;
    int             (* pf_func)(AVCodecContext *c, void *arg);
    void            *arg;
    int             i_ret;

    vlc_mutex_t     lock;
    vlc_cond_t      cond;
dionoea's avatar
dionoea committed
86
    bool            b_work, b_done;
87
88
};

gbazin's avatar
   
gbazin committed
89
/*****************************************************************************
90
 * encoder_sys_t : libavcodec encoder descriptor
gbazin's avatar
   
gbazin committed
91
92
93
94
 *****************************************************************************/
struct encoder_sys_t
{
    /*
95
     * libavcodec properties
gbazin's avatar
   
gbazin committed
96
97
98
99
100
     */
    AVCodec         *p_codec;
    AVCodecContext  *p_context;

    /*
101
     * Common buffer mainly for audio as frame size in there needs usually be constant
gbazin's avatar
   
gbazin committed
102
     */
103
    uint8_t *p_buffer;
104
    size_t i_buffer_out;
gbazin's avatar
   
gbazin committed
105

gbazin's avatar
   
gbazin committed
106
    /*
107
     * Video properties
gbazin's avatar
   
gbazin committed
108
     */
gbazin's avatar
   
gbazin committed
109
110
    mtime_t i_last_ref_pts;
    mtime_t i_buggy_pts_detect;
111
    mtime_t i_last_pts;
dionoea's avatar
dionoea committed
112
    bool    b_inited;
gbazin's avatar
   
gbazin committed
113

gbazin's avatar
   
gbazin committed
114
115
116
    /*
     * Audio properties
     */
117
    int i_sample_bytes;
gbazin's avatar
   
gbazin committed
118
    int i_frame_size;
gbazin's avatar
   
gbazin committed
119
120
    int i_samples_delay;
    mtime_t i_pts;
121
122
123
124
125
126
127
128
129
130

    /* Encoding settings */
    int        i_key_int;
    int        i_b_frames;
    int        i_vtolerance;
    int        i_qmin;
    int        i_qmax;
    int        i_hq;
    int        i_rc_buffer_size;
    float      f_rc_buffer_aggressivity;
dionoea's avatar
dionoea committed
131
132
133
    bool       b_pre_me;
    bool       b_hurry_up;
    bool       b_interlace, b_interlace_me;
134
135
    float      f_i_quant_factor;
    int        i_noise_reduction;
dionoea's avatar
dionoea committed
136
137
    bool       b_mpeg4_matrix;
    bool       b_trellis;
gbazin's avatar
gbazin committed
138
    int        i_quality; /* for VBR */
139
    float      f_lumi_masking, f_dark_masking, f_p_masking, f_border_masking;
140
#if (LIBAVCODEC_VERSION_MAJOR < 55)
141
    int        i_luma_elim, i_chroma_elim;
142
#endif
143
    int        i_aac_profile; /* AAC profile to use.*/
144
145

    AVFrame    *frame;
146
147
};

148
static const char *const ppsz_enc_options[] = {
149
    "keyint", "bframes", "vt", "qmin", "qmax", "codec", "hq",
150
    "rc-buffer-size", "rc-buffer-aggressivity", "pre-me", "hurry-up",
ivoire's avatar
ivoire committed
151
    "interlace", "interlace-me", "i-quant-factor", "noise-reduction", "mpeg4-matrix",
152
    "trellis", "qscale", "strict", "lumi-masking", "dark-masking",
153
154
155
156
157
158
    "p-masking", "border-masking",
#if (LIBAVCODEC_VERSION_MAJOR < 55)
    "luma-elim-threshold", "chroma-elim-threshold",
#endif
    "aac-profile",
    NULL
gbazin's avatar
   
gbazin committed
159
160
};

161
162
163
164
165
166
167
168
169
static const uint16_t mpa_bitrate_tab[2][15] =
{
    {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},
    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
};

static const uint16_t mpa_freq_tab[6] =
{ 44100, 48000, 32000, 22050, 24000, 16000 };

170
static const uint16_t mpeg4_default_intra_matrix[64] = {
171
172
173
174
175
176
177
178
179
180
  8, 17, 18, 19, 21, 23, 25, 27,
 17, 18, 19, 21, 23, 25, 27, 28,
 20, 21, 22, 23, 24, 26, 28, 30,
 21, 22, 23, 24, 26, 28, 30, 32,
 22, 23, 24, 26, 28, 30, 32, 35,
 23, 24, 26, 28, 30, 32, 35, 38,
 25, 26, 28, 30, 32, 35, 38, 41,
 27, 28, 30, 32, 35, 38, 41, 45,
};

181
static const uint16_t mpeg4_default_non_intra_matrix[64] = {
182
183
184
185
186
187
188
189
190
191
 16, 17, 18, 19, 20, 21, 22, 23,
 17, 18, 19, 20, 21, 22, 23, 24,
 18, 19, 20, 21, 22, 23, 24, 25,
 19, 20, 21, 22, 23, 24, 26, 27,
 20, 21, 22, 23, 25, 26, 27, 28,
 21, 22, 23, 24, 26, 27, 28, 30,
 22, 23, 24, 26, 27, 28, 30, 31,
 23, 24, 25, 27, 28, 30, 31, 33,
};

gbazin's avatar
   
gbazin committed
192
/*****************************************************************************
gbazin's avatar
   
gbazin committed
193
 * OpenEncoder: probe the encoder
gbazin's avatar
   
gbazin committed
194
 *****************************************************************************/
195

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
196
int OpenEncoder( vlc_object_t *p_this )
gbazin's avatar
   
gbazin committed
197
198
{
    encoder_t *p_enc = (encoder_t *)p_this;
ivoire's avatar
ivoire committed
199
    encoder_sys_t *p_sys;
gbazin's avatar
   
gbazin committed
200
    AVCodecContext *p_context;
201
    AVCodec *p_codec = NULL;
gbazin's avatar
   
gbazin committed
202
    int i_codec_id, i_cat;
203
    const char *psz_namecodec;
204
205
    float f_val;
    char *psz_val;
gbazin's avatar
   
gbazin committed
206

207
208
209
    /* Initialization must be done before avcodec_find_encoder() */
    vlc_init_avcodec();

aurelien's avatar
aurelien committed
210
211
    config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );

212
213
214
    if( p_enc->fmt_out.i_codec == VLC_CODEC_MP3 )
    {
        i_cat = AUDIO_ES;
215
        i_codec_id = AV_CODEC_ID_MP3;
216
217
218
219
220
        psz_namecodec = "MPEG I/II Layer 3";
    }
    else if( p_enc->fmt_out.i_codec == VLC_CODEC_MP2 )
    {
        i_cat = AUDIO_ES;
221
        i_codec_id = AV_CODEC_ID_MP2;
222
223
        psz_namecodec = "MPEG I/II Layer 2";
    }
224
225
226
    else if( p_enc->fmt_out.i_codec == VLC_CODEC_MP1V )
    {
        i_cat = VIDEO_ES;
227
        i_codec_id = AV_CODEC_ID_MPEG1VIDEO;
228
229
        psz_namecodec = "MPEG-1 video";
    }
230
    else if( !GetFfmpegCodec( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
gbazin's avatar
   
gbazin committed
231
                             &psz_namecodec ) )
gbazin's avatar
   
gbazin committed
232
    {
233
234
235
        if( FindFfmpegChroma( p_enc->fmt_out.i_codec ) == PIX_FMT_NONE )
            return VLC_EGENERIC; /* handed chroma output */

236
        i_cat      = VIDEO_ES;
237
        i_codec_id = AV_CODEC_ID_RAWVIDEO;
238
        psz_namecodec = "Raw video";
gbazin's avatar
   
gbazin committed
239
240
    }

gbazin's avatar
   
gbazin committed
241
    if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
gbazin's avatar
   
gbazin committed
242
    {
gbazin's avatar
   
gbazin committed
243
        msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
244
        dialog_Fatal( p_enc, _("Streaming / Transcoding failed"),
245
                        _("\"%s\" is no video encoder."), psz_namecodec );
gbazin's avatar
   
gbazin committed
246
247
248
        return VLC_EGENERIC;
    }

gbazin's avatar
   
gbazin committed
249
250
251
    if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )
    {
        msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
252
        dialog_Fatal( p_enc, _("Streaming / Transcoding failed"),
253
                        _("\"%s\" is no audio encoder."), psz_namecodec );
gbazin's avatar
   
gbazin committed
254
255
256
        return VLC_EGENERIC;
    }

257
258
259
260
261
262
    if( p_enc->fmt_out.i_cat == SPU_ES )
    {
        /* We don't support subtitle encoding */
        return VLC_EGENERIC;
    }

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    char *psz_encoder = var_GetString( p_this, ENC_CFG_PREFIX "codec" );
    if( psz_encoder && *psz_encoder )
    {
        p_codec = avcodec_find_encoder_by_name( psz_encoder );
        if( !p_codec )
            msg_Err( p_this, "Encoder `%s' not found", psz_encoder );
        else if( p_codec->id != i_codec_id )
        {
            msg_Err( p_this, "Encoder `%s' can't handle %4.4s",
                    psz_encoder, (char*)&p_enc->fmt_out.i_codec );
            p_codec = NULL;
        }
    }
    free( psz_encoder );
    if( !p_codec )
        p_codec = avcodec_find_encoder( i_codec_id );
gbazin's avatar
   
gbazin committed
279
280
    if( !p_codec )
    {
281
        msg_Err( p_enc, "cannot find encoder %s\n"
282
283
"*** Your Libav/FFmpeg installation is crippled.   ***\n"
"*** Please check with your Libav/FFmpeg packager. ***\n"
284
"*** This is NOT a VLC media player issue.   ***", psz_namecodec );
285

286
        dialog_Fatal( p_enc, _("Streaming / Transcoding failed"), _(
287
288
289
290
/* I have had enough of all these MPEG-3 transcoding bug reports.
 * Downstream packager, you had better not patch this out, or I will be really
 * annoyed. Think about it - you don't want to fork the VLC translation files,
 * do you? -- Courmisch, 2008-10-22 */
291
"It seems your Libav/FFmpeg (libavcodec) installation lacks the following encoder:\n"
292
293
294
295
296
297
"%s.\n"
"If you don't know how to fix this, ask for support from your distribution.\n"
"\n"
"This is not an error inside VLC media player.\n"
"Do not contact the VideoLAN project about this issue.\n"),
            psz_namecodec );
gbazin's avatar
   
gbazin committed
298
299
300
        return VLC_EGENERIC;
    }

Jean-Paul Saman's avatar
Jean-Paul Saman committed
301
    /* Allocate the memory needed to store the encoder's structure */
ivoire's avatar
ivoire committed
302
    if( ( p_sys = calloc( 1, sizeof(encoder_sys_t) ) ) == NULL )
ivoire's avatar
ivoire committed
303
        return VLC_ENOMEM;
gbazin's avatar
   
gbazin committed
304
    p_enc->p_sys = p_sys;
305
    p_sys->i_samples_delay = 0;
gbazin's avatar
   
gbazin committed
306
307
    p_sys->p_codec = p_codec;

gbazin's avatar
   
gbazin committed
308
    p_sys->p_buffer = NULL;
309
    p_sys->i_buffer_out = 0;
gbazin's avatar
   
gbazin committed
310

311
312
    p_context = avcodec_alloc_context3(p_codec);
    p_sys->p_context = p_context;
313
    p_sys->p_context->codec_id = p_sys->p_codec->id;
314
    p_context->debug = var_InheritInteger( p_enc, "avcodec-debug" );
315
    p_context->opaque = (void *)p_this;
316
317

    /* set CPU capabilities */
318
#if LIBAVUTIL_VERSION_CHECK(51, 25, 0, 42, 100)
319
320
321
322
    av_set_cpu_flags_mask( INT_MAX & ~GetVlcDspMask() );
#else
    p_context->dsp_mask = GetVlcDspMask();
#endif
gbazin's avatar
   
gbazin committed
323

324
325
326
327
328
329
330
    p_sys->i_key_int = var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" );
    p_sys->i_b_frames = var_GetInteger( p_enc, ENC_CFG_PREFIX "bframes" );
    p_sys->i_vtolerance = var_GetInteger( p_enc, ENC_CFG_PREFIX "vt" ) * 1000;
    p_sys->b_interlace = var_GetBool( p_enc, ENC_CFG_PREFIX "interlace" );
    p_sys->b_interlace_me = var_GetBool( p_enc, ENC_CFG_PREFIX "interlace-me" );
    p_sys->b_pre_me = var_GetBool( p_enc, ENC_CFG_PREFIX "pre-me" );
    p_sys->b_hurry_up = var_GetBool( p_enc, ENC_CFG_PREFIX "hurry-up" );
331
332
333
334
335
336
337

    if( p_sys->b_hurry_up )
    {
        /* hurry up mode needs noise reduction, even small */
        p_sys->i_noise_reduction = 1;
    }

338
339
340
341
342
    p_sys->i_rc_buffer_size = var_GetInteger( p_enc, ENC_CFG_PREFIX "rc-buffer-size" );
    p_sys->f_rc_buffer_aggressivity = var_GetFloat( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity" );
    p_sys->f_i_quant_factor = var_GetFloat( p_enc, ENC_CFG_PREFIX "i-quant-factor" );
    p_sys->i_noise_reduction = var_GetInteger( p_enc, ENC_CFG_PREFIX "noise-reduction" );
    p_sys->b_mpeg4_matrix = var_GetBool( p_enc, ENC_CFG_PREFIX "mpeg4-matrix" );
343

344
345
346
    f_val = var_GetFloat( p_enc, ENC_CFG_PREFIX "qscale" );
    if( f_val < 0.01 || f_val > 255.0 ) f_val = 0;
    p_sys->i_quality = (int)(FF_QP2LAMBDA * f_val + 0.5);
347

348
    psz_val = var_GetString( p_enc, ENC_CFG_PREFIX "hq" );
349
    p_sys->i_hq = FF_MB_DECISION_RD;
350
    if( psz_val && *psz_val )
351
    {
352
        if( !strcmp( psz_val, "rd" ) )
353
            p_sys->i_hq = FF_MB_DECISION_RD;
354
        else if( !strcmp( psz_val, "bits" ) )
355
            p_sys->i_hq = FF_MB_DECISION_BITS;
356
        else if( !strcmp( psz_val, "simple" ) )
357
358
359
360
            p_sys->i_hq = FF_MB_DECISION_SIMPLE;
        else
            p_sys->i_hq = FF_MB_DECISION_RD;
    }
361
362
    else
        p_sys->i_hq = FF_MB_DECISION_RD;
363
364
365
366
367
368
    free( psz_val );

    p_sys->i_qmin = var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" );
    p_sys->i_qmax = var_GetInteger( p_enc, ENC_CFG_PREFIX "qmax" );
    p_sys->b_trellis = var_GetBool( p_enc, ENC_CFG_PREFIX "trellis" );

369
    p_context->strict_std_compliance = var_GetInteger( p_enc, ENC_CFG_PREFIX "strict" );
370
371
372
373
374

    p_sys->f_lumi_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "lumi-masking" );
    p_sys->f_dark_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "dark-masking" );
    p_sys->f_p_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "p-masking" );
    p_sys->f_border_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "border-masking" );
375
#if (LIBAVCODEC_VERSION_MAJOR < 55)
376
377
    p_sys->i_luma_elim = var_GetInteger( p_enc, ENC_CFG_PREFIX "luma-elim-threshold" );
    p_sys->i_chroma_elim = var_GetInteger( p_enc, ENC_CFG_PREFIX "chroma-elim-threshold" );
378
#endif
379
380

    psz_val = var_GetString( p_enc, ENC_CFG_PREFIX "aac-profile" );
381
    /* libavcodec uses faac encoder atm, and it has issues with
382
     * other than low-complexity profile, so default to that */
383
    p_sys->i_aac_profile = FF_PROFILE_AAC_LOW;
384
    if( psz_val && *psz_val )
385
    {
386
        if( !strncmp( psz_val, "main", 4 ) )
387
            p_sys->i_aac_profile = FF_PROFILE_AAC_MAIN;
388
        else if( !strncmp( psz_val, "low", 3 ) )
389
390
            p_sys->i_aac_profile = FF_PROFILE_AAC_LOW;
#if 0    /* Not supported by FAAC encoder */
391
        else if( !strncmp( psz_val, "ssr", 3 ) )
392
393
            p_sys->i_aac_profile = FF_PROFILE_AAC_SSR;
#endif
394
        else if( !strncmp( psz_val, "ltp", 3 ) )
395
            p_sys->i_aac_profile = FF_PROFILE_AAC_LTP;
396
#if LIBAVCODEC_VERSION_CHECK( 54, 19, 0, 35, 100 )
397
/* These require libavcodec with libfdk-aac */
398
399
400
401
        else if( !strncmp( psz_val, "hev2", 4 ) )
            p_sys->i_aac_profile = FF_PROFILE_AAC_HE_V2;
        else if( !strncmp( psz_val, "hev1", 4 ) )
            p_sys->i_aac_profile = FF_PROFILE_AAC_HE;
402
#endif
403
        else
404
        {
405
406
            msg_Warn( p_enc, "unknown AAC profile requested, setting it to low" );
            p_sys->i_aac_profile = FF_PROFILE_AAC_LOW;
407
        }
408
    }
409
    free( psz_val );
410

gbazin's avatar
   
gbazin committed
411
412
    if( p_enc->fmt_in.i_cat == VIDEO_ES )
    {
413
414
415
416
417
418
419
420
        if( !p_enc->fmt_in.video.i_width || !p_enc->fmt_in.video.i_height )
        {
            msg_Warn( p_enc, "invalid size %ix%i", p_enc->fmt_in.video.i_width,
                      p_enc->fmt_in.video.i_height );
            free( p_sys );
            return VLC_EGENERIC;
        }

421
        p_context->codec_type = AVMEDIA_TYPE_VIDEO;
422

gbazin's avatar
   
gbazin committed
423
424
        p_context->width = p_enc->fmt_in.video.i_width;
        p_context->height = p_enc->fmt_in.video.i_height;
gbazin's avatar
   
gbazin committed
425

426
427
        p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base;
        p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate;
428
429
430
431
432
433
434
435
436
437
438
        if( p_codec->supported_framerates )
        {
            AVRational target = {
                .num = p_enc->fmt_in.video.i_frame_rate,
                .den = p_enc->fmt_in.video.i_frame_rate_base,
            };
            int idx = av_find_nearest_q_idx(target, p_codec->supported_framerates);

            p_context->time_base.num = p_codec->supported_framerates[idx].den;
            p_context->time_base.den = p_codec->supported_framerates[idx].num;
        }
gbazin's avatar
   
gbazin committed
439

440
441
442
443
444
445
446
447
        /* Defaults from ffmpeg.c */
        p_context->qblur = 0.5;
        p_context->qcompress = 0.5;
        p_context->b_quant_offset = 1.25;
        p_context->b_quant_factor = 1.25;
        p_context->i_quant_offset = 0.0;
        p_context->i_quant_factor = -0.8;

448
449
450
451
        p_context->lumi_masking = p_sys->f_lumi_masking;
        p_context->dark_masking = p_sys->f_dark_masking;
        p_context->p_masking = p_sys->f_p_masking;
        p_context->border_masking = p_sys->f_border_masking;
452
#if (LIBAVCODEC_VERSION_MAJOR < 55)
453
454
        p_context->luma_elim_threshold = p_sys->i_luma_elim;
        p_context->chroma_elim_threshold = p_sys->i_chroma_elim;
455
#endif
456

457
458
        if( p_sys->i_key_int > 0 )
            p_context->gop_size = p_sys->i_key_int;
459
        p_context->max_b_frames =
460
            VLC_CLIP( p_sys->i_b_frames, 0, FF_MAX_B_FRAMES );
461
        p_context->b_frame_strategy = 0;
462
        if( !p_context->max_b_frames  &&
Laurent Aimar's avatar
Laurent Aimar committed
463
            (  p_enc->fmt_out.i_codec == VLC_CODEC_MPGV ||
464
               p_enc->fmt_out.i_codec == VLC_CODEC_MP2V ) )
465
            p_context->flags |= CODEC_FLAG_LOW_DELAY;
466

467
468
        av_reduce( &p_context->sample_aspect_ratio.num,
                   &p_context->sample_aspect_ratio.den,
Laurent Aimar's avatar
Laurent Aimar committed
469
470
                   p_enc->fmt_in.video.i_sar_num,
                   p_enc->fmt_in.video.i_sar_den, 1 << 30 );
gbazin's avatar
   
gbazin committed
471

gbazin's avatar
   
gbazin committed
472

473
        p_enc->fmt_in.i_codec = VLC_CODEC_I420;
474
        p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec;
475
        GetFfmpegChroma( &p_context->pix_fmt, &p_enc->fmt_in.video );
476

477
478
479
480
481
482
483
484
        if( p_codec->pix_fmts )
        {
            const enum PixelFormat *p = p_codec->pix_fmts;
            for( ; *p != -1; p++ )
            {
                if( *p == p_context->pix_fmt ) break;
            }
            if( *p == -1 ) p_context->pix_fmt = p_codec->pix_fmts[0];
485
486
            GetVlcChroma( &p_enc->fmt_in.video, p_context->pix_fmt );
            p_enc->fmt_in.i_codec = p_enc->fmt_in.video.i_chroma;
487
        }
Christophe Massiot's avatar
Christophe Massiot committed
488

489

490
491
        if ( p_sys->f_i_quant_factor != 0.0 )
            p_context->i_quant_factor = p_sys->f_i_quant_factor;
492

493
        p_context->noise_reduction = p_sys->i_noise_reduction;
494

495
        if ( p_sys->b_mpeg4_matrix )
496
        {
497
498
            p_context->intra_matrix = mpeg4_default_intra_matrix;
            p_context->inter_matrix = mpeg4_default_non_intra_matrix;
Christophe Massiot's avatar
Christophe Massiot committed
499
500
        }

501
        if ( p_sys->b_pre_me )
Christophe Massiot's avatar
Christophe Massiot committed
502
503
504
505
        {
            p_context->pre_me = 1;
            p_context->me_pre_cmp = FF_CMP_CHROMA;
        }
506

507
        if ( p_sys->b_interlace )
508
        {
509
510
            if ( p_context->height <= 280 )
            {
511
512
513
514
                if ( p_context->height != 16 || p_context->width != 16 )
                    msg_Warn( p_enc,
                        "disabling interlaced video because height=%d <= 280",
                        p_context->height );
515
516
517
518
519
520
521
            }
            else
            {
                p_context->flags |= CODEC_FLAG_INTERLACED_DCT;
                if ( p_sys->b_interlace_me )
                    p_context->flags |= CODEC_FLAG_INTERLACED_ME;
            }
522
523
        }

aballier's avatar
aballier committed
524
        p_context->trellis = p_sys->b_trellis;
525

526
        if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax )
527
            p_context->flags |= CODEC_FLAG_QSCALE;
528
        /* These codecs cause libavcodec to exit if thread_count is > 1.
529
530
           See libavcodec/mpegvideo_enc.c:MPV_encode_init and
           libavcodec/svq3.c , WMV2 calls MPV_encode_init also.
531
         */
532
533
534
535
536
537
538
539
540
541
542
543
544
545
        if ( i_codec_id == AV_CODEC_ID_FLV1 ||
             i_codec_id == AV_CODEC_ID_H261 ||
             i_codec_id == AV_CODEC_ID_LJPEG ||
             i_codec_id == AV_CODEC_ID_MJPEG ||
             i_codec_id == AV_CODEC_ID_H263 ||
             i_codec_id == AV_CODEC_ID_H263P ||
             i_codec_id == AV_CODEC_ID_MSMPEG4V1 ||
             i_codec_id == AV_CODEC_ID_MSMPEG4V2 ||
             i_codec_id == AV_CODEC_ID_MSMPEG4V3 ||
             i_codec_id == AV_CODEC_ID_WMV1 ||
             i_codec_id == AV_CODEC_ID_WMV2 ||
             i_codec_id == AV_CODEC_ID_RV10 ||
             i_codec_id == AV_CODEC_ID_RV20 ||
             i_codec_id == AV_CODEC_ID_SVQ3 )
546
            p_enc->i_threads = 1;
547

548
549
        if( p_sys->i_vtolerance > 0 )
            p_context->bit_rate_tolerance = p_sys->i_vtolerance;
550

dionoea's avatar
dionoea committed
551
552
        /* usually if someone sets bitrate, he likes more to get that bitrate
         * over quality should help 'normal' user to get asked bitrate
553
554
555
556
         */
        if( p_enc->fmt_out.i_bitrate > 0 && p_sys->i_qmax == 0 && p_sys->i_qmin == 0 )
        {
            p_sys->i_qmax = 51;
557
            p_sys->i_qmin = 3;
558
559
        }

560
        if( p_sys->i_qmin > 0 )
561
        {
562
            p_context->qmin = p_sys->i_qmin;
563
            p_context->mb_lmin = p_context->lmin = p_sys->i_qmin * FF_QP2LAMBDA;
564
        }
565
        if( p_sys->i_qmax > 0 )
566
        {
567
            p_context->qmax = p_sys->i_qmax;
568
            p_context->mb_lmax = p_context->lmax = p_sys->i_qmax * FF_QP2LAMBDA;
569
        }
570
571
        p_context->max_qdiff = 3;

572
        p_context->mb_decision = p_sys->i_hq;
gbazin's avatar
gbazin committed
573
574
575
576
577

        if( p_sys->i_quality )
        {
            p_context->flags |= CODEC_FLAG_QSCALE;
            p_context->global_quality = p_sys->i_quality;
dionoea's avatar
dionoea committed
578
579
        }
        else
580
581
        {
            p_context->rc_qsquish = 1.0;
582
583
584
585
586
            if( p_sys->i_rc_buffer_size )
            {
                p_context->rc_max_rate = p_enc->fmt_out.i_bitrate;
                p_context->rc_min_rate = p_enc->fmt_out.i_bitrate;
            }
587
588
589
590
591
            p_context->rc_buffer_size = p_sys->i_rc_buffer_size;
            /* This is from ffmpeg's ffmpeg.c : */
            p_context->rc_initial_buffer_occupancy
                = p_sys->i_rc_buffer_size * 3/4;
            p_context->rc_buffer_aggressivity = p_sys->f_rc_buffer_aggressivity;
gbazin's avatar
gbazin committed
592
        }
gbazin's avatar
   
gbazin committed
593
594
595
    }
    else if( p_enc->fmt_in.i_cat == AUDIO_ES )
    {
596
        /* work around bug in libmp3lame encoding */
597
        if( i_codec_id == AV_CODEC_ID_MP3 && p_enc->fmt_in.audio.i_channels > 2 )
598
599
            p_enc->fmt_in.audio.i_channels = 2;

600
        p_context->codec_type  = AVMEDIA_TYPE_AUDIO;
601
602
        p_context->sample_fmt  = p_codec->sample_fmts ?
                                    p_codec->sample_fmts[0] :
603
                                    AV_SAMPLE_FMT_S16;
604

605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
        /* Try to match avcodec input format to vlc format so we could avoid one
           format conversion */
        if( GetVlcAudioFormat( p_context->sample_fmt ) != p_enc->fmt_in.i_codec )
        {
            msg_Dbg( p_enc, "Trying to find more suitable sample format instead of %s", av_get_sample_fmt_name( p_context->sample_fmt ) );
            for( unsigned int i=0; p_codec->sample_fmts[i] != -1; i++ )
            {
                if( GetVlcAudioFormat( p_codec->sample_fmts[i] ) == p_enc->fmt_in.i_codec )
                {
                    p_context->sample_fmt = p_codec->sample_fmts[i];
                    msg_Dbg( p_enc, "Using %s as new sample format", av_get_sample_fmt_name( p_context->sample_fmt ) );
                    break;
                }
            }
        }
620
621
622
623
        // Try if we can use interleaved format for codec input as VLC doesn't really do planar audio yet
        // FIXME: Remove when planar/interleaved audio in vlc is equally supported
        if( av_sample_fmt_is_planar( p_context->sample_fmt ) )
        {
624
            msg_Dbg( p_enc, "Trying to find packet sample format instead of planar %s", av_get_sample_fmt_name( p_context->sample_fmt ) );
625
626
627
628
629
            for( unsigned int i=0; p_codec->sample_fmts[i] != -1; i++ )
            {
                if( !av_sample_fmt_is_planar( p_codec->sample_fmts[i] ) )
                {
                    p_context->sample_fmt = p_codec->sample_fmts[i];
630
                    msg_Dbg( p_enc, "Changing to packet format %s as new sample format", av_get_sample_fmt_name( p_context->sample_fmt ) );
631
632
633
634
                    break;
                }
            }
        }
635
        msg_Dbg( p_enc, "Ended up using %s as sample format", av_get_sample_fmt_name( p_context->sample_fmt ) );
636
637
        p_enc->fmt_in.i_codec  = GetVlcAudioFormat( p_context->sample_fmt );

638
        p_context->sample_rate = p_enc->fmt_out.audio.i_rate;
639
640
        p_context->time_base.num = 1;
        p_context->time_base.den = p_context->sample_rate;
641
        p_context->channels    = p_enc->fmt_out.audio.i_channels;
642
643
644
#if LIBAVUTIL_VERSION_CHECK( 52, 2, 6, 0, 0)
        p_context->channel_layout = av_get_default_channel_layout( p_context->channels );
#endif
645

646
        if ( p_enc->fmt_out.i_codec == VLC_CODEC_MP4A )
647
648
        {
            /* XXX: FAAC does resample only when setting the INPUT samplerate
dionoea's avatar
dionoea committed
649
             * to the desired value (-R option of the faac frontend)
650
            p_enc->fmt_in.audio.i_rate = p_context->sample_rate;*/
651
652
            /* vlc should default to low-complexity profile, faac encoder
             * has bug and aac audio has issues otherwise atm */
653
            p_context->profile = p_sys->i_aac_profile;
654
        }
gbazin's avatar
   
gbazin committed
655
656
657
    }

    /* Misc parameters */
gbazin's avatar
   
gbazin committed
658
    p_context->bit_rate = p_enc->fmt_out.i_bitrate;
gbazin's avatar
   
gbazin committed
659

660
661
    /* Set reasonable defaults to VP8, based on
       libvpx-720p preset from libvpx ffmpeg-patch */
662
    if( i_codec_id == AV_CODEC_ID_VP8 )
663
    {
664
        /* Lets give bitrate tolerance */
665
        p_context->bit_rate_tolerance = __MAX(2 * (int)p_enc->fmt_out.i_bitrate, p_sys->i_vtolerance );
666
667
        /* default to 120 frames between keyframe */
        if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" ) )
668
            p_context->gop_size = 120;
669
        /* Don't set rc-values atm, they were from time before
670
           libvpx was officially in FFmpeg */
671
672
        //p_context->rc_max_rate = 24 * 1000 * 1000; //24M
        //p_context->rc_min_rate = 40 * 1000; // 40k
673
        /* seems that FFmpeg presets have 720p as divider for buffers */
674
        if( p_enc->fmt_out.video.i_height >= 720 )
675
        {
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
            /* Check that we don't overrun users qmin/qmax values */
            if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ) )
            {
                p_context->qmin = 10;
                p_context->mb_lmin = p_context->lmin = 10 * FF_QP2LAMBDA;
            }

            if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmax" ) )
            {
                p_context->qmax = 42;
                p_context->mb_lmax = p_context->lmax = 42 * FF_QP2LAMBDA;
            }

            } else {
            if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ) )
            {
                p_context->qmin = 1;
                p_context->mb_lmin = p_context->lmin = FF_QP2LAMBDA;
            }
695
        }
696
697


698
#if 0 /* enable when/if vp8 encoder is accepted in libavcodec */
699
700
701
702
703
        p_context->lag = 16;
        p_context->level = 216;
        p_context->profile = 0;
        p_context->rc_buffer_aggressivity = 0.95;
        p_context->token_partitions = 4;
704
        p_context->mb_static_threshold = 0;
705
#endif
706
707
    }

708
    if( i_codec_id == AV_CODEC_ID_RAWVIDEO )
gbazin's avatar
   
gbazin committed
709
    {
710
        /* XXX: hack: Force same codec (will be handled by transcode) */
711
        p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
712
        GetFfmpegChroma( &p_context->pix_fmt, &p_enc->fmt_in.video );
gbazin's avatar
   
gbazin committed
713
714
715
716
717
718
719
    }

    /* Make sure we get extradata filled by the encoder */
    p_context->extradata_size = 0;
    p_context->extradata = NULL;
    p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;

720
721
722
723
724
    if( p_enc->i_threads >= 1)
        p_context->thread_count = p_enc->i_threads;
    else
        p_context->thread_count = vlc_GetCPUCount();

725
726
    int ret;
    vlc_avcodec_lock();
727
    ret = avcodec_open2( p_context, p_codec, NULL /* options */ );
728
729
    vlc_avcodec_unlock();
    if( ret )
gbazin's avatar
   
gbazin committed
730
    {
731
        if( p_enc->fmt_in.i_cat == AUDIO_ES &&
732
733
             (p_context->channels > 2 || i_codec_id == AV_CODEC_ID_MP2
               || i_codec_id == AV_CODEC_ID_MP3) )
gbazin's avatar
   
gbazin committed
734
        {
735
736
737
738
739
740
741
            if( p_context->channels > 2 )
            {
                p_context->channels = 2;
                p_enc->fmt_in.audio.i_channels = 2; // FIXME
                msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
            }

742
            if( i_codec_id == AV_CODEC_ID_MP2 || i_codec_id == AV_CODEC_ID_MP3 )
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
            {
                int i_frequency, i;

                for ( i_frequency = 0; i_frequency < 6; i_frequency++ )
                {
                    if ( p_enc->fmt_out.audio.i_rate
                            == mpa_freq_tab[i_frequency] )
                        break;
                }
                if ( i_frequency == 6 )
                {
                    msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
                             p_enc->fmt_out.audio.i_rate );
                    free( p_sys );
                    return VLC_EGENERIC;
                }

                for ( i = 1; i < 14; i++ )
                {
                    if ( p_enc->fmt_out.i_bitrate / 1000
                          <= mpa_bitrate_tab[i_frequency / 3][i] )
                        break;
                }
                if ( p_enc->fmt_out.i_bitrate / 1000
                      != mpa_bitrate_tab[i_frequency / 3][i] )
                {
                    msg_Warn( p_enc,
                              "MPEG audio doesn't support bitrate=%d, using %d",
                              p_enc->fmt_out.i_bitrate,
                              mpa_bitrate_tab[i_frequency / 3][i] * 1000 );
                    p_enc->fmt_out.i_bitrate =
                        mpa_bitrate_tab[i_frequency / 3][i] * 1000;
                    p_context->bit_rate = p_enc->fmt_out.i_bitrate;
                }
            }

            p_context->codec = NULL;
780
            vlc_avcodec_lock();
781
            ret = avcodec_open2( p_context, p_codec, NULL /* options */ );
782
783
            vlc_avcodec_unlock();
            if( ret )
gbazin's avatar
   
gbazin committed
784
785
            {
                msg_Err( p_enc, "cannot open encoder" );
786
                dialog_Fatal( p_enc,
dionoea's avatar
dionoea committed
787
                                _("Streaming / Transcoding failed"),
788
                                "%s", _("VLC could not open the encoder.") );
789
                free( p_sys );
gbazin's avatar
   
gbazin committed
790
791
792
793
794
795
                return VLC_EGENERIC;
            }
        }
        else
        {
            msg_Err( p_enc, "cannot open encoder" );
796
            dialog_Fatal( p_enc, _("Streaming / Transcoding failed"),
797
                            "%s", _("VLC could not open the encoder.") );
798
            free( p_sys );
gbazin's avatar
   
gbazin committed
799
800
            return VLC_EGENERIC;
        }
gbazin's avatar
   
gbazin committed
801
802
    }

803
    if( i_codec_id == AV_CODEC_ID_FLAC )
804
    {
805
        p_enc->fmt_out.i_extra = 4 + 1 + 3 + p_context->extradata_size;
806
        p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
807
808
809
        if( p_enc->fmt_out.p_extra )
        {
            uint8_t *p = p_enc->fmt_out.p_extra;
810
811
812
813
814
            p[0] = 0x66;    /* f */
            p[1] = 0x4C;    /* L */
            p[2] = 0x61;    /* a */
            p[3] = 0x43;    /* C */
            p[4] = 0x80;    /* streaminfo block, last block before audio */
815
816
817
818
819
820
821
822
823
            p[5] = ( p_context->extradata_size >> 16 ) & 0xff;
            p[6] = ( p_context->extradata_size >>  8 ) & 0xff;
            p[7] = ( p_context->extradata_size       ) & 0xff;
            memcpy( &p[8], p_context->extradata, p_context->extradata_size );
        }
        else
        {
            p_enc->fmt_out.i_extra = 0;
        }
824
    }
825
826
827
828
829
830
    else
    {
        p_enc->fmt_out.i_extra = p_context->extradata_size;
        if( p_enc->fmt_out.i_extra )
        {
            p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
831
832
833
834
            if ( p_enc->fmt_out.p_extra == NULL )
            {
                goto error;
            }
835
836
837
838
839
            memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
                    p_enc->fmt_out.i_extra );
        }
    }

gbazin's avatar
   
gbazin committed
840
841
    p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;

gbazin's avatar
   
gbazin committed
842
843
    if( p_enc->fmt_in.i_cat == AUDIO_ES )
    {
844
845
846
        p_enc->fmt_in.i_codec = GetVlcAudioFormat( p_sys->p_context->sample_fmt );
        p_enc->fmt_in.audio.i_bitspersample = aout_BitsPerSample( p_enc->fmt_in.i_codec );

847
848
849
850
        p_sys->i_sample_bytes = (p_enc->fmt_in.audio.i_bitspersample / 8) *
                                p_context->channels;
        p_sys->i_frame_size = p_context->frame_size > 1 ?
                                    p_context->frame_size :
851
                                    FF_MIN_BUFFER_SIZE;
852
        p_sys->p_buffer = malloc( p_sys->i_frame_size * p_sys->i_sample_bytes );
853
        if ( unlikely( p_sys->p_buffer == NULL ) )
854
855
856
        {
            goto error;
        }
857
        p_enc->fmt_out.audio.i_blockalign = p_context->block_align;
858
        p_enc->fmt_out.audio.i_bitspersample = aout_BitsPerSample( p_enc->fmt_out.i_codec );
859

860
        p_sys->i_buffer_out = p_sys->i_frame_size * p_sys->i_sample_bytes;
gbazin's avatar
   
gbazin committed
861
862
    }

863
864
865
866
867
    p_sys->frame = avcodec_alloc_frame();
    if( !p_sys->frame )
    {
        goto error;
    }
gbazin's avatar
   
gbazin committed
868
    msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
869
    
870
871
872
    p_enc->pf_encode_video = EncodeVideo;
    p_enc->pf_encode_audio = EncodeAudio;

gbazin's avatar
   
gbazin committed
873

gbazin's avatar
   
gbazin committed
874
    return VLC_SUCCESS;
875
876
877
878
879
error:
    free( p_enc->fmt_out.p_extra );
    free( p_sys->p_buffer );
    free( p_sys );
    return VLC_ENOMEM;
gbazin's avatar
   
gbazin committed
880
881
882
883
884
885
886
887
}

/****************************************************************************
 * EncodeVideo: the whole thing
 ****************************************************************************/
static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
{
    encoder_sys_t *p_sys = p_enc->p_sys;
888
889
    int i_out, i_plane, i_got_packet=1;
    AVPacket av_pkt;
890

891
892
893
894
    /* Initialize the video output buffer the first time.
     * This is done here instead of OpenEncoder() because we need the actual
     * bits_per_pixel value, without having to assume anything.
     */
895
896
897
    const int bytesPerPixel = p_enc->fmt_out.video.i_bits_per_pixel ?
                         p_enc->fmt_out.video.i_bits_per_pixel / 8 : 3;
    const int blocksize = __MAX( FF_MIN_BUFFER_SIZE,bytesPerPixel * p_sys->p_context->height * p_sys->p_context->width + 200 );
898
    block_t *p_block = block_Alloc( blocksize );
gbazin's avatar
   
gbazin committed
899

900
901
902
903
904
905
#if (LIBAVCODEC_VERSION_MAJOR >= 54)
    /*We don't use av_pkt with major_version < 54, so no point init it*/
    av_init_packet( &av_pkt );
    av_pkt.data = p_block->p_buffer;
    av_pkt.size = p_block->i_buffer;
#endif
906
    if( likely(p_pict) ) {
907
        avcodec_get_frame_defaults( p_sys->frame );
908
909
        for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
        {
910
911
            p_sys->frame->data[i_plane] = p_pict->p[i_plane].p_pixels;
            p_sys->frame->linesize[i_plane] = p_pict->p[i_plane].i_pitch;
912
913
        }

914
        /* Let libavcodec select the frame type */
915
        p_sys->frame->pict_type = 0;
916

917
918
919
        p_sys->frame->repeat_pict = p_pict->i_nb_fields - 2;
        p_sys->frame->interlaced_frame = !p_pict->b_progressive;
        p_sys->frame->top_field_first = !!p_pict->b_top_field_first;
920

921
        /* Set the pts of the frame being encoded */
922
        p_sys->frame->pts = p_pict->date ? p_pict->date : (int64_t)AV_NOPTS_VALUE;
923

924
        if ( p_sys->b_hurry_up && p_sys->frame->pts != (int64_t)AV_NOPTS_VALUE )
925
        {
926
            mtime_t current_date = mdate();
927

928
            if ( current_date + HURRY_UP_GUARD3 > p_sys->frame->pts )
929
930
931
932
933
934
            {
                p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE;
                p_sys->p_context->trellis = 0;
                msg_Dbg( p_enc, "hurry up mode 3" );
            }
            else
935
            {
936
                p_sys->p_context->mb_decision = p_sys->i_hq;
937