encoder.c 35.2 KB
Newer Older
gbazin's avatar
 
gbazin committed
1
2
3
/*****************************************************************************
 * encoder.c: video and audio encoder using the ffmpeg library
 *****************************************************************************
4
 * Copyright (C) 1999-2004 the VideoLAN team
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
11
 * Part of the file Copyright (C) FFMPEG Project Developers
 * (mpeg4_default matrixes)
gbazin's avatar
 
gbazin committed
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (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
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
dionoea's avatar
dionoea committed
25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
gbazin's avatar
 
gbazin committed
26
27
28
29
30
31
32
33
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/aout.h>
34
#include <vlc/sout.h>
gbazin's avatar
 
gbazin committed
35
36
37
#include <vlc/decoder.h>

/* ffmpeg header */
38
#define HAVE_MMX 1
gbazin's avatar
 
gbazin committed
39
40
41
42
43
44
#ifdef HAVE_FFMPEG_AVCODEC_H
#   include <ffmpeg/avcodec.h>
#else
#   include <avcodec.h>
#endif

45
46
47
#if LIBAVCODEC_BUILD < 4704
#   define AV_NOPTS_VALUE 0
#endif
48
49
50
#if LIBAVCODEC_BUILD < 4684
#    define FF_QP2LAMBDA 118
#endif
51

gbazin's avatar
 
gbazin committed
52
53
54
#include "ffmpeg.h"

#define AVCODEC_MAX_VIDEO_FRAME_SIZE (3*1024*1024)
55
56
57
#define HURRY_UP_GUARD1 (450000)
#define HURRY_UP_GUARD2 (300000)
#define HURRY_UP_GUARD3 (100000)
gbazin's avatar
 
gbazin committed
58

59
60
#define MAX_FRAME_DELAY (FF_MAX_B_FRAMES + 2)

gbazin's avatar
 
gbazin committed
61
62
63
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
gbazin's avatar
   
gbazin committed
64
65
int  E_(OpenEncoder) ( vlc_object_t * );
void E_(CloseEncoder)( vlc_object_t * );
gbazin's avatar
 
gbazin committed
66
67
68
69

static block_t *EncodeVideo( encoder_t *, picture_t * );
static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
struct thread_context_t;
static int FfmpegThread( struct thread_context_t *p_context );
static int FfmpegExecute( AVCodecContext *s,
                          int (*pf_func)(AVCodecContext *c2, void *arg2),
                          void **arg, int *ret, int count );

/*****************************************************************************
 * thread_context_t : for multithreaded encoding
 *****************************************************************************/
#if LIBAVCODEC_BUILD >= 4702
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;
    vlc_bool_t      b_work, b_done;
};
#endif

gbazin's avatar
 
gbazin committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*****************************************************************************
 * encoder_sys_t : ffmpeg encoder descriptor
 *****************************************************************************/
struct encoder_sys_t
{
    /*
     * Ffmpeg properties
     */
    AVCodec         *p_codec;
    AVCodecContext  *p_context;

    /*
     * Common properties
     */
gbazin's avatar
   
gbazin committed
109
110
    char *p_buffer;
    char *p_buffer_out;
gbazin's avatar
 
gbazin committed
111

gbazin's avatar
   
gbazin committed
112
    /*
113
     * Video properties
gbazin's avatar
   
gbazin committed
114
     */
gbazin's avatar
 
gbazin committed
115
116
    mtime_t i_last_ref_pts;
    mtime_t i_buggy_pts_detect;
117
    mtime_t i_last_pts;
118
    vlc_bool_t b_inited;
gbazin's avatar
 
gbazin committed
119

gbazin's avatar
   
gbazin committed
120
121
122
    /*
     * Audio properties
     */
gbazin's avatar
 
gbazin committed
123
    int i_frame_size;
gbazin's avatar
   
gbazin committed
124
125
    int i_samples_delay;
    mtime_t i_pts;
126
127
128
129
130
131
132
133
134
135
136
137
138

    /* Encoding settings */
    int        i_key_int;
    int        i_b_frames;
    int        i_vtolerance;
    int        i_qmin;
    int        i_qmax;
    int        i_hq;
    vlc_bool_t b_strict_rc;
    int        i_rc_buffer_size;
    float      f_rc_buffer_aggressivity;
    vlc_bool_t b_pre_me;
    vlc_bool_t b_hurry_up;
139
    vlc_bool_t b_interlace, b_interlace_me;
140
141
142
143
    float      f_i_quant_factor;
    int        i_noise_reduction;
    vlc_bool_t b_mpeg4_matrix;
    vlc_bool_t b_trellis;
gbazin's avatar
gbazin committed
144
    int        i_quality; /* for VBR */
145
146
    float      f_lumi_masking, f_dark_masking, f_p_masking, f_border_masking;
    int        i_luma_elim, i_chroma_elim;
147
148
149
150

    /* Used to work around stupid timestamping behaviour in libavcodec */
    uint64_t i_framenum;
    mtime_t  pi_delay_pts[MAX_FRAME_DELAY];
151
152
153
};

static const char *ppsz_enc_options[] = {
154
    "keyint", "bframes", "vt", "qmin", "qmax", "hq", "strict-rc",
155
156
    "rc-buffer-size", "rc-buffer-aggressivity", "pre-me", "hurry-up",
    "interlace", "i-quant-factor", "noise-reduction", "mpeg4-matrix",
157
158
159
    "trellis", "qscale", "strict", "lumi-masking", "dark-masking",
    "p-masking", "border-masking", "luma-elim-threshold",
    "chroma-elim-threshold", NULL
gbazin's avatar
 
gbazin committed
160
161
};

162
163
164
165
166
167
168
169
170
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 };

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
static const int16_t mpeg4_default_intra_matrix[64] = {
  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,
};

static const int16_t mpeg4_default_non_intra_matrix[64] = {
 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
194
/*****************************************************************************
gbazin's avatar
   
gbazin committed
195
 * OpenEncoder: probe the encoder
gbazin's avatar
 
gbazin committed
196
 *****************************************************************************/
197

gbazin's avatar
   
gbazin committed
198
int E_(OpenEncoder)( vlc_object_t *p_this )
gbazin's avatar
 
gbazin committed
199
200
201
{
    encoder_t *p_enc = (encoder_t *)p_this;
    encoder_sys_t *p_sys = p_enc->p_sys;
gbazin's avatar
   
gbazin committed
202
    AVCodecContext *p_context;
gbazin's avatar
 
gbazin committed
203
    AVCodec *p_codec;
gbazin's avatar
   
gbazin committed
204
205
    int i_codec_id, i_cat;
    char *psz_namecodec;
206
    vlc_value_t val;
207
208
209
    vlc_value_t lockval;

    var_Get( p_enc->p_libvlc, "avcodec", &lockval );
gbazin's avatar
 
gbazin committed
210

gbazin's avatar
   
gbazin committed
211
    if( !E_(GetFfmpegCodec)( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
gbazin's avatar
   
gbazin committed
212
                             &psz_namecodec ) )
gbazin's avatar
 
gbazin committed
213
    {
214
215
216
217
218
219
220
221
        if( E_(GetFfmpegChroma)( p_enc->fmt_out.i_codec ) < 0 )
        {
            /* handed chroma output */
            return VLC_EGENERIC;
        }
        i_cat      = VIDEO_ES;
        i_codec_id = CODEC_ID_RAWVIDEO;
        psz_namecodec = "Raw video";
gbazin's avatar
 
gbazin committed
222
223
    }

gbazin's avatar
   
gbazin committed
224
    if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
gbazin's avatar
 
gbazin committed
225
    {
gbazin's avatar
   
gbazin committed
226
        msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
gbazin's avatar
 
gbazin committed
227
228
229
        return VLC_EGENERIC;
    }

gbazin's avatar
   
gbazin committed
230
231
232
233
234
235
    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 );
        return VLC_EGENERIC;
    }

Jean-Paul Saman's avatar
Jean-Paul Saman committed
236
    /* Initialization must be done before avcodec_find_encoder() */
gbazin's avatar
 
gbazin committed
237
238
    E_(InitLibavcodec)(p_this);

gbazin's avatar
   
gbazin committed
239
240
241
242
243
244
245
    p_codec = avcodec_find_encoder( i_codec_id );
    if( !p_codec )
    {
        msg_Err( p_enc, "cannot find encoder %s", psz_namecodec );
        return VLC_EGENERIC;
    }

Jean-Paul Saman's avatar
Jean-Paul Saman committed
246
    /* Allocate the memory needed to store the encoder's structure */
gbazin's avatar
 
gbazin committed
247
248
249
250
251
    if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
    {
        msg_Err( p_enc, "out of memory" );
        return VLC_EGENERIC;
    }
252
    memset( p_sys, 0, sizeof(encoder_sys_t) );
gbazin's avatar
 
gbazin committed
253
254
255
256
    p_enc->p_sys = p_sys;
    p_sys->p_codec = p_codec;

    p_enc->pf_encode_video = EncodeVideo;
gbazin's avatar
   
gbazin committed
257
    p_enc->pf_encode_audio = EncodeAudio;
gbazin's avatar
 
gbazin committed
258

gbazin's avatar
   
gbazin committed
259
260
261
262
    p_sys->p_buffer_out = NULL;
    p_sys->p_buffer = NULL;

    p_sys->p_context = p_context = avcodec_alloc_context();
263
264
    p_context->debug = config_GetInt( p_enc, "ffmpeg-debug" );
    p_context->opaque = (void *)p_this;
gbazin's avatar
   
gbazin committed
265
266
267

    /* Set CPU capabilities */
    p_context->dsp_mask = 0;
gbazin's avatar
   
gbazin committed
268
    if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMX) )
gbazin's avatar
   
gbazin committed
269
    {
gbazin's avatar
   
gbazin committed
270
        p_context->dsp_mask |= FF_MM_MMX;
gbazin's avatar
   
gbazin committed
271
    }
gbazin's avatar
   
gbazin committed
272
    if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT) )
gbazin's avatar
   
gbazin committed
273
    {
gbazin's avatar
   
gbazin committed
274
        p_context->dsp_mask |= FF_MM_MMXEXT;
gbazin's avatar
   
gbazin committed
275
    }
gbazin's avatar
   
gbazin committed
276
    if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW) )
gbazin's avatar
   
gbazin committed
277
    {
gbazin's avatar
   
gbazin committed
278
        p_context->dsp_mask |= FF_MM_3DNOW;
gbazin's avatar
   
gbazin committed
279
    }
gbazin's avatar
   
gbazin committed
280
    if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE) )
gbazin's avatar
 
gbazin committed
281
    {
gbazin's avatar
   
gbazin committed
282
283
        p_context->dsp_mask |= FF_MM_SSE;
        p_context->dsp_mask |= FF_MM_SSE2;
gbazin's avatar
 
gbazin committed
284
285
    }

286
    sout_CfgParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
287
288
289
290
291
292
293
294
295
296
297
298
299

    var_Get( p_enc, ENC_CFG_PREFIX "keyint", &val );
    p_sys->i_key_int = val.i_int;

    var_Get( p_enc, ENC_CFG_PREFIX "bframes", &val );
    p_sys->i_b_frames = val.i_int;

    var_Get( p_enc, ENC_CFG_PREFIX "vt", &val );
    p_sys->i_vtolerance = val.i_int;

    var_Get( p_enc, ENC_CFG_PREFIX "interlace", &val );
    p_sys->b_interlace = val.b_bool;

300
301
302
    var_Get( p_enc, ENC_CFG_PREFIX "interlace-me", &val );
    p_sys->b_interlace_me = val.b_bool;

303
    var_Get( p_enc, ENC_CFG_PREFIX "pre-me", &val );
304
305
    p_sys->b_pre_me = val.b_bool;

306
    var_Get( p_enc, ENC_CFG_PREFIX "hurry-up", &val );
307
308
309
310
311
312
313
    p_sys->b_hurry_up = val.b_bool;
    if( p_sys->b_hurry_up )
    {
        /* hurry up mode needs noise reduction, even small */
        p_sys->i_noise_reduction = 1;
    }

314
    var_Get( p_enc, ENC_CFG_PREFIX "strict-rc", &val );
315
    p_sys->b_strict_rc = val.b_bool;
316
    var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-size", &val );
317
    p_sys->i_rc_buffer_size = val.i_int;
318
    var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity", &val );
319
320
    p_sys->f_rc_buffer_aggressivity = val.f_float;

321
    var_Get( p_enc, ENC_CFG_PREFIX "i-quant-factor", &val );
322
323
    p_sys->f_i_quant_factor = val.f_float;

324
    var_Get( p_enc, ENC_CFG_PREFIX "noise-reduction", &val );
325
326
    p_sys->i_noise_reduction = val.i_int;

327
    var_Get( p_enc, ENC_CFG_PREFIX "mpeg4-matrix", &val );
328
329
    p_sys->b_mpeg4_matrix = val.b_bool;

gbazin's avatar
gbazin committed
330
331
332
333
    var_Get( p_enc, ENC_CFG_PREFIX "qscale", &val );
    if( val.f_float < 0.01 || val.f_float > 255.0 ) val.f_float = 0;
    p_sys->i_quality = (int)(FF_QP2LAMBDA * val.f_float + 0.5);

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
    var_Get( p_enc, ENC_CFG_PREFIX "hq", &val );
    if( val.psz_string && *val.psz_string )
    {
        if( !strcmp( val.psz_string, "rd" ) )
            p_sys->i_hq = FF_MB_DECISION_RD;
        else if( !strcmp( val.psz_string, "bits" ) )
            p_sys->i_hq = FF_MB_DECISION_BITS;
        else if( !strcmp( val.psz_string, "simple" ) )
            p_sys->i_hq = FF_MB_DECISION_SIMPLE;
        else
            p_sys->i_hq = FF_MB_DECISION_RD;
    }
    if( val.psz_string ) free( val.psz_string );

    var_Get( p_enc, ENC_CFG_PREFIX "qmin", &val );
    p_sys->i_qmin = val.i_int;
    var_Get( p_enc, ENC_CFG_PREFIX "qmax", &val );
    p_sys->i_qmax = val.i_int;
    var_Get( p_enc, ENC_CFG_PREFIX "trellis", &val );
    p_sys->b_trellis = val.b_bool;

gbazin's avatar
gbazin committed
355
356
357
358
    var_Get( p_enc, ENC_CFG_PREFIX "strict", &val );
    if( val.i_int < - 1 || val.i_int > 1 ) val.i_int = 0;
    p_context->strict_std_compliance = val.i_int;

359
360
361
362
363
364
365
366
367
368
369
370
371
    var_Get( p_enc, ENC_CFG_PREFIX "lumi-masking", &val );
    p_sys->f_lumi_masking = val.f_float;
    var_Get( p_enc, ENC_CFG_PREFIX "dark-masking", &val );
    p_sys->f_dark_masking = val.f_float;
    var_Get( p_enc, ENC_CFG_PREFIX "p-masking", &val );
    p_sys->f_p_masking = val.f_float;
    var_Get( p_enc, ENC_CFG_PREFIX "border-masking", &val );
    p_sys->f_border_masking = val.f_float;
    var_Get( p_enc, ENC_CFG_PREFIX "luma-elim-threshold", &val );
    p_sys->i_luma_elim = val.i_int;
    var_Get( p_enc, ENC_CFG_PREFIX "chroma-elim-threshold", &val );
    p_sys->i_chroma_elim = val.i_int;

gbazin's avatar
   
gbazin committed
372
373
    if( p_enc->fmt_in.i_cat == VIDEO_ES )
    {
374
375
        int i_aspect_num, i_aspect_den;

376
377
378
379
380
381
382
383
        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;
        }

gbazin's avatar
   
gbazin committed
384
385
        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
386

387
388
389
390
#if LIBAVCODEC_BUILD >= 4754
        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;
#else
gbazin's avatar
   
gbazin committed
391
392
        p_context->frame_rate = p_enc->fmt_in.video.i_frame_rate;
        p_context->frame_rate_base= p_enc->fmt_in.video.i_frame_rate_base;
393
#endif
gbazin's avatar
   
gbazin committed
394

395
396
397
398
399
400
401
402
        /* 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;

403
404
405
        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;
sigmunau's avatar
sigmunau committed
406
#if LIBAVCODEC_BUILD >= 4741
407
        p_context->border_masking = p_sys->f_border_masking;
sigmunau's avatar
sigmunau committed
408
#endif
409
410
411
        p_context->luma_elim_threshold = p_sys->i_luma_elim;
        p_context->chroma_elim_threshold = p_sys->i_chroma_elim;

412
413
        if( p_sys->i_key_int > 0 )
            p_context->gop_size = p_sys->i_key_int;
414
        p_context->max_b_frames =
415
            __MAX( __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES ), 0 );
416
417
        p_context->b_frame_strategy = 0;

gbazin's avatar
   
gbazin committed
418
#if LIBAVCODEC_BUILD >= 4687
419
        av_reduce( &i_aspect_num, &i_aspect_den,
420
421
                   p_enc->fmt_in.video.i_aspect,
                   VOUT_ASPECT_FACTOR, 1 << 30 /* something big */ );
422
423
424
425
        av_reduce( &p_context->sample_aspect_ratio.num,
                   &p_context->sample_aspect_ratio.den,
                   i_aspect_num * (int64_t)p_context->height,
                   i_aspect_den * (int64_t)p_context->width, 1 << 30 );
gbazin's avatar
   
gbazin committed
426
#else
gbazin's avatar
   
gbazin committed
427
428
        p_context->aspect_ratio = ((float)p_enc->fmt_in.video.i_aspect) /
            VOUT_ASPECT_FACTOR;
gbazin's avatar
   
gbazin committed
429
#endif
gbazin's avatar
 
gbazin committed
430

gbazin's avatar
   
gbazin committed
431
432
        p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE );

433
        p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
434
        p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
435
#if LIBAVCODEC_BUILD >= 4714
436
437
438
439
440
441
442
443
444
445
        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];
            p_enc->fmt_in.i_codec = E_(GetVlcChroma)( p_context->pix_fmt );
        }
446
447
448
#else
        p_enc->fmt_in.i_codec = E_(GetVlcChroma)( p_context->pix_fmt );
#endif
Christophe Massiot's avatar
Christophe Massiot committed
449

450
        if ( p_sys->b_strict_rc )
Christophe Massiot's avatar
Christophe Massiot committed
451
452
        {
            p_context->rc_max_rate = p_enc->fmt_out.i_bitrate;
453
            p_context->rc_buffer_size = p_sys->i_rc_buffer_size;
454
455
456
            /* This is from ffmpeg's ffmpeg.c : */
            p_context->rc_initial_buffer_occupancy
                = p_sys->i_rc_buffer_size * 3/4;
457
            p_context->rc_buffer_aggressivity = p_sys->f_rc_buffer_aggressivity;
458
459
        }

460
461
        if ( p_sys->f_i_quant_factor != 0.0 )
            p_context->i_quant_factor = p_sys->f_i_quant_factor;
462

gbazin's avatar
   
gbazin committed
463
#if LIBAVCODEC_BUILD >= 4690
464
        p_context->noise_reduction = p_sys->i_noise_reduction;
gbazin's avatar
   
gbazin committed
465
#endif
466

467
        if ( p_sys->b_mpeg4_matrix )
468
        {
469
470
            p_context->intra_matrix = mpeg4_default_intra_matrix;
            p_context->inter_matrix = mpeg4_default_non_intra_matrix;
Christophe Massiot's avatar
Christophe Massiot committed
471
472
        }

473
        if ( p_sys->b_pre_me )
Christophe Massiot's avatar
Christophe Massiot committed
474
475
476
477
        {
            p_context->pre_me = 1;
            p_context->me_pre_cmp = FF_CMP_CHROMA;
        }
478

479
        if ( p_sys->b_interlace )
480
        {
481
482
            if ( p_context->height <= 280 )
            {
483
484
485
486
                if ( p_context->height != 16 || p_context->width != 16 )
                    msg_Warn( p_enc,
                        "disabling interlaced video because height=%d <= 280",
                        p_context->height );
487
488
489
490
            }
            else
            {
                p_context->flags |= CODEC_FLAG_INTERLACED_DCT;
491
#if LIBAVCODEC_BUILD >= 4698
492
493
494
                if ( p_sys->b_interlace_me )
                    p_context->flags |= CODEC_FLAG_INTERLACED_ME;
            }
495
496
497
#endif
        }

498
        if ( p_sys->b_trellis )
499
500
            p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;

501
        if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax )
502
503
            p_context->flags |= CODEC_FLAG_QSCALE;

gbazin's avatar
   
gbazin committed
504
#if LIBAVCODEC_BUILD >= 4702
505
506
        if ( p_enc->i_threads >= 1 )
            p_context->thread_count = p_enc->i_threads;
gbazin's avatar
   
gbazin committed
507
#endif
508

509
510
        if( p_sys->i_vtolerance > 0 )
            p_context->bit_rate_tolerance = p_sys->i_vtolerance;
511

512
513
514
515
        if( p_sys->i_qmin > 0 )
            p_context->mb_qmin = p_context->qmin = p_sys->i_qmin;
        if( p_sys->i_qmax > 0 )
            p_context->mb_qmax = p_context->qmax = p_sys->i_qmax;
516
517
        p_context->max_qdiff = 3;

518
        p_context->mb_decision = p_sys->i_hq;
gbazin's avatar
gbazin committed
519
520
521
522
523
524
525
526

        if( p_sys->i_quality )
        {
            p_context->flags |= CODEC_FLAG_QSCALE;
#if LIBAVCODEC_BUILD >= 4668
            p_context->global_quality = p_sys->i_quality;
#endif
        }
gbazin's avatar
   
gbazin committed
527
528
529
    }
    else if( p_enc->fmt_in.i_cat == AUDIO_ES )
    {
530
531
532
533
        /* work around bug in libmp3lame encoding */
        if( i_codec_id == CODEC_ID_MP3 && p_enc->fmt_in.audio.i_channels > 2 )
            p_enc->fmt_in.audio.i_channels = 2;

gbazin's avatar
   
gbazin committed
534
535
536
537
538
539
        p_enc->fmt_in.i_codec  = AOUT_FMT_S16_NE;
        p_context->sample_rate = p_enc->fmt_in.audio.i_rate;
        p_context->channels    = p_enc->fmt_in.audio.i_channels;
    }

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

gbazin's avatar
   
gbazin committed
542
    if( i_codec_id == CODEC_ID_RAWVIDEO )
gbazin's avatar
 
gbazin committed
543
    {
544
545
        /* XXX: hack: Force same codec (will be handled by transcode) */
        p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
gbazin's avatar
   
gbazin committed
546
        p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
gbazin's avatar
 
gbazin committed
547
548
549
550
551
552
553
    }

    /* 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;

554
    vlc_mutex_lock( lockval.p_address );
gbazin's avatar
   
gbazin committed
555
    if( avcodec_open( p_context, p_codec ) )
gbazin's avatar
 
gbazin committed
556
    {
557
        vlc_mutex_unlock( lockval.p_address );
558
559
560
        if( p_enc->fmt_in.i_cat == AUDIO_ES &&
             (p_context->channels > 2 || i_codec_id == CODEC_ID_MP2
               || i_codec_id == CODEC_ID_MP3) )
gbazin's avatar
   
gbazin committed
561
        {
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
            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)" );
            }

            if( i_codec_id == CODEC_ID_MP2 || i_codec_id == CODEC_ID_MP3 )
            {
                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;
607
            vlc_mutex_lock( lockval.p_address );
gbazin's avatar
   
gbazin committed
608
609
            if( avcodec_open( p_context, p_codec ) )
            {
610
                vlc_mutex_unlock( lockval.p_address );
gbazin's avatar
   
gbazin committed
611
                msg_Err( p_enc, "cannot open encoder" );
612
                free( p_sys );
gbazin's avatar
   
gbazin committed
613
614
615
616
617
618
                return VLC_EGENERIC;
            }
        }
        else
        {
            msg_Err( p_enc, "cannot open encoder" );
619
            free( p_sys );
gbazin's avatar
   
gbazin committed
620
621
            return VLC_EGENERIC;
        }
gbazin's avatar
 
gbazin committed
622
    }
623
    vlc_mutex_unlock( lockval.p_address );
gbazin's avatar
 
gbazin committed
624

gbazin's avatar
   
gbazin committed
625
    p_enc->fmt_out.i_extra = p_context->extradata_size;
626
627
628
629
630
631
    if( p_enc->fmt_out.i_extra )
    {
        p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
        memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
                p_enc->fmt_out.i_extra );
    }
gbazin's avatar
 
gbazin committed
632
633
    p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;

gbazin's avatar
   
gbazin committed
634
635
    if( p_enc->fmt_in.i_cat == AUDIO_ES )
    {
636
        p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
gbazin's avatar
   
gbazin committed
637
638
639
640
        p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
        p_sys->p_buffer = malloc( p_sys->i_frame_size );
    }

gbazin's avatar
   
gbazin committed
641
642
    msg_Dbg( p_enc, "found encoder %s", psz_namecodec );

gbazin's avatar
 
gbazin committed
643
644
645
    return VLC_SUCCESS;
}

646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
/****************************************************************************
 * Ffmpeg threading system
 ****************************************************************************/
#if LIBAVCODEC_BUILD >= 4702
static int FfmpegThread( struct thread_context_t *p_context )
{
    while ( !p_context->b_die && !p_context->b_error )
    {
        vlc_mutex_lock( &p_context->lock );
        while ( !p_context->b_work && !p_context->b_die && !p_context->b_error )
        {
            vlc_cond_wait( &p_context->cond, &p_context->lock );
        }
        p_context->b_work = 0;
        vlc_mutex_unlock( &p_context->lock );
        if ( p_context->b_die || p_context->b_error )
            break;

        if ( p_context->pf_func )
        {
            p_context->i_ret = p_context->pf_func( p_context->p_context,
                                                   p_context->arg );
        }

        vlc_mutex_lock( &p_context->lock );
        p_context->b_done = 1;
        vlc_cond_signal( &p_context->cond );
        vlc_mutex_unlock( &p_context->lock );
    }

    return 0;
}

static int FfmpegExecute( AVCodecContext *s,
                          int (*pf_func)(AVCodecContext *c2, void *arg2),
                          void **arg, int *ret, int count )
{
    struct thread_context_t ** pp_contexts =
                         (struct thread_context_t **)s->thread_opaque;
    int i;

    /* Note, we can be certain that this is not called with the same
     * AVCodecContext by different threads at the same time */
    for ( i = 0; i < count; i++ )
    {
        vlc_mutex_lock( &pp_contexts[i]->lock );
        pp_contexts[i]->arg = arg[i];
        pp_contexts[i]->pf_func = pf_func;
        pp_contexts[i]->i_ret = 12345;
        pp_contexts[i]->b_work = 1;
        vlc_cond_signal( &pp_contexts[i]->cond );
        vlc_mutex_unlock( &pp_contexts[i]->lock );
    }
    for ( i = 0; i < count; i++ )
    {
        vlc_mutex_lock( &pp_contexts[i]->lock );
        while ( !pp_contexts[i]->b_done )
        {
            vlc_cond_wait( &pp_contexts[i]->cond, &pp_contexts[i]->lock );
        }
        pp_contexts[i]->b_done = 0;
        pp_contexts[i]->pf_func = NULL;
        vlc_mutex_unlock( &pp_contexts[i]->lock );

        if ( ret )
        {
            ret[i] = pp_contexts[i]->i_ret;
        }
    }

    return 0;
}
#endif

gbazin's avatar
 
gbazin committed
720
721
722
723
724
725
726
727
/****************************************************************************
 * 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;
    AVFrame frame;
    int i_out, i_plane;
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759

#if LIBAVCODEC_BUILD >= 4702
    if ( !p_sys->b_inited && p_enc->i_threads >= 1 )
    {
        struct thread_context_t ** pp_contexts;
        int i;

        p_sys->b_inited = 1;
        pp_contexts = malloc( sizeof(struct thread_context_t *)
                                 * p_enc->i_threads );
        p_sys->p_context->thread_opaque = (void *)pp_contexts;

        for ( i = 0; i < p_enc->i_threads; i++ )
        {
            pp_contexts[i] = vlc_object_create( p_enc,
                                     sizeof(struct thread_context_t) );
            pp_contexts[i]->p_context = p_sys->p_context;
            vlc_mutex_init( p_enc, &pp_contexts[i]->lock );
            vlc_cond_init( p_enc, &pp_contexts[i]->cond );
            pp_contexts[i]->b_work = 0;
            pp_contexts[i]->b_done = 0;
            if ( vlc_thread_create( pp_contexts[i], "encoder", FfmpegThread,
                                    VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) )
            {
                msg_Err( p_enc, "cannot spawn encoder thread, expect to die soon" );
                return NULL;
            }
        }

        p_sys->p_context->execute = FfmpegExecute;
    }
#endif
gbazin's avatar
 
gbazin committed
760

Laurent Aimar's avatar
Laurent Aimar committed
761
    memset( &frame, 0, sizeof( AVFrame ) );
gbazin's avatar
 
gbazin committed
762
763
764
765
766
767
    for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
    {
        frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
        frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
    }

768
769
770
    /* Let ffmpeg select the frame type */
    frame.pict_type = 0;

771
    frame.repeat_pict = p_pict->i_nb_fields - 2;
772
773
774

#if LIBAVCODEC_BUILD >= 4685
    frame.interlaced_frame = !p_pict->b_progressive;
775
    frame.top_field_first = !!p_pict->b_top_field_first;
776
777
#endif

778
#if LIBAVCODEC_BUILD < 4702
gbazin's avatar
   
gbazin committed
779
    /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
780
781
782
    if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) ||
        p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '1', 'v' ) ||
        p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '2', 'v' ) )
783
784
785
#else
    if( 1 )
#endif
Christophe Massiot's avatar
Christophe Massiot committed
786
    {
787
        frame.pts = p_pict->date ? p_pict->date : (signed int) AV_NOPTS_VALUE;
788

789
        if ( p_sys->b_hurry_up && frame.pts != (signed int) AV_NOPTS_VALUE )
Christophe Massiot's avatar
Christophe Massiot committed
790
        {
791
792
            mtime_t current_date = mdate();

793
            if ( current_date + HURRY_UP_GUARD3 > frame.pts )
794
795
796
797
798
799
800
            {
                p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE;
                p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
                msg_Dbg( p_enc, "hurry up mode 3" );
            }
            else
            {
801
                p_sys->p_context->mb_decision = p_sys->i_hq;
802

803
                if ( current_date + HURRY_UP_GUARD2 > frame.pts )
804
805
                {
                    p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
806
#if LIBAVCODEC_BUILD >= 4690
807
                    p_sys->p_context->noise_reduction = p_sys->i_noise_reduction
808
                         + (HURRY_UP_GUARD2 + current_date - frame.pts) / 500;
809
810
811
812
813
#endif
                    msg_Dbg( p_enc, "hurry up mode 2" );
                }
                else
                {
814
                    if ( p_sys->b_trellis )
815
                        p_sys->p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
816
817
#if LIBAVCODEC_BUILD >= 4690
                    p_sys->p_context->noise_reduction =
818
                        p_sys->i_noise_reduction;
819
820
821
822
#endif
                }
            }

823
            if ( current_date + HURRY_UP_GUARD1 > frame.pts )
824
            {
825
826
                frame.pict_type = FF_P_TYPE;
                /* msg_Dbg( p_enc, "hurry up mode 1 %lld", current_date + HURRY_UP_GUARD1 - frame.pts ); */
827
            }
Christophe Massiot's avatar
Christophe Massiot committed
828
829
        }
    }
gbazin's avatar
   
gbazin committed
830
    else
Christophe Massiot's avatar
Christophe Massiot committed
831
    {
832
        frame.pts = AV_NOPTS_VALUE;
Christophe Massiot's avatar
Christophe Massiot committed
833
    }
gbazin's avatar
 
gbazin committed
834

835
    if ( frame.pts != (signed int) AV_NOPTS_VALUE && frame.pts != 0 )
836
837
838
    {
        if ( p_sys->i_last_pts == frame.pts )
        {
gbazin's avatar
gbazin committed
839
840
            msg_Warn( p_enc, "almost fed libavcodec with two frames with the "
                      "same PTS (" I64Fd ")", frame.pts );
841
842
            return NULL;
        }
843
844
845
846
847
848
849
        else if ( p_sys->i_last_pts > frame.pts )
        {
            msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
                      "past (current: " I64Fd ", last: "I64Fd")",
                      frame.pts, p_sys->i_last_pts );
            return NULL;
        }
850
851
852
853
854
        else
        {
            p_sys->i_last_pts = frame.pts;
        }
    }
gbazin's avatar
 
gbazin committed
855

gbazin's avatar
gbazin committed
856
857
    frame.quality = p_sys->i_quality;

858
859
860
861
862
863
864
865
866
867
868
    /* Ugly work-around for stupid libavcodec behaviour */
#if LIBAVCODEC_BUILD >= 4722
    p_sys->i_framenum++;
    p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts;
    frame.pts = p_sys->i_framenum * AV_TIME_BASE *
        p_enc->fmt_in.video.i_frame_rate_base;
    frame.pts += p_enc->fmt_in.video.i_frame_rate - 1;
    frame.pts /= p_enc->fmt_in.video.i_frame_rate;
#endif
    /* End work-around */

gbazin's avatar
 
gbazin committed
869
870
    i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
                                  AVCODEC_MAX_VIDEO_FRAME_SIZE, &frame );
Christophe Massiot's avatar
Christophe Massiot committed
871

gbazin's avatar
 
gbazin committed
872
873
874
875
876
    if( i_out > 0 )
    {
        block_t *p_block = block_New( p_enc, i_out );
        memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );

877
878
879
880
881
882
883
884
885
886
        /* FIXME, 3-2 pulldown is not handled correctly */
        p_block->i_length = I64C(1000000) *
            p_enc->fmt_in.video.i_frame_rate_base /
                p_enc->fmt_in.video.i_frame_rate;

        if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay )
        {
            /* No delay -> output pts == input pts */
            p_block->i_pts = p_block->i_dts = p_pict->date;
        }
887
        else if( p_sys->p_context->coded_frame->pts != (signed int) AV_NOPTS_VALUE &&
gbazin's avatar
gbazin committed
888
            p_sys->p_context->coded_frame->pts != 0 &&
gbazin's avatar
 
gbazin committed
889
890
891
            p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
        {
            p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
892
            p_block->i_pts = p_sys->p_context->coded_frame->pts;
gbazin's avatar
 
gbazin committed
893

894
895
896
897
898
899
            /* Ugly work-around for stupid libavcodec behaviour */
#if LIBAVCODEC_BUILD >= 4722
            {
            int64_t i_framenum = p_block->i_pts *
                p_enc->fmt_in.video.i_frame_rate /
                p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE;
gbazin's avatar
 
gbazin committed
900

901
902
903
904
905
906
907
            p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY];
            }
#endif
            /* End work-around */

            if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
                p_sys->p_context->coded_frame->pict_type != FF_P_TYPE )
gbazin's avatar
 
gbazin committed
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
            {
                p_block->i_dts = p_block->i_pts;
            }
            else
            {
                if( p_sys->i_last_ref_pts )
                {
                    p_block->i_dts = p_sys->i_last_ref_pts;
                }
                else
                {
                    /* Let's put something sensible */
                    p_block->i_dts = p_block->i_pts;
                }

                p_sys->i_last_ref_pts = p_block->i_pts;
            }
        }
        else
        {
            /* Buggy libavcodec which doesn't update coded_frame->pts
             * correctly */
            p_block->i_dts = p_block->i_pts = p_pict->date;
        }

933
934
935
936
937
938
939
940
941
942
943
944
945
        switch ( p_sys->p_context->coded_frame->pict_type )
        {
        case FF_I_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_I;
            break;
        case FF_P_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_P;
            break;
        case FF_B_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_B;
            break;
        }

gbazin's avatar
 
gbazin committed
946
947
948
949
950
951
952
953
954
955
956
957
958
        return p_block;
    }

    return NULL;
}

/****************************************************************************
 * EncodeAudio: the whole thing
 ****************************************************************************/
static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
{
    encoder_sys_t *p_sys = p_enc->p_sys;
    block_t *p_block, *p_chain = NULL;
gbazin's avatar
   
gbazin committed
959

gbazin's avatar
 
gbazin committed
960
961
962
963
964
965
    char *p_buffer = p_aout_buf->p_buffer;
    int i_samples = p_aout_buf->i_nb_samples;
    int i_samples_delay = p_sys->i_samples_delay;

    p_sys->i_pts = p_aout_buf->start_date -
                (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
gbazin's avatar
   
gbazin committed
966
                (mtime_t)p_enc->fmt_in.audio.i_rate;
gbazin's avatar
 
gbazin committed
967
968
969
970
971
972
973
974
975
976
977

    p_sys->i_samples_delay += i_samples;

    while( p_sys->i_samples_delay >= p_sys->p_context->frame_size )
    {
        int16_t *p_samples;
        int i_out;

        if( i_samples_delay )
        {
            /* Take care of the left-over from last time */
gbazin's avatar
   
gbazin committed
978
            int i_delay_size = i_samples_delay * 2 *
gbazin's avatar
 
gbazin committed
979
980
981
982
983
984
                                 p_sys->p_context->channels;
            int i_size = p_sys->i_frame_size - i_delay_size;

            p_samples = (int16_t *)p_sys->p_buffer;
            memcpy( p_sys->p_buffer + i_delay_size, p_buffer, i_size );
            p_buffer -= i_delay_size;
gbazin's avatar
   
gbazin committed
985
            i_samples += i_samples_delay;
gbazin's avatar
 
gbazin committed
986
987
988
989
990
991
992
993
994
995
            i_samples_delay = 0;
        }
        else
        {
            p_samples = (int16_t *)p_buffer;
        }

        i_out = avcodec_encode_audio( p_sys->p_context, p_sys->p_buffer_out,
                                      2 * AVCODEC_MAX_AUDIO_FRAME_SIZE,
                                      p_samples );
gbazin's avatar
   
gbazin committed
996
997
998
999
1000

#if 0
        msg_Warn( p_enc, "avcodec_encode_audio: %d", i_out );
#endif
        if( i_out < 0 ) break;