]> git.sesse.net Git - vlc/blob - modules/codec/avcodec/encoder.c
Allowed to use mp2/mp3 to specify layer 2/3 for mpeg audio encoder.
[vlc] / modules / codec / avcodec / encoder.c
1 /*****************************************************************************
2  * encoder.c: video and audio encoder using the ffmpeg library
3  *****************************************************************************
4  * Copyright (C) 1999-2004 the VideoLAN team
5  * $Id$
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)
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 /*****************************************************************************
29  * Preamble
30  *****************************************************************************/
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <vlc_common.h>
36 #include <vlc_aout.h>
37 #include <vlc_sout.h>
38 #include <vlc_codec.h>
39 #include <vlc_dialog.h>
40 #include <vlc_avcodec.h>
41 #include <vlc_cpu.h>
42
43 /* ffmpeg header */
44 #define HAVE_MMX 1
45 #ifdef HAVE_LIBAVCODEC_AVCODEC_H
46 #   include <libavcodec/avcodec.h>
47 #else
48 #   include <avcodec.h>
49 #endif
50
51 #include "avcodec.h"
52
53 #define HURRY_UP_GUARD1 (450000)
54 #define HURRY_UP_GUARD2 (300000)
55 #define HURRY_UP_GUARD3 (100000)
56
57 #define MAX_FRAME_DELAY (FF_MAX_B_FRAMES + 2)
58
59 #define RAW_AUDIO_FRAME_SIZE (2048)
60
61 /*****************************************************************************
62  * Local prototypes
63  *****************************************************************************/
64 int  OpenEncoder ( vlc_object_t * );
65 void CloseEncoder( vlc_object_t * );
66
67 static block_t *EncodeVideo( encoder_t *, picture_t * );
68 static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );
69
70 struct thread_context_t;
71
72 /*****************************************************************************
73  * thread_context_t : for multithreaded encoding
74  *****************************************************************************/
75 struct thread_context_t
76 {
77     VLC_COMMON_MEMBERS
78
79     AVCodecContext  *p_context;
80     int             (* pf_func)(AVCodecContext *c, void *arg);
81     void            *arg;
82     int             i_ret;
83
84     vlc_mutex_t     lock;
85     vlc_cond_t      cond;
86     bool            b_work, b_done;
87 };
88
89 /*****************************************************************************
90  * encoder_sys_t : ffmpeg encoder descriptor
91  *****************************************************************************/
92 struct encoder_sys_t
93 {
94     /*
95      * Ffmpeg properties
96      */
97     AVCodec         *p_codec;
98     AVCodecContext  *p_context;
99
100     /*
101      * Common properties
102      */
103     char *p_buffer;
104     uint8_t *p_buffer_out;
105     size_t i_buffer_out;
106
107     /*
108      * Video properties
109      */
110     mtime_t i_last_ref_pts;
111     mtime_t i_buggy_pts_detect;
112     mtime_t i_last_pts;
113     bool    b_inited;
114
115     /*
116      * Audio properties
117      */
118     int i_sample_bytes;
119     int i_frame_size;
120     int i_samples_delay;
121     mtime_t i_pts;
122
123     /* Encoding settings */
124     int        i_key_int;
125     int        i_b_frames;
126     int        i_vtolerance;
127     int        i_qmin;
128     int        i_qmax;
129     int        i_hq;
130     int        i_rc_buffer_size;
131     float      f_rc_buffer_aggressivity;
132     bool       b_pre_me;
133     bool       b_hurry_up;
134     bool       b_interlace, b_interlace_me;
135     float      f_i_quant_factor;
136     int        i_noise_reduction;
137     bool       b_mpeg4_matrix;
138     bool       b_trellis;
139     int        i_quality; /* for VBR */
140     float      f_lumi_masking, f_dark_masking, f_p_masking, f_border_masking;
141     int        i_luma_elim, i_chroma_elim;
142     int        i_aac_profile; /* AAC profile to use.*/
143     /* Used to work around stupid timestamping behaviour in libavcodec */
144     uint64_t i_framenum;
145     mtime_t  pi_delay_pts[MAX_FRAME_DELAY];
146 };
147
148 static const char *const ppsz_enc_options[] = {
149     "keyint", "bframes", "vt", "qmin", "qmax", "hq",
150     "rc-buffer-size", "rc-buffer-aggressivity", "pre-me", "hurry-up",
151     "interlace", "interlace-me", "i-quant-factor", "noise-reduction", "mpeg4-matrix",
152     "trellis", "qscale", "strict", "lumi-masking", "dark-masking",
153     "p-masking", "border-masking", "luma-elim-threshold",
154     "chroma-elim-threshold",
155      "aac-profile",
156      NULL
157 };
158
159 static const uint16_t mpa_bitrate_tab[2][15] =
160 {
161     {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},
162     {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
163 };
164
165 static const uint16_t mpa_freq_tab[6] =
166 { 44100, 48000, 32000, 22050, 24000, 16000 };
167
168 static const uint16_t mpeg4_default_intra_matrix[64] = {
169   8, 17, 18, 19, 21, 23, 25, 27,
170  17, 18, 19, 21, 23, 25, 27, 28,
171  20, 21, 22, 23, 24, 26, 28, 30,
172  21, 22, 23, 24, 26, 28, 30, 32,
173  22, 23, 24, 26, 28, 30, 32, 35,
174  23, 24, 26, 28, 30, 32, 35, 38,
175  25, 26, 28, 30, 32, 35, 38, 41,
176  27, 28, 30, 32, 35, 38, 41, 45,
177 };
178
179 static const uint16_t mpeg4_default_non_intra_matrix[64] = {
180  16, 17, 18, 19, 20, 21, 22, 23,
181  17, 18, 19, 20, 21, 22, 23, 24,
182  18, 19, 20, 21, 22, 23, 24, 25,
183  19, 20, 21, 22, 23, 24, 26, 27,
184  20, 21, 22, 23, 25, 26, 27, 28,
185  21, 22, 23, 24, 26, 27, 28, 30,
186  22, 23, 24, 26, 27, 28, 30, 31,
187  23, 24, 25, 27, 28, 30, 31, 33,
188 };
189
190 /*****************************************************************************
191  * OpenEncoder: probe the encoder
192  *****************************************************************************/
193
194 int OpenEncoder( vlc_object_t *p_this )
195 {
196     encoder_t *p_enc = (encoder_t *)p_this;
197     encoder_sys_t *p_sys;
198     AVCodecContext *p_context;
199     AVCodec *p_codec;
200     int i_codec_id, i_cat;
201     const char *psz_namecodec;
202     float f_val;
203     char *psz_val;
204     int i_val;
205
206     if( p_enc->fmt_out.i_codec == VLC_CODEC_MP3 )
207     {
208         i_cat = AUDIO_ES;
209         i_codec_id = CODEC_ID_MP3;
210         psz_namecodec = "MPEG I/II Layer 3";
211     }
212     else if( p_enc->fmt_out.i_codec == VLC_CODEC_MP2 )
213     {
214         i_cat = AUDIO_ES;
215         i_codec_id = CODEC_ID_MP2;
216         psz_namecodec = "MPEG I/II Layer 2";
217     }
218     else if( !GetFfmpegCodec( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
219                              &psz_namecodec ) )
220     {
221         if( TestFfmpegChroma( -1, p_enc->fmt_out.i_codec ) != VLC_SUCCESS )
222         {
223             /* handed chroma output */
224             return VLC_EGENERIC;
225         }
226         i_cat      = VIDEO_ES;
227         i_codec_id = CODEC_ID_RAWVIDEO;
228         psz_namecodec = "Raw video";
229     }
230
231     if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
232     {
233         msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
234         dialog_Fatal( p_enc, _("Streaming / Transcoding failed"),
235                         _("\"%s\" is no video encoder."), psz_namecodec );
236         return VLC_EGENERIC;
237     }
238
239     if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )
240     {
241         msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
242         dialog_Fatal( p_enc, _("Streaming / Transcoding failed"),
243                         _("\"%s\" is no audio encoder."), psz_namecodec );
244         return VLC_EGENERIC;
245     }
246
247     if( p_enc->fmt_out.i_cat == SPU_ES )
248     {
249         /* We don't support subtitle encoding */
250         return VLC_EGENERIC;
251     }
252
253     /* Initialization must be done before avcodec_find_encoder() */
254     InitLibavcodec( p_this );
255
256     p_codec = avcodec_find_encoder( i_codec_id );
257     if( !p_codec )
258     {
259         msg_Err( p_enc, "cannot find encoder %s\n"
260 "*** Your FFMPEG installation is crippled.   ***\n"
261 "*** Please check with your FFMPEG packager. ***\n"
262 "*** This is NOT a VLC media player issue.   ***", psz_namecodec );
263
264         dialog_Fatal( p_enc, _("Streaming / Transcoding failed"), _(
265 /* I have had enough of all these MPEG-3 transcoding bug reports.
266  * Downstream packager, you had better not patch this out, or I will be really
267  * annoyed. Think about it - you don't want to fork the VLC translation files,
268  * do you? -- Courmisch, 2008-10-22 */
269 "It seems your FFMPEG (libavcodec) installation lacks the following encoder:\n"
270 "%s.\n"
271 "If you don't know how to fix this, ask for support from your distribution.\n"
272 "\n"
273 "This is not an error inside VLC media player.\n"
274 "Do not contact the VideoLAN project about this issue.\n"),
275             psz_namecodec );
276         return VLC_EGENERIC;
277     }
278
279     /* Allocate the memory needed to store the encoder's structure */
280     if( ( p_sys = calloc( 1, sizeof(encoder_sys_t) ) ) == NULL )
281         return VLC_ENOMEM;
282     p_enc->p_sys = p_sys;
283     p_sys->p_codec = p_codec;
284
285     p_enc->pf_encode_video = EncodeVideo;
286     p_enc->pf_encode_audio = EncodeAudio;
287
288     p_sys->p_buffer = NULL;
289     p_sys->p_buffer_out = NULL;
290     p_sys->i_buffer_out = 0;
291
292     p_sys->p_context = p_context = avcodec_alloc_context();
293     p_sys->p_context->codec_id = p_sys->p_codec->id;
294     p_context->debug = var_InheritInteger( p_enc, "ffmpeg-debug" );
295     p_context->opaque = (void *)p_this;
296
297     /* Set CPU capabilities */
298     unsigned i_cpu = vlc_CPU();
299     p_context->dsp_mask = 0;
300     if( !(i_cpu & CPU_CAPABILITY_MMX) )
301     {
302         p_context->dsp_mask |= AV_CPU_FLAG_MMX;
303     }
304     if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
305     {
306         p_context->dsp_mask |= AV_CPU_FLAG_MMX2;
307     }
308     if( !(i_cpu & CPU_CAPABILITY_3DNOW) )
309     {
310         p_context->dsp_mask |= AV_CPU_FLAG_3DNOW;
311     }
312     if( !(i_cpu & CPU_CAPABILITY_SSE) )
313     {
314         p_context->dsp_mask |= AV_CPU_FLAG_SSE;
315         p_context->dsp_mask |= AV_CPU_FLAG_SSE2;
316     }
317
318     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
319
320     p_sys->i_key_int = var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" );
321     p_sys->i_b_frames = var_GetInteger( p_enc, ENC_CFG_PREFIX "bframes" );
322     p_sys->i_vtolerance = var_GetInteger( p_enc, ENC_CFG_PREFIX "vt" ) * 1000;
323     p_sys->b_interlace = var_GetBool( p_enc, ENC_CFG_PREFIX "interlace" );
324     p_sys->b_interlace_me = var_GetBool( p_enc, ENC_CFG_PREFIX "interlace-me" );
325     p_sys->b_pre_me = var_GetBool( p_enc, ENC_CFG_PREFIX "pre-me" );
326     p_sys->b_hurry_up = var_GetBool( p_enc, ENC_CFG_PREFIX "hurry-up" );
327
328     if( p_sys->b_hurry_up )
329     {
330         /* hurry up mode needs noise reduction, even small */
331         p_sys->i_noise_reduction = 1;
332     }
333
334     p_sys->i_rc_buffer_size = var_GetInteger( p_enc, ENC_CFG_PREFIX "rc-buffer-size" );
335     p_sys->f_rc_buffer_aggressivity = var_GetFloat( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity" );
336     p_sys->f_i_quant_factor = var_GetFloat( p_enc, ENC_CFG_PREFIX "i-quant-factor" );
337     p_sys->i_noise_reduction = var_GetInteger( p_enc, ENC_CFG_PREFIX "noise-reduction" );
338     p_sys->b_mpeg4_matrix = var_GetBool( p_enc, ENC_CFG_PREFIX "mpeg4-matrix" );
339
340     f_val = var_GetFloat( p_enc, ENC_CFG_PREFIX "qscale" );
341     if( f_val < 0.01 || f_val > 255.0 ) f_val = 0;
342     p_sys->i_quality = (int)(FF_QP2LAMBDA * f_val + 0.5);
343
344     psz_val = var_GetString( p_enc, ENC_CFG_PREFIX "hq" );
345     p_sys->i_hq = FF_MB_DECISION_RD;
346     if( psz_val && *psz_val )
347     {
348         if( !strcmp( psz_val, "rd" ) )
349             p_sys->i_hq = FF_MB_DECISION_RD;
350         else if( !strcmp( psz_val, "bits" ) )
351             p_sys->i_hq = FF_MB_DECISION_BITS;
352         else if( !strcmp( psz_val, "simple" ) )
353             p_sys->i_hq = FF_MB_DECISION_SIMPLE;
354         else
355             p_sys->i_hq = FF_MB_DECISION_RD;
356     }
357     else
358         p_sys->i_hq = FF_MB_DECISION_RD;
359     free( psz_val );
360
361     p_sys->i_qmin = var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" );
362     p_sys->i_qmax = var_GetInteger( p_enc, ENC_CFG_PREFIX "qmax" );
363     p_sys->b_trellis = var_GetBool( p_enc, ENC_CFG_PREFIX "trellis" );
364
365     i_val = var_GetInteger( p_enc, ENC_CFG_PREFIX "strict" );
366     if( i_val < - 1 || i_val > 1 ) i_val = 0;
367     p_context->strict_std_compliance = i_val;
368
369     p_sys->f_lumi_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "lumi-masking" );
370     p_sys->f_dark_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "dark-masking" );
371     p_sys->f_p_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "p-masking" );
372     p_sys->f_border_masking = var_GetFloat( p_enc, ENC_CFG_PREFIX "border-masking" );
373     p_sys->i_luma_elim = var_GetInteger( p_enc, ENC_CFG_PREFIX "luma-elim-threshold" );
374     p_sys->i_chroma_elim = var_GetInteger( p_enc, ENC_CFG_PREFIX "chroma-elim-threshold" );
375
376     psz_val = var_GetString( p_enc, ENC_CFG_PREFIX "aac-profile" );
377     /* ffmpeg uses faac encoder atm, and it has issues with
378      * other than low-complexity profile, so default to that */
379     p_sys->i_aac_profile = FF_PROFILE_AAC_LOW;
380     if( psz_val && *psz_val )
381     {
382         if( !strncmp( psz_val, "main", 4 ) )
383             p_sys->i_aac_profile = FF_PROFILE_AAC_MAIN;
384         else if( !strncmp( psz_val, "low", 3 ) )
385             p_sys->i_aac_profile = FF_PROFILE_AAC_LOW;
386 #if 0    /* Not supported by FAAC encoder */
387         else if( !strncmp( psz_val, "ssr", 3 ) )
388             p_sys->i_aac_profile = FF_PROFILE_AAC_SSR;
389 #endif
390         else  if( !strncmp( psz_val, "ltp", 3 ) )
391             p_sys->i_aac_profile = FF_PROFILE_AAC_LTP;
392         else
393         {
394             msg_Warn( p_enc, "unknown AAC profile requested, setting it to low" );
395             p_sys->i_aac_profile = FF_PROFILE_AAC_LOW;
396         }
397     }
398     free( psz_val );
399
400     if( p_enc->fmt_in.i_cat == VIDEO_ES )
401     {
402         if( !p_enc->fmt_in.video.i_width || !p_enc->fmt_in.video.i_height )
403         {
404             msg_Warn( p_enc, "invalid size %ix%i", p_enc->fmt_in.video.i_width,
405                       p_enc->fmt_in.video.i_height );
406             free( p_sys );
407             return VLC_EGENERIC;
408         }
409
410         p_context->codec_type = AVMEDIA_TYPE_VIDEO;
411
412         p_context->width = p_enc->fmt_in.video.i_width;
413         p_context->height = p_enc->fmt_in.video.i_height;
414
415         p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base;
416         p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate;
417         if( p_codec->supported_framerates )
418         {
419             AVRational target = {
420                 .num = p_enc->fmt_in.video.i_frame_rate,
421                 .den = p_enc->fmt_in.video.i_frame_rate_base,
422             };
423             int idx = av_find_nearest_q_idx(target, p_codec->supported_framerates);
424
425             p_context->time_base.num = p_codec->supported_framerates[idx].den;
426             p_context->time_base.den = p_codec->supported_framerates[idx].num;
427         }
428
429         /* Defaults from ffmpeg.c */
430         p_context->qblur = 0.5;
431         p_context->qcompress = 0.5;
432         p_context->b_quant_offset = 1.25;
433         p_context->b_quant_factor = 1.25;
434         p_context->i_quant_offset = 0.0;
435         p_context->i_quant_factor = -0.8;
436
437         p_context->lumi_masking = p_sys->f_lumi_masking;
438         p_context->dark_masking = p_sys->f_dark_masking;
439         p_context->p_masking = p_sys->f_p_masking;
440         p_context->border_masking = p_sys->f_border_masking;
441         p_context->luma_elim_threshold = p_sys->i_luma_elim;
442         p_context->chroma_elim_threshold = p_sys->i_chroma_elim;
443
444         if( p_sys->i_key_int > 0 )
445             p_context->gop_size = p_sys->i_key_int;
446         p_context->max_b_frames =
447             __MAX( __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES ), 0 );
448         p_context->b_frame_strategy = 0;
449         if( !p_context->max_b_frames  &&
450             (  p_enc->fmt_out.i_codec == VLC_CODEC_MPGV ||
451                p_enc->fmt_out.i_codec == VLC_CODEC_MP2V ||
452                p_enc->fmt_out.i_codec == VLC_CODEC_MP1V ) )
453             p_context->flags |= CODEC_FLAG_LOW_DELAY;
454
455         if( p_enc->fmt_out.i_codec == VLC_CODEC_MP2V )
456             p_context->idct_algo = FF_IDCT_LIBMPEG2MMX;
457
458         av_reduce( &p_context->sample_aspect_ratio.num,
459                    &p_context->sample_aspect_ratio.den,
460                    p_enc->fmt_in.video.i_sar_num,
461                    p_enc->fmt_in.video.i_sar_den, 1 << 30 );
462
463         p_sys->p_buffer_out = NULL;
464
465         p_enc->fmt_in.i_codec = VLC_CODEC_I420;
466         p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec;
467         GetFfmpegChroma( &p_context->pix_fmt, p_enc->fmt_in.video );
468
469         if( p_codec->pix_fmts )
470         {
471             const enum PixelFormat *p = p_codec->pix_fmts;
472             for( ; *p != -1; p++ )
473             {
474                 if( *p == p_context->pix_fmt ) break;
475             }
476             if( *p == -1 ) p_context->pix_fmt = p_codec->pix_fmts[0];
477             GetVlcChroma( &p_enc->fmt_in.video, p_context->pix_fmt );
478             p_enc->fmt_in.i_codec = p_enc->fmt_in.video.i_chroma;
479         }
480
481
482         if ( p_sys->f_i_quant_factor != 0.0 )
483             p_context->i_quant_factor = p_sys->f_i_quant_factor;
484
485         p_context->noise_reduction = p_sys->i_noise_reduction;
486
487         if ( p_sys->b_mpeg4_matrix )
488         {
489             p_context->intra_matrix = mpeg4_default_intra_matrix;
490             p_context->inter_matrix = mpeg4_default_non_intra_matrix;
491         }
492
493         if ( p_sys->b_pre_me )
494         {
495             p_context->pre_me = 1;
496             p_context->me_pre_cmp = FF_CMP_CHROMA;
497         }
498
499         if ( p_sys->b_interlace )
500         {
501             if ( p_context->height <= 280 )
502             {
503                 if ( p_context->height != 16 || p_context->width != 16 )
504                     msg_Warn( p_enc,
505                         "disabling interlaced video because height=%d <= 280",
506                         p_context->height );
507             }
508             else
509             {
510                 p_context->flags |= CODEC_FLAG_INTERLACED_DCT;
511                 if ( p_sys->b_interlace_me )
512                     p_context->flags |= CODEC_FLAG_INTERLACED_ME;
513             }
514         }
515
516         p_context->trellis = p_sys->b_trellis;
517
518         if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax )
519             p_context->flags |= CODEC_FLAG_QSCALE;
520         /* These codecs cause libavcodec to exit if thread_count is > 1.
521            See libavcodec/mpegvideo_enc.c:MPV_encode_init and
522            libavcodec/svq3.c , WMV2 calls MPV_encode_init also.
523          */
524         if ( i_codec_id == CODEC_ID_FLV1 ||
525              i_codec_id == CODEC_ID_H261 ||
526              i_codec_id == CODEC_ID_LJPEG ||
527              i_codec_id == CODEC_ID_MJPEG ||
528              i_codec_id == CODEC_ID_H263 ||
529              i_codec_id == CODEC_ID_H263P ||
530              i_codec_id == CODEC_ID_MSMPEG4V1 ||
531              i_codec_id == CODEC_ID_MSMPEG4V2 ||
532              i_codec_id == CODEC_ID_MSMPEG4V3 ||
533              i_codec_id == CODEC_ID_WMV1 ||
534              i_codec_id == CODEC_ID_WMV2 ||
535              i_codec_id == CODEC_ID_RV10 ||
536              i_codec_id == CODEC_ID_RV20 ||
537              i_codec_id == CODEC_ID_SVQ3 )
538             p_enc->i_threads = 1;
539
540         if( p_sys->i_vtolerance > 0 )
541             p_context->bit_rate_tolerance = p_sys->i_vtolerance;
542
543         /* usually if someone sets bitrate, he likes more to get that bitrate
544          * over quality should help 'normal' user to get asked bitrate
545          */
546         if( p_enc->fmt_out.i_bitrate > 0 && p_sys->i_qmax == 0 && p_sys->i_qmin == 0 )
547         {
548             p_sys->i_qmax = 51;
549             p_sys->i_qmin = 3;
550         }
551
552         if( p_sys->i_qmin > 0 )
553         {
554             p_context->qmin = p_sys->i_qmin;
555             p_context->mb_lmin = p_context->lmin = p_sys->i_qmin * FF_QP2LAMBDA;
556         }
557         if( p_sys->i_qmax > 0 )
558         {
559             p_context->qmax = p_sys->i_qmax;
560             p_context->mb_lmax = p_context->lmax = p_sys->i_qmax * FF_QP2LAMBDA;
561         }
562         p_context->max_qdiff = 3;
563
564         p_context->mb_decision = p_sys->i_hq;
565
566         if( p_sys->i_quality )
567         {
568             p_context->flags |= CODEC_FLAG_QSCALE;
569             p_context->global_quality = p_sys->i_quality;
570         }
571         else
572         {
573             p_context->rc_qsquish = 1.0;
574             p_context->rc_max_rate = p_enc->fmt_out.i_bitrate;
575             p_context->rc_min_rate = p_enc->fmt_out.i_bitrate;
576             p_context->rc_buffer_size = p_sys->i_rc_buffer_size;
577             /* This is from ffmpeg's ffmpeg.c : */
578             p_context->rc_initial_buffer_occupancy
579                 = p_sys->i_rc_buffer_size * 3/4;
580             p_context->rc_buffer_aggressivity = p_sys->f_rc_buffer_aggressivity;
581         }
582     }
583     else if( p_enc->fmt_in.i_cat == AUDIO_ES )
584     {
585         /* work around bug in libmp3lame encoding */
586         if( i_codec_id == CODEC_ID_MP3 && p_enc->fmt_in.audio.i_channels > 2 )
587             p_enc->fmt_in.audio.i_channels = 2;
588
589         p_context->codec_type  = AVMEDIA_TYPE_AUDIO;
590         p_context->sample_fmt  = p_codec->sample_fmts ?
591                                     p_codec->sample_fmts[0] :
592                                     SAMPLE_FMT_S16;
593         p_enc->fmt_in.i_codec  = VLC_CODEC_S16N;
594         p_context->sample_rate = p_enc->fmt_out.audio.i_rate;
595         p_context->channels    = p_enc->fmt_out.audio.i_channels;
596
597         if ( p_enc->fmt_out.i_codec == VLC_CODEC_MP4A )
598         {
599             /* XXX: FAAC does resample only when setting the INPUT samplerate
600              * to the desired value (-R option of the faac frontend)
601             p_enc->fmt_in.audio.i_rate = p_context->sample_rate;*/
602             /* vlc should default to low-complexity profile, faac encoder
603              * has bug and aac audio has issues otherwise atm */
604             p_context->profile = p_sys->i_aac_profile;
605         }
606     }
607
608     /* Misc parameters */
609     p_context->bit_rate = p_enc->fmt_out.i_bitrate;
610
611 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 52, 69, 2 )
612     /* Set reasonable defaults to VP8, based on
613        libvpx-720p preset from libvpx ffmpeg-patch */
614     if( i_codec_id == CODEC_ID_VP8 )
615     {
616         /* Lets give bitrate tolerance */
617         p_context->bit_rate_tolerance = __MAX(2 * p_enc->fmt_out.i_bitrate, p_sys->i_vtolerance );
618         /* default to 120 frames between keyframe */
619         if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" ) )
620             p_context->gop_size = 120;
621         /* Don't set rc-values atm, they were from time before
622            libvpx was officially in ffmpeg */
623         //p_context->rc_max_rate = 24 * 1000 * 1000; //24M
624         //p_context->rc_min_rate = 40 * 1000; // 40k
625         /* seems that ffmpeg presets have 720p as divider for buffers */
626         if( p_enc->fmt_out.video.i_height >= 720 )
627         {
628             /* Check that we don't overrun users qmin/qmax values */
629             if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ) )
630             {
631                 p_context->qmin = 10;
632                 p_context->mb_lmin = p_context->lmin = 10 * FF_QP2LAMBDA;
633             }
634
635             if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmax" ) )
636             {
637                 p_context->qmax = 42;
638                 p_context->mb_lmax = p_context->lmax = 42 * FF_QP2LAMBDA;
639             }
640
641             } else {
642             if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ) )
643             {
644                 p_context->qmin = 1;
645                 p_context->mb_lmin = p_context->lmin = FF_QP2LAMBDA;
646             }
647         }
648
649
650 #if 0 /* enable when/if vp8 encoder is accepted in libavcodec */
651         p_context->lag = 16;
652         p_context->level = 216;
653         p_context->profile = 0;
654         p_context->rc_buffer_aggressivity = 0.95;
655         p_context->token_partitions = 4;
656         p_context->mb_static_threshold = 0;
657 #endif
658     }
659 #endif
660
661     if( i_codec_id == CODEC_ID_RAWVIDEO )
662     {
663         /* XXX: hack: Force same codec (will be handled by transcode) */
664         p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
665         GetFfmpegChroma( &p_context->pix_fmt, p_enc->fmt_in.video );
666     }
667
668     /* Make sure we get extradata filled by the encoder */
669     p_context->extradata_size = 0;
670     p_context->extradata = NULL;
671     p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
672
673     if( p_enc->i_threads >= 1)
674         p_context->thread_count = p_enc->i_threads;
675     else
676         p_context->thread_count = vlc_GetCPUCount();
677
678     int ret;
679     vlc_avcodec_lock();
680     ret = avcodec_open( p_context, p_codec );
681     vlc_avcodec_unlock();
682     if( ret )
683     {
684         if( p_enc->fmt_in.i_cat == AUDIO_ES &&
685              (p_context->channels > 2 || i_codec_id == CODEC_ID_MP2
686                || i_codec_id == CODEC_ID_MP3) )
687         {
688             if( p_context->channels > 2 )
689             {
690                 p_context->channels = 2;
691                 p_enc->fmt_in.audio.i_channels = 2; // FIXME
692                 msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
693             }
694
695             if( i_codec_id == CODEC_ID_MP2 || i_codec_id == CODEC_ID_MP3 )
696             {
697                 int i_frequency, i;
698
699                 for ( i_frequency = 0; i_frequency < 6; i_frequency++ )
700                 {
701                     if ( p_enc->fmt_out.audio.i_rate
702                             == mpa_freq_tab[i_frequency] )
703                         break;
704                 }
705                 if ( i_frequency == 6 )
706                 {
707                     msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
708                              p_enc->fmt_out.audio.i_rate );
709                     free( p_sys );
710                     return VLC_EGENERIC;
711                 }
712
713                 for ( i = 1; i < 14; i++ )
714                 {
715                     if ( p_enc->fmt_out.i_bitrate / 1000
716                           <= mpa_bitrate_tab[i_frequency / 3][i] )
717                         break;
718                 }
719                 if ( p_enc->fmt_out.i_bitrate / 1000
720                       != mpa_bitrate_tab[i_frequency / 3][i] )
721                 {
722                     msg_Warn( p_enc,
723                               "MPEG audio doesn't support bitrate=%d, using %d",
724                               p_enc->fmt_out.i_bitrate,
725                               mpa_bitrate_tab[i_frequency / 3][i] * 1000 );
726                     p_enc->fmt_out.i_bitrate =
727                         mpa_bitrate_tab[i_frequency / 3][i] * 1000;
728                     p_context->bit_rate = p_enc->fmt_out.i_bitrate;
729                 }
730             }
731
732             p_context->codec = NULL;
733             vlc_avcodec_lock();
734             ret = avcodec_open( p_context, p_codec );
735             vlc_avcodec_unlock();
736             if( ret )
737             {
738                 msg_Err( p_enc, "cannot open encoder" );
739                 dialog_Fatal( p_enc,
740                                 _("Streaming / Transcoding failed"),
741                                 "%s", _("VLC could not open the encoder.") );
742                 free( p_sys );
743                 return VLC_EGENERIC;
744             }
745         }
746         else
747         {
748             msg_Err( p_enc, "cannot open encoder" );
749             dialog_Fatal( p_enc, _("Streaming / Transcoding failed"),
750                             "%s", _("VLC could not open the encoder.") );
751             free( p_sys );
752             return VLC_EGENERIC;
753         }
754     }
755
756     if( i_codec_id == CODEC_ID_FLAC )
757     {
758         p_enc->fmt_out.i_extra = 4 + 1 + 3 + p_context->extradata_size;
759         p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
760         if( p_enc->fmt_out.p_extra )
761         {
762             uint8_t *p = p_enc->fmt_out.p_extra;
763             p[0] = 0x66;    /* f */
764             p[1] = 0x4C;    /* L */
765             p[2] = 0x61;    /* a */
766             p[3] = 0x43;    /* C */
767             p[4] = 0x80;    /* streaminfo block, last block before audio */
768             p[5] = ( p_context->extradata_size >> 16 ) & 0xff;
769             p[6] = ( p_context->extradata_size >>  8 ) & 0xff;
770             p[7] = ( p_context->extradata_size       ) & 0xff;
771             memcpy( &p[8], p_context->extradata, p_context->extradata_size );
772         }
773         else
774         {
775             p_enc->fmt_out.i_extra = 0;
776         }
777     }
778     else
779     {
780         p_enc->fmt_out.i_extra = p_context->extradata_size;
781         if( p_enc->fmt_out.i_extra )
782         {
783             p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
784             if ( p_enc->fmt_out.p_extra == NULL )
785             {
786                 goto error;
787             }
788             memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
789                     p_enc->fmt_out.i_extra );
790         }
791     }
792
793     p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
794
795     if( p_enc->fmt_in.i_cat == AUDIO_ES )
796     {
797         GetVlcAudioFormat( &p_enc->fmt_in.i_codec,
798                            &p_enc->fmt_in.audio.i_bitspersample,
799                            p_sys->p_context->sample_fmt );
800         p_sys->i_sample_bytes = (p_enc->fmt_in.audio.i_bitspersample / 8) *
801                                 p_context->channels;
802         p_sys->i_frame_size = p_context->frame_size > 1 ?
803                                     p_context->frame_size :
804                                     RAW_AUDIO_FRAME_SIZE;
805         p_sys->p_buffer = malloc( p_sys->i_frame_size * p_sys->i_sample_bytes );
806         if ( p_sys->p_buffer == NULL )
807         {
808             goto error;
809         }
810         p_enc->fmt_out.audio.i_blockalign = p_context->block_align;
811         p_enc->fmt_out.audio.i_bitspersample = aout_BitsPerSample( vlc_fourcc_GetCodec( AUDIO_ES, p_enc->fmt_out.i_codec ) );
812
813         if( p_context->frame_size > 1 )
814             p_sys->i_buffer_out = 8 * AVCODEC_MAX_AUDIO_FRAME_SIZE;
815         else
816             p_sys->i_buffer_out = p_sys->i_frame_size * p_sys->i_sample_bytes;
817         p_sys->p_buffer_out = malloc( p_sys->i_buffer_out );
818         if ( p_sys->p_buffer_out == NULL )
819         {
820             goto error;
821         }
822     }
823
824     msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
825
826     return VLC_SUCCESS;
827 error:
828     free( p_enc->fmt_out.p_extra );
829     free( p_sys->p_buffer );
830     free( p_sys->p_buffer_out );
831     free( p_sys );
832     return VLC_ENOMEM;
833 }
834
835 /****************************************************************************
836  * EncodeVideo: the whole thing
837  ****************************************************************************/
838 static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
839 {
840     encoder_sys_t *p_sys = p_enc->p_sys;
841     int i_out, i_plane;
842
843     /* Initialize the video output buffer the first time.
844      * This is done here instead of OpenEncoder() because we need the actual
845      * bits_per_pixel value, without having to assume anything.
846      */
847     if ( p_sys->p_buffer_out == NULL )
848     {
849         int bytesPerPixel = p_enc->fmt_out.video.i_bits_per_pixel ?
850                             p_enc->fmt_out.video.i_bits_per_pixel / 8 : 3;
851
852         p_sys->i_buffer_out = p_sys->p_context->height * p_sys->p_context->width
853             * bytesPerPixel + 200;  /* some room for potential headers (such as BMP) */
854
855         if( p_sys->i_buffer_out < FF_MIN_BUFFER_SIZE )
856             p_sys->i_buffer_out = FF_MIN_BUFFER_SIZE;
857         p_sys->p_buffer_out = malloc( p_sys->i_buffer_out );
858         if ( p_sys->p_buffer_out == NULL )
859             return NULL;
860     }
861
862     if( likely(p_pict) ) {
863         AVFrame frame;
864         memset( &frame, 0, sizeof( AVFrame ) );
865         for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
866         {
867             frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
868             frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
869         }
870
871         /* Let ffmpeg select the frame type */
872         frame.pict_type = 0;
873
874         frame.repeat_pict = p_pict->i_nb_fields - 2;
875         frame.interlaced_frame = !p_pict->b_progressive;
876         frame.top_field_first = !!p_pict->b_top_field_first;
877
878         /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
879         if( p_enc->fmt_out.i_codec != VLC_CODEC_MP4V )
880         {
881             frame.pts = p_pict->date ? p_pict->date : (int64_t)AV_NOPTS_VALUE;
882
883             if ( p_sys->b_hurry_up && frame.pts != (int64_t)AV_NOPTS_VALUE )
884             {
885                 mtime_t current_date = mdate();
886
887                 if ( current_date + HURRY_UP_GUARD3 > frame.pts )
888                 {
889                     p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE;
890                     p_sys->p_context->trellis = 0;
891                     msg_Dbg( p_enc, "hurry up mode 3" );
892                 }
893                 else
894                 {
895                     p_sys->p_context->mb_decision = p_sys->i_hq;
896
897                     if ( current_date + HURRY_UP_GUARD2 > frame.pts )
898                     {
899                         p_sys->p_context->trellis = 0;
900                         p_sys->p_context->noise_reduction = p_sys->i_noise_reduction
901                             + (HURRY_UP_GUARD2 + current_date - frame.pts) / 500;
902                         msg_Dbg( p_enc, "hurry up mode 2" );
903                     }
904                     else
905                     {
906                         p_sys->p_context->trellis = p_sys->b_trellis;
907
908                         p_sys->p_context->noise_reduction =
909                            p_sys->i_noise_reduction;
910                     }
911                 }
912
913                 if ( current_date + HURRY_UP_GUARD1 > frame.pts )
914                 {
915                     frame.pict_type = FF_P_TYPE;
916                     /* msg_Dbg( p_enc, "hurry up mode 1 %lld", current_date + HURRY_UP_GUARD1 - frame.pts ); */
917                 }
918             }
919         }
920         else
921         {
922             frame.pts = (int64_t)AV_NOPTS_VALUE;
923         }
924
925         if ( frame.pts != (int64_t)AV_NOPTS_VALUE && frame.pts != 0 )
926         {
927             if ( p_sys->i_last_pts == frame.pts )
928             {
929                 msg_Warn( p_enc, "almost fed libavcodec with two frames with the "
930                          "same PTS (%"PRId64 ")", frame.pts );
931                 return NULL;
932             }
933             else if ( p_sys->i_last_pts > frame.pts )
934             {
935                 msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
936                          "past (current: %"PRId64 ", last: %"PRId64")",
937                          frame.pts, p_sys->i_last_pts );
938                 return NULL;
939             }
940             else
941             {
942                 p_sys->i_last_pts = frame.pts;
943             }
944         }
945
946         frame.quality = p_sys->i_quality;
947
948         /* Ugly work-around for stupid libavcodec behaviour */
949         p_sys->i_framenum++;
950         p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts;
951         frame.pts = p_sys->i_framenum * AV_TIME_BASE *
952             p_enc->fmt_in.video.i_frame_rate_base;
953         frame.pts += p_enc->fmt_in.video.i_frame_rate - 1;
954         frame.pts /= p_enc->fmt_in.video.i_frame_rate;
955         /* End work-around */
956
957         i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
958                                      p_sys->i_buffer_out, &frame );
959     }
960     else
961     {
962         i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
963                                      p_sys->i_buffer_out, NULL);
964     }
965
966     if( i_out <= 0 )
967         return NULL;
968
969     block_t *p_block = block_New( p_enc, i_out );
970     memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
971
972     /* FIXME, 3-2 pulldown is not handled correctly */
973     p_block->i_length = INT64_C(1000000) *
974         p_enc->fmt_in.video.i_frame_rate_base /
975             p_enc->fmt_in.video.i_frame_rate;
976
977     if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay )
978     {
979         /* No delay -> output pts == input pts */
980         if( p_pict )
981             p_block->i_dts = p_pict->date;
982         p_block->i_pts = p_block->i_dts;
983     }
984     else if( p_sys->p_context->coded_frame->pts != (int64_t)AV_NOPTS_VALUE &&
985         p_sys->p_context->coded_frame->pts != 0 &&
986         p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
987     {
988         p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
989         p_block->i_pts = p_sys->p_context->coded_frame->pts;
990
991         /* Ugly work-around for stupid libavcodec behaviour */
992         {
993             int64_t i_framenum = p_block->i_pts *
994                 p_enc->fmt_in.video.i_frame_rate /
995                 p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE;
996
997             p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY];
998         }
999         /* End work-around */
1000
1001         if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
1002             p_sys->p_context->coded_frame->pict_type != FF_P_TYPE )
1003         {
1004             p_block->i_dts = p_block->i_pts;
1005         }
1006         else
1007         {
1008             if( p_sys->i_last_ref_pts )
1009             {
1010                 p_block->i_dts = p_sys->i_last_ref_pts;
1011             }
1012             else
1013             {
1014                 /* Let's put something sensible */
1015                 p_block->i_dts = p_block->i_pts;
1016             }
1017
1018             p_sys->i_last_ref_pts = p_block->i_pts;
1019         }
1020     }
1021     else if( p_pict )
1022     {
1023         /* Buggy libavcodec which doesn't update coded_frame->pts
1024          * correctly */
1025         p_block->i_dts = p_block->i_pts = p_pict->date;
1026     }
1027
1028     switch ( p_sys->p_context->coded_frame->pict_type )
1029     {
1030     case FF_I_TYPE:
1031         p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1032         break;
1033     case FF_P_TYPE:
1034         p_block->i_flags |= BLOCK_FLAG_TYPE_P;
1035         break;
1036     case FF_B_TYPE:
1037         p_block->i_flags |= BLOCK_FLAG_TYPE_B;
1038         break;
1039     }
1040
1041     return p_block;
1042 }
1043
1044 /****************************************************************************
1045  * EncodeAudio: the whole thing
1046  ****************************************************************************/
1047 static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
1048 {
1049     encoder_sys_t *p_sys = p_enc->p_sys;
1050
1051     block_t *p_block, *p_chain = NULL;
1052
1053     uint8_t *p_buffer = p_aout_buf->p_buffer;
1054     int i_samples = p_aout_buf->i_nb_samples;
1055     int i_samples_delay = p_sys->i_samples_delay;
1056
1057     p_sys->i_pts = p_aout_buf->i_pts -
1058                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
1059                 (mtime_t)p_enc->fmt_in.audio.i_rate;
1060
1061     p_sys->i_samples_delay += i_samples;
1062
1063     while( p_sys->i_samples_delay >= p_sys->i_frame_size )
1064     {
1065         void *p_samples;
1066         int i_out;
1067
1068         if( i_samples_delay )
1069         {
1070             /* Take care of the left-over from last time */
1071             int i_delay_size = i_samples_delay;
1072             int i_size = (p_sys->i_frame_size - i_delay_size) *
1073                          p_sys->i_sample_bytes;
1074
1075             memcpy( p_sys->p_buffer + i_delay_size * p_sys->i_sample_bytes,
1076                     p_buffer, i_size );
1077             p_buffer -= i_delay_size * p_sys->i_sample_bytes;
1078             i_samples += i_samples_delay;
1079             i_samples_delay = 0;
1080
1081             p_samples = p_sys->p_buffer;
1082         }
1083         else
1084         {
1085             p_samples = p_buffer;
1086         }
1087
1088         i_out = avcodec_encode_audio( p_sys->p_context, p_sys->p_buffer_out,
1089                                       p_sys->i_buffer_out, p_samples );
1090
1091 #if 0
1092         msg_Warn( p_enc, "avcodec_encode_audio: %d", i_out );
1093 #endif
1094         p_buffer += p_sys->i_frame_size * p_sys->i_sample_bytes;
1095         p_sys->i_samples_delay -= p_sys->i_frame_size;
1096         i_samples -= p_sys->i_frame_size;
1097
1098         if( i_out <= 0 )
1099             continue;
1100
1101         p_block = block_New( p_enc, i_out );
1102         memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
1103
1104         p_block->i_length = (mtime_t)1000000 *
1105             (mtime_t)p_sys->i_frame_size /
1106             (mtime_t)p_sys->p_context->sample_rate;
1107
1108         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
1109
1110         /* Update pts */
1111         p_sys->i_pts += p_block->i_length;
1112         block_ChainAppend( &p_chain, p_block );
1113     }
1114
1115     /* Backup the remaining raw samples */
1116     if( i_samples )
1117     {
1118         memcpy( &p_sys->p_buffer[i_samples_delay * p_sys->i_sample_bytes],
1119                 p_buffer,
1120                 i_samples * p_sys->i_sample_bytes );
1121     }
1122
1123     return p_chain;
1124 }
1125
1126 /*****************************************************************************
1127  * CloseEncoder: ffmpeg encoder destruction
1128  *****************************************************************************/
1129 void CloseEncoder( vlc_object_t *p_this )
1130 {
1131     encoder_t *p_enc = (encoder_t *)p_this;
1132     encoder_sys_t *p_sys = p_enc->p_sys;
1133
1134     vlc_avcodec_lock();
1135     avcodec_close( p_sys->p_context );
1136     vlc_avcodec_unlock();
1137     av_free( p_sys->p_context );
1138
1139     free( p_sys->p_buffer );
1140     free( p_sys->p_buffer_out );
1141
1142     free( p_sys );
1143 }