]> git.sesse.net Git - vlc/blob - modules/codec/ffmpeg/encoder.c
199cd042256b2564da66a426283b366d797f1499
[vlc] / modules / codec / ffmpeg / encoder.c
1 /*****************************************************************************
2  * encoder.c: video and audio encoder using the ffmpeg library
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: encoder.c,v 1.1 2003/10/27 01:04:38 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>                                      /* malloc(), free() */
29 #include <string.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/vout.h>
33 #include <vlc/aout.h>
34 #include <vlc/decoder.h>
35 #include <vlc/input.h>
36 #include <vlc/sout.h>
37
38 #include "aout_internal.h"
39
40 /* ffmpeg header */
41 #ifdef HAVE_FFMPEG_AVCODEC_H
42 #   include <ffmpeg/avcodec.h>
43 #else
44 #   include <avcodec.h>
45 #endif
46
47 #include "ffmpeg.h"
48
49 #define AVCODEC_MAX_VIDEO_FRAME_SIZE (3*1024*1024)
50
51 /*****************************************************************************
52  * Local prototypes
53  *****************************************************************************/
54 int  E_(OpenVideoEncoder) ( vlc_object_t * );
55 void E_(CloseVideoEncoder)( vlc_object_t * );
56
57 int  E_(OpenAudioEncoder) ( vlc_object_t * );
58 void E_(CloseAudioEncoder)( vlc_object_t * );
59
60 static block_t *EncodeVideo( encoder_t *, picture_t * );
61 static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );
62
63 /*****************************************************************************
64  * encoder_sys_t : ffmpeg encoder descriptor
65  *****************************************************************************/
66 struct encoder_sys_t
67 {
68     /*
69      * Ffmpeg properties
70      */
71     AVCodec         *p_codec;
72     AVCodecContext  *p_context;
73
74     /*
75      * Packetizer output properties
76      */
77     sout_packetizer_input_t *p_sout_input;
78     sout_format_t           sout_format;
79
80     /*
81      * Common properties
82      */
83     int i_last_block_size;
84     int i_samples_delay;
85     mtime_t i_pts;
86
87     mtime_t i_last_ref_pts;
88     mtime_t i_buggy_pts_detect;
89
90     int i_frame_size;
91
92     char *p_buffer;
93     char *p_buffer_out;
94 };
95
96 /*****************************************************************************
97  * OpenVideoEncoder: probe the encoder
98  *****************************************************************************/
99 int E_(OpenVideoEncoder)( vlc_object_t *p_this )
100 {
101     encoder_t *p_enc = (encoder_t *)p_this;
102     encoder_sys_t *p_sys = p_enc->p_sys;
103     AVCodecContext  *p_context;
104     AVCodec *p_codec;
105     int i_ff_codec;
106
107     /* find encoder */
108     i_ff_codec = E_(GetFfmpegCodec)( p_enc->i_fourcc, 0, 0, 0 );
109     if( !i_ff_codec )
110     {
111         return VLC_EGENERIC;
112     }
113
114     p_codec = avcodec_find_encoder( i_ff_codec );
115     if( !p_codec )
116     {
117         return VLC_EGENERIC;
118     }
119
120     /* libavcodec needs to be initialized */
121     E_(InitLibavcodec)(p_this);
122
123     /* Allocate the memory needed to store the decoder's structure */
124     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
125     {
126         msg_Err( p_enc, "out of memory" );
127         return VLC_EGENERIC;
128     }
129     p_enc->p_sys = p_sys;
130     p_sys->p_codec = p_codec;
131
132     p_enc->pf_header = NULL;
133     p_enc->pf_encode_video = EncodeVideo;
134     p_enc->format.video.i_chroma = VLC_FOURCC('I','4','2','0');
135
136     if( p_enc->i_fourcc == VLC_FOURCC( 'm','p','1','v' ) ||
137         p_enc->i_fourcc == VLC_FOURCC( 'm','p','2','v' ) )
138     {
139         p_enc->i_fourcc = VLC_FOURCC( 'm','p','g','v' );
140     }
141
142     p_sys->p_context = p_context = avcodec_alloc_context();
143     p_context->width = p_enc->format.video.i_width;
144     p_context->height = p_enc->format.video.i_height;
145     p_context->bit_rate = p_enc->i_bitrate;
146
147     p_context->frame_rate = p_enc->i_frame_rate;
148     p_context->frame_rate_base= p_enc->i_frame_rate_base;
149
150     p_context->gop_size = p_enc->i_key_int >= 0 ? p_enc->i_key_int : 50;
151     p_context->max_b_frames =
152         __MIN( p_enc->i_b_frames, FF_MAX_B_FRAMES );
153     p_context->b_frame_strategy = 0;
154     p_context->b_quant_factor = 2.0;
155
156     if( p_enc->i_vtolerance >= 0 )
157     {
158         p_context->bit_rate_tolerance = p_enc->i_vtolerance;
159     }
160     p_context->qmin = p_enc->i_qmin;
161     p_context->qmax = p_enc->i_qmax;
162
163 #if LIBAVCODEC_BUILD >= 4673
164     p_context->mb_decision = p_enc->i_hq;
165 #else
166     if( p_enc->i_hq )
167     {
168         p_context->flags |= CODEC_FLAG_HQ;
169     }
170 #endif
171
172     if( i_ff_codec == CODEC_ID_RAWVIDEO )
173     {
174         p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->i_fourcc );
175     }
176
177     /* Make sure we get extradata filled by the encoder */
178     p_context->extradata_size = 0;
179     p_context->extradata = NULL;
180     p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
181
182     if( avcodec_open( p_context, p_sys->p_codec ) )
183     {
184         msg_Err( p_enc, "cannot open encoder" );
185         return VLC_EGENERIC;
186     }
187
188     p_enc->i_extra_data = p_context->extradata_size;
189     p_enc->p_extra_data = p_context->extradata;
190     p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
191
192     p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE );
193     p_sys->i_last_ref_pts = 0;
194     p_sys->i_buggy_pts_detect = 0;
195
196     return VLC_SUCCESS;
197 }
198
199 /****************************************************************************
200  * EncodeVideo: the whole thing
201  ****************************************************************************/
202 static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
203 {
204     encoder_sys_t *p_sys = p_enc->p_sys;
205     AVFrame frame;
206     int i_out, i_plane;
207
208     for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
209     {
210         frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
211         frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
212     }
213
214     frame.pts = p_pict->date;
215
216     /* Let ffmpeg select the frame type */
217     frame.pict_type = 0;
218
219     i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
220                                   AVCODEC_MAX_VIDEO_FRAME_SIZE, &frame );
221     if( i_out > 0 )
222     {
223         block_t *p_block = block_New( p_enc, i_out );
224         memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
225
226         if( p_sys->p_context->coded_frame->pts != 0 &&
227             p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
228         {
229             p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
230
231             /* FIXME, 3-2 pulldown is not handled correctly */
232             p_block->i_length = 0;//in->i_length;
233             p_block->i_pts    = p_sys->p_context->coded_frame->pts;
234
235             if( !p_sys->p_context->delay ||
236                 ( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
237                   p_sys->p_context->coded_frame->pict_type != FF_P_TYPE ) )
238             {
239                 p_block->i_dts = p_block->i_pts;
240             }
241             else
242             {
243                 if( p_sys->i_last_ref_pts )
244                 {
245                     p_block->i_dts = p_sys->i_last_ref_pts;
246                 }
247                 else
248                 {
249                     /* Let's put something sensible */
250                     p_block->i_dts = p_block->i_pts;
251                 }
252
253                 p_sys->i_last_ref_pts = p_block->i_pts;
254             }
255         }
256         else
257         {
258             /* Buggy libavcodec which doesn't update coded_frame->pts
259              * correctly */
260             p_block->i_length = 0;//in->i_length;
261             p_block->i_dts = p_block->i_pts = p_pict->date;
262         }
263
264         return p_block;
265     }
266
267     return NULL;
268 }
269
270 /*****************************************************************************
271  * CloseVideoEncoder: ffmpeg video encoder destruction
272  *****************************************************************************/
273 void E_(CloseVideoEncoder)( vlc_object_t *p_this )
274 {
275     encoder_t *p_enc = (encoder_t *)p_this;
276     encoder_sys_t *p_sys = p_enc->p_sys;
277
278     avcodec_close( p_sys->p_context );
279     free( p_sys->p_context );
280     free( p_sys->p_buffer_out );
281     free( p_sys );
282 }
283
284 /*****************************************************************************
285  * OpenAudioEncoder: probe the encoder
286  *****************************************************************************/
287 int E_(OpenAudioEncoder)( vlc_object_t *p_this )
288 {
289     encoder_t *p_enc = (encoder_t *)p_this;
290     encoder_sys_t *p_sys = p_enc->p_sys;
291     AVCodecContext  *p_context;
292     AVCodec *p_codec;
293     int i_ff_codec;
294
295     i_ff_codec = E_(GetFfmpegCodec)( p_enc->i_fourcc, 0, 0, 0 );
296     if( i_ff_codec == 0 )
297     {
298         msg_Err( p_enc, "cannot find encoder id" );
299         return VLC_EGENERIC;
300     }
301
302     p_codec = avcodec_find_encoder( i_ff_codec );
303     if( !p_codec )
304     {
305         msg_Err( p_enc, "cannot find encoder (avcodec)" );
306         return VLC_EGENERIC;
307     }
308
309     /* libavcodec needs to be initialized */
310     E_(InitLibavcodec)(p_this);
311
312     /* Allocate the memory needed to store the decoder's structure */
313     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
314     {
315         msg_Err( p_enc, "out of memory" );
316         return VLC_EGENERIC;
317     }
318     p_enc->p_sys = p_sys;
319     p_sys->p_codec = p_codec;
320
321     p_enc->pf_header = NULL;
322     p_enc->pf_encode_audio = EncodeAudio;
323     p_enc->format.audio.i_format = VLC_FOURCC('s','1','6','n');
324
325     p_sys->p_context = p_context = avcodec_alloc_context();
326     p_context->bit_rate    = p_enc->i_bitrate;
327     p_context->sample_rate = p_enc->format.audio.i_rate;
328     p_context->channels    =
329         aout_FormatNbChannels( &p_enc->format.audio );
330
331     /* Make sure we get extradata filled by the encoder */
332     p_context->extradata_size = 0;
333     p_context->extradata = NULL;
334     p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
335
336     p_sys->i_samples_delay = 0;
337     p_sys->i_last_block_size = 0;
338     p_sys->i_pts = 0;
339
340     if( avcodec_open( p_context, p_sys->p_codec ) )
341     {
342 #if 0
343         if( p_context->channels > 2 )
344         {
345             p_context->channels = 2;
346             id->f_dst.i_channels   = 2;
347             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
348             {
349                 msg_Err( p_enc, "cannot open encoder" );
350                 return VLC_EGENERIC;
351             }
352             msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
353         }
354         else
355         {
356             msg_Err( p_enc, "cannot open encoder" );
357             return VLC_EGENERIC;
358         }
359 #endif
360     }
361
362     p_enc->i_extra_data = p_context->extradata_size;
363     p_enc->p_extra_data = p_context->extradata;
364     p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
365
366     p_sys->p_buffer = malloc( p_context->frame_size * 2 *
367                               p_context->channels * 2 );
368
369     p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
370
371     p_sys->i_frame_size = p_sys->p_context->frame_size * 2 *
372                             p_context->channels;
373
374     /* Hack for mp3 transcoding support */
375     if( p_enc->i_fourcc == VLC_FOURCC( 'm','p','3',' ' ) )
376     {
377         p_enc->i_fourcc = VLC_FOURCC( 'm','p','g','a' );
378     }
379
380     return VLC_SUCCESS;
381 }
382
383 /****************************************************************************
384  * EncodeAudio: the whole thing
385  ****************************************************************************/
386 static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
387 {
388     encoder_sys_t *p_sys = p_enc->p_sys;
389     block_t *p_block, *p_chain = NULL;
390     char *p_buffer = p_aout_buf->p_buffer;
391     int i_samples = p_aout_buf->i_nb_samples;
392     int i_samples_delay = p_sys->i_samples_delay;
393
394     p_sys->i_pts = p_aout_buf->start_date -
395                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
396                 (mtime_t)p_enc->format.audio.i_rate;
397
398     p_sys->i_samples_delay += i_samples;
399
400     while( p_sys->i_samples_delay >= p_sys->p_context->frame_size )
401     {
402         int16_t *p_samples;
403         int i_out;
404
405         if( i_samples_delay )
406         {
407             /* Take care of the left-over from last time */
408             int i_delay_size = i_samples_delay  * 2 *
409                                  p_sys->p_context->channels;
410             int i_size = p_sys->i_frame_size - i_delay_size;
411
412             p_samples = (int16_t *)p_sys->p_buffer;
413             memcpy( p_sys->p_buffer + i_delay_size, p_buffer, i_size );
414             p_buffer -= i_delay_size;
415             i_samples += i_samples_delay;
416             i_samples_delay = 0;
417         }
418         else
419         {
420             p_samples = (int16_t *)p_buffer;
421         }
422
423         i_out = avcodec_encode_audio( p_sys->p_context, p_sys->p_buffer_out,
424                                       2 * AVCODEC_MAX_AUDIO_FRAME_SIZE,
425                                       p_samples );
426         if( i_out <= 0 )
427         {
428             break;
429         }
430
431         p_buffer += p_sys->i_frame_size;
432         p_sys->i_samples_delay -= p_sys->p_context->frame_size;
433         i_samples = p_sys->p_context->frame_size;
434
435         p_block = block_New( p_enc, i_out );
436         memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
437
438         p_block->i_length = (mtime_t)1000000 *
439             (mtime_t)p_sys->p_context->frame_size /
440             (mtime_t)p_sys->p_context->sample_rate;
441
442         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
443
444         /* Update pts */
445         p_sys->i_pts += p_block->i_length;
446         block_ChainAppend( &p_chain, p_block );
447     }
448
449     /* Backup the remaining raw samples */
450     if( p_sys->i_samples_delay > 0 )
451     {
452         memcpy( p_sys->p_buffer, p_buffer + i_samples_delay,
453                 i_samples * 2 * p_sys->p_context->channels );
454     }
455
456     return p_chain;
457 }
458
459 /*****************************************************************************
460  * CloseAudioEncoder: ffmpeg audio encoder destruction
461  *****************************************************************************/
462 void E_(CloseAudioEncoder)( vlc_object_t *p_this )
463 {
464     encoder_t *p_enc = (encoder_t *)p_this;
465     encoder_sys_t *p_sys = p_enc->p_sys;
466
467     avcodec_close( p_sys->p_context );
468     free( p_sys->p_context );
469     free( p_sys->p_buffer );
470     free( p_sys->p_buffer_out );
471     free( p_sys );
472 }