1 /* $Id: encavcodec.c,v 1.23 2005/10/13 23:47:06 titer Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.m0k.org/>.
5 It may be used under the terms of the GNU General Public License. */
9 #include "ffmpeg/avcodec.h"
11 struct hb_work_object_s
16 AVCodecContext * context;
20 /***********************************************************************
22 **********************************************************************/
23 static void Close( hb_work_object_t ** _w );
24 static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
25 hb_buffer_t ** buf_out );
27 /***********************************************************************
28 * hb_work_encavcodec_init
29 ***********************************************************************
31 **********************************************************************/
32 hb_work_object_t * hb_work_encavcodec_init( hb_job_t * job )
35 AVCodecContext * context;
37 hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
38 w->name = strdup( "MPEG-4 encoder (libavcodec)" );
44 codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
47 hb_log( "hb_work_encavcodec_init: avcodec_find_encoder "
50 context = avcodec_alloc_context();
51 if( job->vquality < 0.0 || job->vquality > 1.0 )
54 context->bit_rate = 1000 * job->vbitrate;
55 context->bit_rate_tolerance = 10 * context->bit_rate;
59 /* Constant quantizer */
60 context->qmin = 31 - job->vquality * 30;
61 context->qmax = context->qmin;
62 hb_log( "encavcodec: encoding at constant quantizer %d",
65 context->width = job->width;
66 context->height = job->height;
67 context->time_base = (AVRational) { job->vrate_base, job->vrate };
68 context->gop_size = 10 * job->vrate / job->vrate_base;
69 context->pix_fmt = PIX_FMT_YUV420P;
71 if( job->mux & HB_MUX_MP4 )
73 context->flags |= CODEC_FLAG_GLOBAL_HEADER;
77 context->flags |= CODEC_FLAG_GRAY;
82 char filename[1024]; memset( filename, 0, 1024 );
83 hb_get_tempory_filename( job->h, filename, "ffmpeg.log" );
87 w->file = fopen( filename, "wb" );
88 context->flags |= CODEC_FLAG_PASS1;
95 w->file = fopen( filename, "rb" );
96 fseek( w->file, 0, SEEK_END );
97 size = ftell( w->file );
98 fseek( w->file, 0, SEEK_SET );
99 log = malloc( size + 1 );
101 fread( log, size, 1, w->file );
105 context->flags |= CODEC_FLAG_PASS2;
106 context->stats_in = log;
110 if( avcodec_open( context, codec ) )
112 hb_log( "hb_work_encavcodec_init: avcodec_open failed" );
114 w->context = context;
116 if( ( job->mux & HB_MUX_MP4 ) && job->pass != 1 )
118 #define c job->config.mpeg4
120 c.config = malloc( 15 );
121 c.config_length = 15;
122 memcpy( c.config, context->extradata + 15, 15 );
129 /***********************************************************************
131 ***********************************************************************
133 **********************************************************************/
134 static void Close( hb_work_object_t ** _w )
136 hb_work_object_t * w = *_w;
137 hb_job_t * job = w->job;
141 hb_log( "encavcodec: closing libavcodec" );
142 avcodec_close( w->context );
150 free( job->es_config );
151 job->es_config = NULL;
152 job->es_config_length = 0;
160 /***********************************************************************
162 ***********************************************************************
164 **********************************************************************/
165 static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
166 hb_buffer_t ** buf_out )
168 hb_job_t * job = w->job;
170 hb_buffer_t * in = *buf_in, * buf;
172 frame = avcodec_alloc_frame();
173 frame->data[0] = in->data;
174 frame->data[1] = frame->data[0] + job->width * job->height;
175 frame->data[2] = frame->data[1] + job->width * job->height / 4;
176 frame->linesize[0] = job->width;
177 frame->linesize[1] = job->width / 2;
178 frame->linesize[2] = job->width / 2;
180 /* Should be way too large */
181 buf = hb_buffer_init( 3 * job->width * job->height / 2 );
182 buf->size = avcodec_encode_video( w->context, buf->data, buf->alloc,
184 buf->start = in->start;
185 buf->stop = in->stop;
186 buf->key = w->context->coded_frame->key_frame;
193 fprintf( w->file, "%s", w->context->stats_out );