Mercurial > mplayer.hg
annotate libmpcodecs/ve_lavc.c @ 6110:7bea806b9c5f
Improvment for spu subtitles.
Removed the integreted spudec in vobsub.
Various cleanup/bugfix in vobsub (no more auto palette when a true one is
here)
HW spu rendering moved in spudec because we first need to reassable the
packet before sending them to the hw.
Spudec is now created only if nedded.
author | albeu |
---|---|
date | Fri, 17 May 2002 23:47:27 +0000 |
parents | e8f6f477aad0 |
children | ea6b20e70ac5 |
rev | line source |
---|---|
5550 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 | |
5 #include "../config.h" | |
6 | |
7 #ifdef USE_LIBAVCODEC | |
8 | |
9 #include "../mp_msg.h" | |
10 #include "../help_mp.h" | |
11 | |
12 #include "codec-cfg.h" | |
13 #include "stream.h" | |
14 #include "demuxer.h" | |
15 #include "stheader.h" | |
16 | |
17 #include "aviwrite.h" | |
18 | |
5607 | 19 #include "img_format.h" |
20 #include "mp_image.h" | |
5550 | 21 #include "vf.h" |
22 | |
23 #include "divx4_vbr.h" | |
24 | |
25 extern int pass; | |
26 extern char* passtmpfile; | |
27 | |
28 //===========================================================================// | |
29 | |
30 #ifdef USE_LIBAVCODEC_SO | |
31 #include <libffmpeg/avcodec.h> | |
32 #else | |
33 #include "libavcodec/avcodec.h" | |
34 #endif | |
35 | |
5778 | 36 #if LIBAVCODEC_BUILD < 4601 |
37 #error your version of libavcodec is too old, get a newer one, and dont send a bugreport, THIS IS NO BUG | |
38 #endif | |
39 | |
5550 | 40 extern int avcodec_inited; |
41 | |
42 /* video options */ | |
43 static char *lavc_param_vcodec = NULL; | |
44 static int lavc_param_vbitrate = -1; | |
45 static int lavc_param_vrate_tolerance = 1024*8; | |
46 static int lavc_param_vhq = 0; /* default is realtime encoding */ | |
47 static int lavc_param_v4mv = 0; | |
5556 | 48 static int lavc_param_vme = 4; |
5550 | 49 static int lavc_param_vqscale = 0; |
50 static int lavc_param_vqmin = 3; | |
51 static int lavc_param_vqmax = 15; | |
52 static int lavc_param_vqdiff = 3; | |
53 static float lavc_param_vqcompress = 0.5; | |
54 static float lavc_param_vqblur = 0.5; | |
5778 | 55 static float lavc_param_vb_qfactor = 2.0; |
5657
ee2efbf3dc9d
Preliminary support for lavcs b-frame encoding, disabled by default.
atmos4
parents:
5646
diff
changeset
|
56 static int lavc_param_vmax_b_frames = 0; |
5550 | 57 static int lavc_param_keyint = -1; |
5778 | 58 static int lavc_param_vpass = 0; |
59 static int lavc_param_vrc_strategy = 2; | |
60 static int lavc_param_vb_strategy = 0; | |
5550 | 61 |
62 #include "cfgparser.h" | |
63 | |
64 #ifdef USE_LIBAVCODEC | |
65 struct config lavcopts_conf[]={ | |
66 {"vcodec", &lavc_param_vcodec, CONF_TYPE_STRING, 0, 0, 0, NULL}, | |
67 {"vbitrate", &lavc_param_vbitrate, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL}, | |
68 {"vratetol", &lavc_param_vrate_tolerance, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL}, | |
69 {"vhq", &lavc_param_vhq, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
70 {"v4mv", &lavc_param_v4mv, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
71 {"vme", &lavc_param_vme, CONF_TYPE_INT, CONF_RANGE, 0, 5, NULL}, | |
72 {"vqscale", &lavc_param_vqscale, CONF_TYPE_INT, CONF_RANGE, 1, 31, NULL}, | |
73 {"vqmin", &lavc_param_vqmin, CONF_TYPE_INT, CONF_RANGE, 1, 31, NULL}, | |
74 {"vqmax", &lavc_param_vqmax, CONF_TYPE_INT, CONF_RANGE, 1, 31, NULL}, | |
75 {"vqdiff", &lavc_param_vqdiff, CONF_TYPE_INT, CONF_RANGE, 1, 31, NULL}, | |
76 {"vqcomp", &lavc_param_vqcompress, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 1.0, NULL}, | |
77 {"vqblur", &lavc_param_vqblur, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 1.0, NULL}, | |
5778 | 78 {"vb_qfactor", &lavc_param_vb_qfactor, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 31.0, NULL}, |
5657
ee2efbf3dc9d
Preliminary support for lavcs b-frame encoding, disabled by default.
atmos4
parents:
5646
diff
changeset
|
79 {"vmax_b_frames", &lavc_param_vmax_b_frames, CONF_TYPE_INT, CONF_RANGE, 0, FF_MAX_B_FRAMES, NULL}, |
5778 | 80 {"vpass", &lavc_param_vpass, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL}, |
81 {"vrc_strategy", &lavc_param_vrc_strategy, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL}, | |
82 {"vb_strategy", &lavc_param_vb_strategy, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL}, | |
5550 | 83 {"keyint", &lavc_param_keyint, CONF_TYPE_INT, 0, 0, 0, NULL}, |
84 {NULL, NULL, 0, 0, 0, 0, NULL} | |
85 }; | |
86 #endif | |
87 | |
88 struct vf_priv_s { | |
89 aviwrite_stream_t* mux; | |
90 AVCodecContext context; | |
91 AVCodec *codec; | |
92 }; | |
93 | |
94 #define mux_v (vf->priv->mux) | |
95 #define lavc_venc_context (vf->priv->context) | |
96 | |
97 static int config(struct vf_instance_s* vf, | |
98 int width, int height, int d_width, int d_height, | |
99 unsigned int flags, unsigned int outfmt){ | |
100 | |
101 mux_v->bih->biWidth=width; | |
102 mux_v->bih->biHeight=height; | |
103 mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8); | |
104 | |
105 memset(&lavc_venc_context, 0, sizeof(lavc_venc_context)); | |
106 | |
107 printf("videocodec: libavcodec (%dx%d fourcc=%x [%.4s])\n", | |
108 mux_v->bih->biWidth, mux_v->bih->biHeight, mux_v->bih->biCompression, | |
109 (char *)&mux_v->bih->biCompression); | |
110 | |
111 lavc_venc_context.width = width; | |
112 lavc_venc_context.height = height; | |
5677
a21cab74cde8
bitrate>16000 means bits not kbits - noticed by George Hawkins <george_hawkins@yahoo.com>
arpi
parents:
5657
diff
changeset
|
113 if (lavc_param_vbitrate > 16000) /* != -1 */ |
a21cab74cde8
bitrate>16000 means bits not kbits - noticed by George Hawkins <george_hawkins@yahoo.com>
arpi
parents:
5657
diff
changeset
|
114 lavc_venc_context.bit_rate = lavc_param_vbitrate; |
a21cab74cde8
bitrate>16000 means bits not kbits - noticed by George Hawkins <george_hawkins@yahoo.com>
arpi
parents:
5657
diff
changeset
|
115 else if (lavc_param_vbitrate >= 0) /* != -1 */ |
5550 | 116 lavc_venc_context.bit_rate = lavc_param_vbitrate*1000; |
117 else | |
118 lavc_venc_context.bit_rate = 800000; /* default */ | |
119 lavc_venc_context.bit_rate_tolerance= lavc_param_vrate_tolerance*1000; | |
120 lavc_venc_context.frame_rate = (float)mux_v->h.dwRate/mux_v->h.dwScale * FRAME_RATE_BASE; | |
121 lavc_venc_context.qmin= lavc_param_vqmin; | |
122 lavc_venc_context.qmax= lavc_param_vqmax; | |
123 lavc_venc_context.max_qdiff= lavc_param_vqdiff; | |
124 lavc_venc_context.qcompress= lavc_param_vqcompress; | |
125 lavc_venc_context.qblur= lavc_param_vqblur; | |
5657
ee2efbf3dc9d
Preliminary support for lavcs b-frame encoding, disabled by default.
atmos4
parents:
5646
diff
changeset
|
126 lavc_venc_context.max_b_frames= lavc_param_vmax_b_frames; |
5778 | 127 lavc_venc_context.b_quant_factor= lavc_param_vb_qfactor; |
128 lavc_venc_context.rc_strategy= lavc_param_vrc_strategy; | |
129 lavc_venc_context.b_frame_strategy= lavc_param_vb_strategy; | |
130 | |
5550 | 131 /* keyframe interval */ |
132 if (lavc_param_keyint >= 0) /* != -1 */ | |
133 lavc_venc_context.gop_size = lavc_param_keyint; | |
134 else | |
135 lavc_venc_context.gop_size = 250; /* default */ | |
136 | |
137 if (lavc_param_vhq) | |
138 { | |
139 printf("High quality encoding selected (non real time)!\n"); | |
140 lavc_venc_context.flags = CODEC_FLAG_HQ; | |
141 } | |
142 else | |
143 lavc_venc_context.flags = 0; | |
144 | |
5781
62e9e0c0bd6a
hq mode in first pass should work (as bad, ehh as well as LQ)
michael
parents:
5778
diff
changeset
|
145 /* 4mv is currently buggy with B frames */ |
62e9e0c0bd6a
hq mode in first pass should work (as bad, ehh as well as LQ)
michael
parents:
5778
diff
changeset
|
146 if (lavc_param_vmax_b_frames > 0 && lavc_param_v4mv) { |
62e9e0c0bd6a
hq mode in first pass should work (as bad, ehh as well as LQ)
michael
parents:
5778
diff
changeset
|
147 printf("4MV with B-Frames not yet supported -> 4MV disabled\n"); |
62e9e0c0bd6a
hq mode in first pass should work (as bad, ehh as well as LQ)
michael
parents:
5778
diff
changeset
|
148 lavc_param_v4mv = 0; |
62e9e0c0bd6a
hq mode in first pass should work (as bad, ehh as well as LQ)
michael
parents:
5778
diff
changeset
|
149 } |
62e9e0c0bd6a
hq mode in first pass should work (as bad, ehh as well as LQ)
michael
parents:
5778
diff
changeset
|
150 |
5550 | 151 lavc_venc_context.flags|= lavc_param_v4mv ? CODEC_FLAG_4MV : 0; |
152 | |
5778 | 153 /* lavc internal 2pass bitrate control */ |
154 if(lavc_param_vpass==1) | |
155 lavc_venc_context.flags|= CODEC_FLAG_PASS1; | |
156 else if(lavc_param_vpass==2) | |
157 lavc_venc_context.flags|= CODEC_FLAG_PASS2; | |
158 | |
5624 | 159 #ifdef ME_ZERO |
160 // workaround Juanjo's stupid incompatible change: | |
5550 | 161 motion_estimation_method = lavc_param_vme; |
5624 | 162 #else |
163 lavc_venc_context.me_method = ME_ZERO+lavc_param_vme; | |
164 #endif | |
5550 | 165 |
166 /* fixed qscale :p */ | |
167 if (lavc_param_vqscale) | |
168 { | |
169 printf("Using constant qscale = %d (VBR)\n", lavc_param_vqscale); | |
170 lavc_venc_context.flags |= CODEC_FLAG_QSCALE; | |
171 lavc_venc_context.quality = lavc_param_vqscale; | |
172 } | |
173 | |
174 switch(pass){ | |
175 case 1: | |
176 if (VbrControl_init_2pass_vbr_analysis(passtmpfile, 5) == -1){ | |
177 mp_msg(MSGT_MENCODER,MSGL_ERR,"2pass failed: filename=%s\n", passtmpfile); | |
178 pass=0; | |
5781
62e9e0c0bd6a
hq mode in first pass should work (as bad, ehh as well as LQ)
michael
parents:
5778
diff
changeset
|
179 } |
5550 | 180 break; |
181 case 2: | |
182 if (VbrControl_init_2pass_vbr_encoding(passtmpfile, | |
183 lavc_venc_context.bit_rate, | |
184 (float)mux_v->h.dwRate/mux_v->h.dwScale, | |
185 100, /* crispness */ | |
186 5) == -1){ | |
187 mp_msg(MSGT_MENCODER,MSGL_ERR,"2pass failed: filename=%s\n", passtmpfile); | |
188 pass=0; | |
5632 | 189 } else |
190 lavc_venc_context.flags|=CODEC_FLAG_QSCALE|CODEC_FLAG_TYPE; // VBR | |
5550 | 191 break; |
192 } | |
193 | |
194 if (avcodec_open(&lavc_venc_context, vf->priv->codec) != 0) { | |
195 mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_CantOpenCodec); | |
196 return 0; | |
197 } | |
198 | |
199 if (lavc_venc_context.codec->encode == NULL) { | |
200 mp_msg(MSGT_MENCODER,MSGL_ERR,"avcodec init failed (ctx->codec->encode == NULL)!\n"); | |
201 return 0; | |
202 } | |
203 | |
204 return 1; | |
205 } | |
206 | |
207 static int control(struct vf_instance_s* vf, int request, void* data){ | |
208 | |
209 return CONTROL_UNKNOWN; | |
210 } | |
211 | |
212 static int query_format(struct vf_instance_s* vf, unsigned int fmt){ | |
213 switch(fmt){ | |
214 case IMGFMT_YV12: | |
215 case IMGFMT_IYUV: | |
216 case IMGFMT_I420: | |
5565
0b301fec999a
capabilities support -> automatic insertion of scale, expand, pp
arpi
parents:
5556
diff
changeset
|
217 return VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE; |
5550 | 218 } |
219 return 0; | |
220 } | |
221 | |
222 static void put_image(struct vf_instance_s* vf, mp_image_t *mpi){ | |
223 int out_size; | |
224 AVPicture lavc_venc_picture; | |
225 | |
226 lavc_venc_picture.data[0]=mpi->planes[0]; | |
227 lavc_venc_picture.data[1]=mpi->planes[1]; | |
228 lavc_venc_picture.data[2]=mpi->planes[2]; | |
229 lavc_venc_picture.linesize[0]=mpi->stride[0]; | |
230 lavc_venc_picture.linesize[1]=mpi->stride[1]; | |
231 lavc_venc_picture.linesize[2]=mpi->stride[2]; | |
232 | |
233 if(pass==2){ // handle 2-pass: | |
234 lavc_venc_context.flags|=CODEC_FLAG_QSCALE; // enable VBR | |
235 lavc_venc_context.quality=VbrControl_get_quant(); | |
236 lavc_venc_context.key_frame=VbrControl_get_intra(); | |
237 lavc_venc_context.gop_size=0x3fffffff; | |
238 out_size = avcodec_encode_video(&lavc_venc_context, mux_v->buffer, mux_v->buffer_size, | |
239 &lavc_venc_picture); | |
240 VbrControl_update_2pass_vbr_encoding(lavc_venc_context.mv_bits, | |
241 lavc_venc_context.i_tex_bits+lavc_venc_context.p_tex_bits, | |
242 8*out_size); | |
243 } else { | |
244 out_size = avcodec_encode_video(&lavc_venc_context, mux_v->buffer, mux_v->buffer_size, | |
245 &lavc_venc_picture); | |
246 | |
247 if(pass==1){ | |
248 VbrControl_update_2pass_vbr_analysis(lavc_venc_context.key_frame, | |
249 lavc_venc_context.mv_bits, | |
250 lavc_venc_context.i_tex_bits+lavc_venc_context.p_tex_bits, | |
251 8*out_size, lavc_venc_context.quality); | |
252 } | |
253 | |
254 } | |
255 | |
256 mencoder_write_chunk(mux_v,out_size,lavc_venc_context.key_frame?0x10:0); | |
257 } | |
258 | |
5551 | 259 static void uninit(struct vf_instance_s* vf){ |
260 avcodec_close(&lavc_venc_context); | |
261 } | |
262 | |
5550 | 263 //===========================================================================// |
264 | |
265 static int vf_open(vf_instance_t *vf, char* args){ | |
5551 | 266 vf->uninit=uninit; |
5550 | 267 vf->config=config; |
268 vf->control=control; | |
269 vf->query_format=query_format; | |
270 vf->put_image=put_image; | |
271 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
272 memset(vf->priv,0,sizeof(struct vf_priv_s)); | |
273 vf->priv->mux=args; | |
274 | |
5977
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
275 /* XXX: hack: some of the MJPEG decoder DLL's needs exported huffman |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
276 table, so we define a zero-table, also lavc mjpeg encoder is putting |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
277 huffman tables into the stream, so no problem */ |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
278 if (lavc_param_vcodec && !strcasecmp(lavc_param_vcodec, "mjpeg")) |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
279 { |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
280 mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)+28); |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
281 memset(mux_v->bih, 0, sizeof(BITMAPINFOHEADER)+28); |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
282 mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+28; |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
283 } |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
284 else |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
285 { |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
286 mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)); |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
287 memset(mux_v->bih, 0, sizeof(BITMAPINFOHEADER)); |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
288 mux_v->bih->biSize=sizeof(BITMAPINFOHEADER); |
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
289 } |
5550 | 290 mux_v->bih->biWidth=0; |
291 mux_v->bih->biHeight=0; | |
292 mux_v->bih->biPlanes=1; | |
293 mux_v->bih->biBitCount=24; | |
294 if (!lavc_param_vcodec) | |
295 { | |
5977
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
296 printf("No libavcodec codec specified! It's required!\n"); |
5550 | 297 return 0; |
298 } | |
299 | |
300 if (!strcasecmp(lavc_param_vcodec, "mpeg1") || !strcasecmp(lavc_param_vcodec, "mpeg1video")) | |
301 mux_v->bih->biCompression = mmioFOURCC('m', 'p', 'g', '1'); | |
302 else if (!strcasecmp(lavc_param_vcodec, "h263") || !strcasecmp(lavc_param_vcodec, "h263p")) | |
303 mux_v->bih->biCompression = mmioFOURCC('h', '2', '6', '3'); | |
304 else if (!strcasecmp(lavc_param_vcodec, "rv10")) | |
305 mux_v->bih->biCompression = mmioFOURCC('R', 'V', '1', '0'); | |
306 else if (!strcasecmp(lavc_param_vcodec, "mjpeg")) | |
307 mux_v->bih->biCompression = mmioFOURCC('M', 'J', 'P', 'G'); | |
308 else if (!strcasecmp(lavc_param_vcodec, "mpeg4")) | |
309 mux_v->bih->biCompression = mmioFOURCC('D', 'I', 'V', 'X'); | |
310 else if (!strcasecmp(lavc_param_vcodec, "msmpeg4")) | |
311 mux_v->bih->biCompression = mmioFOURCC('d', 'i', 'v', '3'); | |
5972 | 312 else if (!strcasecmp(lavc_param_vcodec, "msmpeg4v2")) |
313 mux_v->bih->biCompression = mmioFOURCC('M', 'P', '4', '2'); | |
5550 | 314 else |
315 mux_v->bih->biCompression = mmioFOURCC(lavc_param_vcodec[0], | |
316 lavc_param_vcodec[1], lavc_param_vcodec[2], lavc_param_vcodec[3]); /* FIXME!!! */ | |
317 | |
318 if (!avcodec_inited){ | |
319 avcodec_init(); | |
320 avcodec_register_all(); | |
321 avcodec_inited=1; | |
322 } | |
323 | |
324 vf->priv->codec = (AVCodec *)avcodec_find_encoder_by_name(lavc_param_vcodec); | |
325 if (!vf->priv->codec) { | |
326 mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_MissingLAVCcodec, lavc_param_vcodec); | |
327 return 0; | |
328 } | |
329 | |
330 return 1; | |
331 } | |
332 | |
333 vf_info_t ve_info_lavc = { | |
334 "libavcodec encoder", | |
335 "lavc", | |
5977
e8f6f477aad0
a hack to make ffmjpeg created files viewable with windows dlls too
alex
parents:
5972
diff
changeset
|
336 "A'rpi and Alex", |
5550 | 337 "for internal use by mencoder", |
338 vf_open | |
339 }; | |
340 | |
341 //===========================================================================// | |
342 #endif |