]> git.sesse.net Git - vlc/blob - modules/codec/ffmpeg/encoder.c
* ALL: final improvements to the decoders/packetizers api.
[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.7 2003/11/16 21:07:31 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_(OpenEncoder) ( vlc_object_t * );
55 void E_(CloseEncoder)( vlc_object_t * );
56
57 static block_t *EncodeVideo( encoder_t *, picture_t * );
58 static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );
59
60 /*****************************************************************************
61  * encoder_sys_t : ffmpeg encoder descriptor
62  *****************************************************************************/
63 struct encoder_sys_t
64 {
65     /*
66      * Ffmpeg properties
67      */
68     AVCodec         *p_codec;
69     AVCodecContext  *p_context;
70
71     /*
72      * Common properties
73      */
74     char *p_buffer;
75     char *p_buffer_out;
76
77     /*
78      * Videoo properties
79      */
80     mtime_t i_last_ref_pts;
81     mtime_t i_buggy_pts_detect;
82
83     /*
84      * Audio properties
85      */
86     int i_frame_size;
87     int i_samples_delay;
88     mtime_t i_pts;
89 };
90
91 /*****************************************************************************
92  * OpenEncoder: probe the encoder
93  *****************************************************************************/
94 int E_(OpenEncoder)( vlc_object_t *p_this )
95 {
96     encoder_t *p_enc = (encoder_t *)p_this;
97     encoder_sys_t *p_sys = p_enc->p_sys;
98     AVCodecContext *p_context;
99     AVCodec *p_codec;
100     int i_codec_id, i_cat;
101     char *psz_namecodec;
102
103     if( !E_(GetFfmpegCodec)( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
104                              &psz_namecodec ) )
105     {
106         return VLC_EGENERIC;
107     }
108
109     if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
110     {
111         msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
112         return VLC_EGENERIC;
113     }
114
115     if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )
116     {
117         msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
118         return VLC_EGENERIC;
119     }
120
121     /* Initialization must be done before avcodec_find_decoder() */
122     E_(InitLibavcodec)(p_this);
123
124     p_codec = avcodec_find_encoder( i_codec_id );
125     if( !p_codec )
126     {
127         msg_Err( p_enc, "cannot find encoder %s", psz_namecodec );
128         return VLC_EGENERIC;
129     }
130
131     /* Allocate the memory needed to store the decoder's structure */
132     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
133     {
134         msg_Err( p_enc, "out of memory" );
135         return VLC_EGENERIC;
136     }
137     p_enc->p_sys = p_sys;
138     p_sys->p_codec = p_codec;
139
140     p_enc->pf_encode_video = EncodeVideo;
141     p_enc->pf_encode_audio = EncodeAudio;
142
143     p_sys->p_buffer_out = NULL;
144     p_sys->p_buffer = NULL;
145
146     p_sys->p_context = p_context = avcodec_alloc_context();
147
148     /* Set CPU capabilities */
149 #ifdef HAVE_MMX
150     p_context->dsp_mask = 0;
151     if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
152     {
153         p_context->dsp_mask &= FF_MM_MMX;
154     }
155     if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT )
156     {
157         p_context->dsp_mask &= FF_MM_MMXEXT;
158     }
159     if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW )
160     {
161         p_context->dsp_mask &= FF_MM_3DNOW;
162     }
163     if( p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE )
164     {
165         p_context->dsp_mask &= FF_MM_SSE;
166         p_context->dsp_mask &= FF_MM_SSE2; /* FIXME */
167     }
168     /* Hack to make sure everything can be disabled **/
169     p_context->dsp_mask &= (FF_MM_FORCE >> 1);
170 #endif
171
172     /* Make sure we get extradata filled by the encoder */
173     p_context->extradata_size = 0;
174     p_context->extradata = NULL;
175     p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
176
177     if( p_enc->fmt_in.i_cat == VIDEO_ES )
178     {
179         p_context->width = p_enc->fmt_in.video.i_width;
180         p_context->height = p_enc->fmt_in.video.i_height;
181
182         p_context->frame_rate = p_enc->fmt_in.video.i_frame_rate;
183 #if LIBAVCODEC_BUILD >= 4662
184         p_context->frame_rate_base= p_enc->fmt_in.video.i_frame_rate_base;
185 #endif
186
187 #if LIBAVCODEC_BUILD >= 4687
188         p_context->sample_aspect_ratio =
189             av_d2q( p_enc->fmt_in.video.i_aspect * p_context->height /
190                     p_context->width / VOUT_ASPECT_FACTOR, 255 );
191 #else
192         p_context->aspect_ratio = ((float)p_enc->fmt_in.video.i_aspect) /
193             VOUT_ASPECT_FACTOR;
194 #endif
195
196         p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE );
197
198         /* Ffmpeg does handle the conversion itself */
199         //p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
200     }
201     else if( p_enc->fmt_in.i_cat == AUDIO_ES )
202     {
203         p_enc->fmt_in.i_codec  = AOUT_FMT_S16_NE;
204         p_context->bit_rate    = p_enc->fmt_out.i_bitrate;
205         p_context->sample_rate = p_enc->fmt_in.audio.i_rate;
206         p_context->channels    = p_enc->fmt_in.audio.i_channels;
207         p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
208         p_sys->p_buffer = malloc( p_sys->i_frame_size );
209         p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
210     }
211
212     /* Misc parameters */
213     p_context->gop_size = p_enc->i_key_int > 0 ? p_enc->i_key_int : 50;
214     p_context->max_b_frames =
215         __MIN( p_enc->i_b_frames, FF_MAX_B_FRAMES );
216     p_context->b_frame_strategy = 0;
217     p_context->b_quant_factor = 2.0;
218
219     if( p_enc->i_vtolerance > 0 )
220     {
221         p_context->bit_rate_tolerance = p_enc->i_vtolerance;
222     }
223     p_context->qmin = p_enc->i_qmin;
224     p_context->qmax = p_enc->i_qmax;
225
226 #if LIBAVCODEC_BUILD >= 4673
227     p_context->mb_decision = p_enc->i_hq;
228 #else
229     if( p_enc->i_hq )
230     {
231         p_context->flags |= CODEC_FLAG_HQ;
232     }
233 #endif
234
235     if( i_codec_id == CODEC_ID_RAWVIDEO )
236     {
237         p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
238     }
239
240     /* Make sure we get extradata filled by the encoder */
241     p_context->extradata_size = 0;
242     p_context->extradata = NULL;
243     p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
244
245     if( avcodec_open( p_context, p_codec ) )
246     {
247         if( p_enc->fmt_in.i_cat == AUDIO_ES && p_context->channels > 2 )
248         {
249             p_context->channels = 2;
250             p_enc->fmt_in.audio.i_channels = 2; // FIXME
251             if( avcodec_open( p_context, p_codec ) )
252             {
253                 msg_Err( p_enc, "cannot open encoder" );
254                 return VLC_EGENERIC;
255             }
256             msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
257         }
258         else
259         {
260             msg_Err( p_enc, "cannot open encoder" );
261             return VLC_EGENERIC;
262         }
263     }
264
265     p_enc->fmt_out.i_extra = p_context->extradata_size;
266     p_enc->fmt_out.p_extra = p_context->extradata;
267     p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
268
269     if( p_enc->fmt_in.i_cat == AUDIO_ES )
270     {
271         p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
272         p_sys->p_buffer = malloc( p_sys->i_frame_size );
273     }
274
275     p_sys->i_last_ref_pts = 0;
276     p_sys->i_buggy_pts_detect = 0;
277     p_sys->i_samples_delay = 0;
278     p_sys->i_pts = 0;
279
280     msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
281
282     return VLC_SUCCESS;
283 }
284
285 /****************************************************************************
286  * EncodeVideo: the whole thing
287  ****************************************************************************/
288 static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
289 {
290     encoder_sys_t *p_sys = p_enc->p_sys;
291     AVFrame frame;
292     int i_out, i_plane;
293
294     for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
295     {
296         frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
297         frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
298     }
299
300     /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
301     if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
302         frame.pts = p_pict->date;
303     else
304         frame.pts = 0;
305
306     /* Let ffmpeg select the frame type */
307     frame.pict_type = 0;
308
309     i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
310                                   AVCODEC_MAX_VIDEO_FRAME_SIZE, &frame );
311     if( i_out > 0 )
312     {
313         block_t *p_block = block_New( p_enc, i_out );
314         memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
315
316         if( p_sys->p_context->coded_frame->pts != 0 &&
317             p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
318         {
319             p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
320
321             /* FIXME, 3-2 pulldown is not handled correctly */
322             p_block->i_length = I64C(1000000) *
323                 p_enc->fmt_in.video.i_frame_rate_base /
324                 p_enc->fmt_in.video.i_frame_rate;
325             p_block->i_pts    = p_sys->p_context->coded_frame->pts;
326
327             if( !p_sys->p_context->delay ||
328                 ( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
329                   p_sys->p_context->coded_frame->pict_type != FF_P_TYPE ) )
330             {
331                 p_block->i_dts = p_block->i_pts;
332             }
333             else
334             {
335                 if( p_sys->i_last_ref_pts )
336                 {
337                     p_block->i_dts = p_sys->i_last_ref_pts;
338                 }
339                 else
340                 {
341                     /* Let's put something sensible */
342                     p_block->i_dts = p_block->i_pts;
343                 }
344
345                 p_sys->i_last_ref_pts = p_block->i_pts;
346             }
347         }
348         else
349         {
350             /* Buggy libavcodec which doesn't update coded_frame->pts
351              * correctly */
352             p_block->i_length = I64C(1000000) *
353                 p_enc->fmt_in.video.i_frame_rate_base /
354                 p_enc->fmt_in.video.i_frame_rate;
355             p_block->i_dts = p_block->i_pts = p_pict->date;
356         }
357
358         return p_block;
359     }
360
361     return NULL;
362 }
363
364 /****************************************************************************
365  * EncodeAudio: the whole thing
366  ****************************************************************************/
367 static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
368 {
369     encoder_sys_t *p_sys = p_enc->p_sys;
370     block_t *p_block, *p_chain = NULL;
371
372     char *p_buffer = p_aout_buf->p_buffer;
373     int i_samples = p_aout_buf->i_nb_samples;
374     int i_samples_delay = p_sys->i_samples_delay;
375
376     p_sys->i_pts = p_aout_buf->start_date -
377                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
378                 (mtime_t)p_enc->fmt_in.audio.i_rate;
379
380     p_sys->i_samples_delay += i_samples;
381
382     while( p_sys->i_samples_delay >= p_sys->p_context->frame_size )
383     {
384         int16_t *p_samples;
385         int i_out;
386
387         if( i_samples_delay )
388         {
389             /* Take care of the left-over from last time */
390             int i_delay_size = i_samples_delay * 2 *
391                                  p_sys->p_context->channels;
392             int i_size = p_sys->i_frame_size - i_delay_size;
393
394             p_samples = (int16_t *)p_sys->p_buffer;
395             memcpy( p_sys->p_buffer + i_delay_size, p_buffer, i_size );
396             p_buffer -= i_delay_size;
397             i_samples += i_samples_delay;
398             i_samples_delay = 0;
399         }
400         else
401         {
402             p_samples = (int16_t *)p_buffer;
403         }
404
405         i_out = avcodec_encode_audio( p_sys->p_context, p_sys->p_buffer_out,
406                                       2 * AVCODEC_MAX_AUDIO_FRAME_SIZE,
407                                       p_samples );
408
409 #if 0
410         msg_Warn( p_enc, "avcodec_encode_audio: %d", i_out );
411 #endif
412         if( i_out < 0 ) break;
413
414         p_buffer += p_sys->i_frame_size;
415         p_sys->i_samples_delay -= p_sys->p_context->frame_size;
416         i_samples -= p_sys->p_context->frame_size;
417
418         if( i_out == 0 ) continue;
419
420         p_block = block_New( p_enc, i_out );
421         memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
422
423         p_block->i_length = (mtime_t)1000000 *
424             (mtime_t)p_sys->p_context->frame_size /
425             (mtime_t)p_sys->p_context->sample_rate;
426
427         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
428
429         /* Update pts */
430         p_sys->i_pts += p_block->i_length;
431         block_ChainAppend( &p_chain, p_block );
432     }
433
434     /* Backup the remaining raw samples */
435     if( i_samples )
436     {
437         memcpy( p_sys->p_buffer, p_buffer + i_samples_delay * 2 *
438                 p_sys->p_context->channels,
439                 i_samples * 2 * p_sys->p_context->channels );
440     }
441
442     return p_chain;
443 }
444
445 /*****************************************************************************
446  * CloseEncoder: ffmpeg encoder destruction
447  *****************************************************************************/
448 void E_(CloseEncoder)( vlc_object_t *p_this )
449 {
450     encoder_t *p_enc = (encoder_t *)p_this;
451     encoder_sys_t *p_sys = p_enc->p_sys;
452
453     avcodec_close( p_sys->p_context );
454     free( p_sys->p_context );
455
456     if( p_sys->p_buffer ) free( p_sys->p_buffer );
457     if( p_sys->p_buffer_out ) free( p_sys->p_buffer_out );
458
459     free( p_sys );
460 }