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