Merge svn changes up to r28310
[mplayer/glamo.git] / libmpcodecs / vd_ffmpeg.c
blob0e8fd81f9732f906886356e8e7e1cad0cca32156
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <time.h>
6 #include "config.h"
7 #include "mp_msg.h"
8 #include "help_mp.h"
9 #include "options.h"
10 #include "av_opts.h"
12 #include "libavutil/common.h"
13 #include "libavutil/intreadwrite.h"
14 #include "mpbswap.h"
16 #include "vd_internal.h"
18 static const vd_info_t info = {
19 "FFmpeg's libavcodec codec family",
20 "ffmpeg",
21 "A'rpi",
22 "A'rpi, Michael, Alex",
23 "native codecs"
26 LIBVD_EXTERN(ffmpeg)
28 #include "libavcodec/avcodec.h"
30 #ifdef CONFIG_XVMC
31 #include "xvmc_render.h"
32 #endif
34 int avcodec_initialized=0;
36 typedef struct {
37 AVCodecContext *avctx;
38 AVFrame *pic;
39 enum PixelFormat pix_fmt;
40 int do_slices;
41 int do_dr1;
42 int vo_initialized;
43 int best_csp;
44 int b_age;
45 int ip_age[2];
46 int qp_stat[32];
47 double qp_sum;
48 double inv_qp_sum;
49 int ip_count;
50 int b_count;
51 AVRational last_sample_aspect_ratio;
52 int lowres;
53 } vd_ffmpeg_ctx;
55 //#ifdef CONFIG_LIBPOSTPROC
56 //unsigned int lavc_pp=0;
57 //#endif
59 #include "m_option.h"
61 static int get_buffer(AVCodecContext *avctx, AVFrame *pic);
62 static void release_buffer(AVCodecContext *avctx, AVFrame *pic);
64 #ifdef CONFIG_XVMC
65 static enum PixelFormat get_format(struct AVCodecContext * avctx,
66 const enum PixelFormat * pix_fmt);
67 static int mc_get_buffer(AVCodecContext *avctx, AVFrame *pic);
68 static void mc_release_buffer(AVCodecContext *avctx, AVFrame *pic);
69 static void mc_render_slice(struct AVCodecContext *s,
70 const AVFrame *src, int offset[4],
71 int y, int type, int height);
72 #endif
74 const m_option_t lavc_decode_opts_conf[]={
75 OPT_INTRANGE("bug", lavc_param.workaround_bugs, 0, -1, 999999),
76 OPT_INTRANGE("er", lavc_param.error_resilience, 0, 0, 99),
77 OPT_FLAG_ON("gray", lavc_param.gray, 0),
78 OPT_INTRANGE("idct", lavc_param.idct_algo, 0, 0, 99),
79 OPT_INTRANGE("ec", lavc_param.error_concealment, 0, 0, 99),
80 OPT_FLAG_ON("vstats", lavc_param.vstats, 0),
81 OPT_INTRANGE("debug", lavc_param.debug, 0, 0, 9999999),
82 OPT_INTRANGE("vismv", lavc_param.vismv, 0, 0, 9999999),
83 OPT_INTRANGE("st", lavc_param.skip_top, 0, 0, 999),
84 OPT_INTRANGE("sb", lavc_param.skip_bottom, 0, 0, 999),
85 #ifdef CODEC_FLAG2_FAST
86 OPT_FLAG_CONSTANTS("fast", lavc_param.fast, 0, 0, CODEC_FLAG2_FAST),
87 #endif
88 OPT_STRING("lowres", lavc_param.lowres_str, 0),
89 OPT_STRING("skiploopfilter", lavc_param.skip_loop_filter_str, 0),
90 OPT_STRING("skipidct", lavc_param.skip_idct_str, 0),
91 OPT_STRING("skipframe", lavc_param.skip_frame_str, 0),
92 OPT_INTRANGE("threads", lavc_param.threads, 0, 1, 8),
93 OPT_FLAG_CONSTANTS("bitexact", lavc_param.bitexact, 0, 0, CODEC_FLAG_BITEXACT),
94 OPT_STRING("o", lavc_param.avopt, 0),
95 {NULL, NULL, 0, 0, 0, 0, NULL}
98 static enum AVDiscard str2AVDiscard(char *str) {
99 if (!str) return AVDISCARD_DEFAULT;
100 if (strcasecmp(str, "none" ) == 0) return AVDISCARD_NONE;
101 if (strcasecmp(str, "default") == 0) return AVDISCARD_DEFAULT;
102 if (strcasecmp(str, "nonref" ) == 0) return AVDISCARD_NONREF;
103 if (strcasecmp(str, "bidir" ) == 0) return AVDISCARD_BIDIR;
104 if (strcasecmp(str, "nonkey" ) == 0) return AVDISCARD_NONKEY;
105 if (strcasecmp(str, "all" ) == 0) return AVDISCARD_ALL;
106 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Unknown discard value %s\n", str);
107 return AVDISCARD_DEFAULT;
110 // to set/get/query special features/parameters
111 static int control(sh_video_t *sh,int cmd,void* arg,...){
112 vd_ffmpeg_ctx *ctx = sh->context;
113 AVCodecContext *avctx = ctx->avctx;
114 switch(cmd){
115 case VDCTRL_QUERY_FORMAT:
117 int format =(*((int*)arg));
118 if( format == ctx->best_csp ) return CONTROL_TRUE;//supported
119 // possible conversions:
120 switch( format ){
121 case IMGFMT_YV12:
122 case IMGFMT_IYUV:
123 case IMGFMT_I420:
124 // "converted" using pointer/stride modification
125 if(avctx->pix_fmt==PIX_FMT_YUV420P) return CONTROL_TRUE;// u/v swap
126 if(avctx->pix_fmt==PIX_FMT_YUV422P && !ctx->do_dr1) return CONTROL_TRUE;// half stride
127 break;
128 #ifdef CONFIG_XVMC
129 case IMGFMT_XVMC_IDCT_MPEG2:
130 case IMGFMT_XVMC_MOCO_MPEG2:
131 if(avctx->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) return CONTROL_TRUE;
132 #endif
134 return CONTROL_FALSE;
136 break;
137 case VDCTRL_RESYNC_STREAM:
138 avcodec_flush_buffers(avctx);
139 return CONTROL_TRUE;
140 case VDCTRL_QUERY_UNSEEN_FRAMES:
141 return avctx->has_b_frames + 10;
143 return CONTROL_UNKNOWN;
146 static void mp_msp_av_log_callback(void* ptr, int level, const char* fmt, va_list vl)
148 static int print_prefix=1;
149 AVClass* avc= ptr ? *(AVClass**)ptr : NULL;
150 int type= MSGT_FIXME;
151 int mp_level;
152 char buf[256];
154 switch(level){
155 case AV_LOG_DEBUG: mp_level= MSGL_V ; break;
156 case AV_LOG_INFO : mp_level= MSGL_INFO; break;
157 case AV_LOG_ERROR: mp_level= MSGL_ERR ; break;
158 default : mp_level= MSGL_ERR ; break;
161 if (!mp_msg_test(type, mp_level)) return;
163 if(ptr){
164 if(!strcmp(avc->class_name, "AVCodecContext")){
165 AVCodecContext * s= ptr;
166 if(s->codec){
167 if(s->codec->type == CODEC_TYPE_AUDIO){
168 if(s->codec->decode)
169 type= MSGT_DECAUDIO;
170 }else if(s->codec->type == CODEC_TYPE_VIDEO){
171 if(s->codec->decode)
172 type= MSGT_DECVIDEO;
174 //FIXME subtitles, encoders (what msgt for them? there is no appropriate ...)
176 }else if(!strcmp(avc->class_name, "AVFormatContext")){
177 #if 0 //needs libavformat include FIXME iam too lazy to do this cleanly,probably the whole should be moved out of this file ...
178 AVFormatContext * s= ptr;
179 if(s->iformat)
180 type= MSGT_DEMUXER;
181 else if(s->oformat)
182 type= MSGT_MUXER;
183 #endif
187 if(print_prefix && avc) {
188 mp_msg(type, mp_level, "[%s @ %p]", avc->item_name(ptr), avc);
191 print_prefix= strchr(fmt, '\n') != NULL;
192 vsnprintf(buf, sizeof(buf), fmt, vl);
193 mp_msg(type, mp_level, buf);
196 // init driver
197 static int init(sh_video_t *sh){
198 struct lavc_param *lavc_param = &sh->opts->lavc_param;
199 AVCodecContext *avctx;
200 vd_ffmpeg_ctx *ctx;
201 AVCodec *lavc_codec;
202 int lowres_w=0;
203 int do_vis_debug= lavc_param->vismv || (lavc_param->debug&(FF_DEBUG_VIS_MB_TYPE|FF_DEBUG_VIS_QP));
205 if(!avcodec_initialized){
206 avcodec_init();
207 avcodec_register_all();
208 avcodec_initialized=1;
209 av_log_set_callback(mp_msp_av_log_callback);
212 ctx = sh->context = malloc(sizeof(vd_ffmpeg_ctx));
213 if (!ctx)
214 return 0;
215 memset(ctx, 0, sizeof(vd_ffmpeg_ctx));
217 lavc_codec = (AVCodec *)avcodec_find_decoder_by_name(sh->codec->dll);
218 if(!lavc_codec){
219 mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_MissingLAVCcodec,sh->codec->dll);
220 uninit(sh);
221 return 0;
224 if(sh->opts->vd_use_slices && (lavc_codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND) && !do_vis_debug)
225 ctx->do_slices=1;
227 if(lavc_codec->capabilities&CODEC_CAP_DR1 && !do_vis_debug && lavc_codec->id != CODEC_ID_H264 && lavc_codec->id != CODEC_ID_INTERPLAY_VIDEO && lavc_codec->id != CODEC_ID_ROQ)
228 ctx->do_dr1=1;
229 ctx->b_age= ctx->ip_age[0]= ctx->ip_age[1]= 256*256*256*64;
230 ctx->ip_count= ctx->b_count= 0;
232 ctx->pic = avcodec_alloc_frame();
233 ctx->avctx = avcodec_alloc_context();
234 avctx = ctx->avctx;
236 #ifdef CONFIG_XVMC
238 #ifdef CODEC_CAP_HWACCEL
239 if(lavc_codec->capabilities & CODEC_CAP_HWACCEL){
240 #else
241 if(lavc_codec->id == CODEC_ID_MPEG2VIDEO_XVMC){
242 #endif /* CODEC_CAP_HWACCEL */
243 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCAcceleratedCodec);
244 assert(ctx->do_dr1);//these are must to!
245 assert(ctx->do_slices); //it is (vo_)ffmpeg bug if this fails
246 avctx->flags|= CODEC_FLAG_EMU_EDGE;//do i need that??!!
247 avctx->get_format= get_format;//for now only this decoder will use it
248 avctx->get_buffer= mc_get_buffer;
249 avctx->release_buffer= mc_release_buffer;
250 avctx->draw_horiz_band = mc_render_slice;
251 avctx->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
252 }else
253 #endif /* CONFIG_XVMC */
254 if(ctx->do_dr1){
255 avctx->flags|= CODEC_FLAG_EMU_EDGE;
256 avctx->get_buffer= get_buffer;
257 avctx->release_buffer= release_buffer;
258 avctx->reget_buffer= get_buffer;
261 #ifdef CODEC_FLAG_NOT_TRUNCATED
262 avctx->flags|= CODEC_FLAG_NOT_TRUNCATED;
263 #endif
264 avctx->flags|= lavc_param->bitexact;
266 avctx->width = sh->disp_w;
267 avctx->height= sh->disp_h;
268 avctx->workaround_bugs= lavc_param->workaround_bugs;
269 avctx->error_recognition= lavc_param->error_resilience;
270 if(lavc_param->gray) avctx->flags|= CODEC_FLAG_GRAY;
271 #ifdef CODEC_FLAG2_FAST
272 avctx->flags2|= lavc_param->fast;
273 #endif
274 avctx->codec_tag= sh->format;
275 avctx->stream_codec_tag= sh->video.fccHandler;
276 avctx->idct_algo= lavc_param->idct_algo;
277 avctx->error_concealment= lavc_param->error_concealment;
278 avctx->debug= lavc_param->debug;
279 if (lavc_param->debug)
280 av_log_set_level(AV_LOG_DEBUG);
281 avctx->debug_mv= lavc_param->vismv;
282 avctx->skip_top = lavc_param->skip_top;
283 avctx->skip_bottom= lavc_param->skip_bottom;
284 if(lavc_param->lowres_str != NULL)
286 sscanf(lavc_param->lowres_str, "%d,%d", &ctx->lowres, &lowres_w);
287 if(ctx->lowres < 1 || ctx->lowres > 16 || (lowres_w > 0 && avctx->width < lowres_w))
288 ctx->lowres = 0;
289 avctx->lowres = ctx->lowres;
291 avctx->skip_loop_filter = str2AVDiscard(lavc_param->skip_loop_filter_str);
292 avctx->skip_idct = str2AVDiscard(lavc_param->skip_idct_str);
293 avctx->skip_frame = str2AVDiscard(lavc_param->skip_frame_str);
295 if(lavc_param->avopt){
296 if(parse_avopts(avctx, lavc_param->avopt) < 0){
297 mp_msg(MSGT_DECVIDEO,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_param->avopt);
298 uninit(sh);
299 return 0;
303 mp_dbg(MSGT_DECVIDEO,MSGL_DBG2,"libavcodec.size: %d x %d\n",avctx->width,avctx->height);
304 switch (sh->format) {
305 case mmioFOURCC('S','V','Q','3'):
306 /* SVQ3 extradata can show up as sh->ImageDesc if demux_mov is used, or
307 in the phony AVI header if demux_lavf is used. The first case is
308 handled here; the second case falls through to the next section. */
309 if (sh->ImageDesc) {
310 avctx->extradata_size = (*(int*)sh->ImageDesc) - sizeof(int);
311 avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
312 memcpy(avctx->extradata, ((int*)sh->ImageDesc)+1, avctx->extradata_size);
313 break;
315 /* fallthrough */
317 case mmioFOURCC('A','V','R','n'):
318 case mmioFOURCC('M','J','P','G'):
319 /* AVRn stores huffman table in AVI header */
320 /* Pegasus MJPEG stores it also in AVI header, but it uses the common
321 MJPG fourcc :( */
322 if (!sh->bih || sh->bih->biSize <= sizeof(BITMAPINFOHEADER))
323 break;
324 avctx->flags |= CODEC_FLAG_EXTERN_HUFF;
325 avctx->extradata_size = sh->bih->biSize-sizeof(BITMAPINFOHEADER);
326 avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
327 memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size);
329 #if 0
331 int x;
332 uint8_t *p = avctx->extradata;
334 for (x=0; x<avctx->extradata_size; x++)
335 mp_msg(MSGT_DECVIDEO, MSGL_INFO,"[%x] ", p[x]);
336 mp_msg(MSGT_DECVIDEO, MSGL_INFO,"\n");
338 #endif
339 break;
341 case mmioFOURCC('R', 'V', '1', '0'):
342 case mmioFOURCC('R', 'V', '1', '3'):
343 case mmioFOURCC('R', 'V', '2', '0'):
344 case mmioFOURCC('R', 'V', '3', '0'):
345 case mmioFOURCC('R', 'V', '4', '0'):
346 if(sh->bih->biSize<sizeof(*sh->bih)+8){
347 /* only 1 packet per frame & sub_id from fourcc */
348 avctx->extradata_size= 8;
349 avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
350 ((uint32_t*)avctx->extradata)[0] = 0;
351 ((uint32_t*)avctx->extradata)[1] =
352 (sh->format == mmioFOURCC('R', 'V', '1', '3')) ? 0x10003001 : 0x10000000;
353 } else {
354 /* has extra slice header (demux_rm or rm->avi streamcopy) */
355 avctx->extradata_size = sh->bih->biSize-sizeof(BITMAPINFOHEADER);
356 avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
357 memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size);
359 avctx->sub_id= AV_RB32(avctx->extradata+4);
361 // printf("%X %X %d %d\n", extrahdr[0], extrahdr[1]);
362 break;
364 default:
365 if (!sh->bih || sh->bih->biSize <= sizeof(BITMAPINFOHEADER))
366 break;
367 avctx->extradata_size = sh->bih->biSize-sizeof(BITMAPINFOHEADER);
368 avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
369 memcpy(avctx->extradata, sh->bih+1, avctx->extradata_size);
370 break;
372 /* Pass palette to codec */
373 if (sh->bih && (sh->bih->biBitCount <= 8)) {
374 avctx->palctrl = calloc(1,sizeof(AVPaletteControl));
375 avctx->palctrl->palette_changed = 1;
376 if (sh->bih->biSize-sizeof(BITMAPINFOHEADER))
377 /* Palette size in biSize */
378 memcpy(avctx->palctrl->palette, sh->bih+1,
379 FFMIN(sh->bih->biSize-sizeof(BITMAPINFOHEADER), AVPALETTE_SIZE));
380 else
381 /* Palette size in biClrUsed */
382 memcpy(avctx->palctrl->palette, sh->bih+1,
383 FFMIN(sh->bih->biClrUsed * 4, AVPALETTE_SIZE));
386 if(sh->bih)
387 avctx->bits_per_coded_sample= sh->bih->biBitCount;
389 if(lavc_param->threads > 1)
390 avcodec_thread_init(avctx, lavc_param->threads);
391 /* open it */
392 if (avcodec_open(avctx, lavc_codec) < 0) {
393 mp_msg(MSGT_DECVIDEO,MSGL_ERR, MSGTR_CantOpenCodec);
394 uninit(sh);
395 return 0;
397 mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: libavcodec init OK!\n");
398 return 1; //mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_YV12);
401 // uninit driver
402 static void uninit(sh_video_t *sh){
403 vd_ffmpeg_ctx *ctx = sh->context;
404 AVCodecContext *avctx = ctx->avctx;
406 if(sh->opts->lavc_param.vstats){
407 int i;
408 for(i=1; i<32; i++){
409 mp_msg(MSGT_DECVIDEO, MSGL_INFO,"QP: %d, count: %d\n", i, ctx->qp_stat[i]);
411 mp_msg(MSGT_DECVIDEO, MSGL_INFO,MSGTR_MPCODECS_ArithmeticMeanOfQP,
412 ctx->qp_sum / avctx->coded_frame->coded_picture_number,
413 1.0/(ctx->inv_qp_sum / avctx->coded_frame->coded_picture_number)
417 if (avctx) {
418 if (avctx->codec && avcodec_close(avctx) < 0)
419 mp_msg(MSGT_DECVIDEO,MSGL_ERR, MSGTR_CantCloseCodec);
421 av_freep(&avctx->extradata);
422 av_freep(&avctx->palctrl);
423 av_freep(&avctx->slice_offset);
426 av_freep(&avctx);
427 av_freep(&ctx->pic);
428 if (ctx)
429 free(ctx);
432 static void draw_slice(struct AVCodecContext *s,
433 const AVFrame *src, int offset[4],
434 int y, int type, int height){
435 sh_video_t * sh = s->opaque;
436 uint8_t *source[3]= {src->data[0] + offset[0], src->data[1] + offset[1], src->data[2] + offset[2]};
437 #if 0
438 int start=0, i;
439 int width= s->width;
440 vd_ffmpeg_ctx *ctx = sh->context;
441 int skip_stride= ((width << ctx->lowres)+15)>>4;
442 uint8_t *skip= &s->coded_frame->mbskip_table[(y>>4)*skip_stride];
443 int threshold= s->coded_frame->age;
444 if(s->pict_type!=B_TYPE){
445 for(i=0; i*16<width+16; i++){
446 if(i*16>=width || skip[i]>=threshold){
447 if(start==i) start++;
448 else{
449 uint8_t *src2[3]= {src[0] + start*16,
450 src[1] + start*8,
451 src[2] + start*8};
452 //printf("%2d-%2d x %d\n", start, i, y);
453 mpcodecs_draw_slice (sh,src2, stride, (i-start)*16, height, start*16, y);
454 start= i+1;
458 }else
459 #endif
460 if (y < sh->disp_h) {
461 mpcodecs_draw_slice (sh, source, src->linesize, sh->disp_w, (y+height)<=sh->disp_h?height:sh->disp_h-y, 0, y);
466 static int init_vo(sh_video_t *sh, enum PixelFormat pix_fmt){
467 vd_ffmpeg_ctx *ctx = sh->context;
468 AVCodecContext *avctx = ctx->avctx;
469 float aspect= av_q2d(avctx->sample_aspect_ratio) * avctx->width / avctx->height;
470 int width, height;
472 width = avctx->width;
473 height = avctx->height;
475 // HACK!
476 // if sh->ImageDesc is non-NULL, it means we decode QuickTime(tm) video.
477 // use dimensions from BIH to avoid black borders at the right and bottom.
478 if (sh->bih && sh->ImageDesc) {
479 width = sh->bih->biWidth >> ctx->lowres;
480 height = sh->bih->biHeight >> ctx->lowres;
483 // it is possible another vo buffers to be used after vo config()
484 // lavc reset its buffers on width/heigh change but not on aspect change!!!
485 if (av_cmp_q(avctx->sample_aspect_ratio, ctx->last_sample_aspect_ratio) ||
486 width != sh->disp_w ||
487 height != sh->disp_h ||
488 pix_fmt != ctx->pix_fmt ||
489 !ctx->vo_initialized)
491 mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] aspect_ratio: %f\n", aspect);
492 if (sh->aspect == 0 ||
493 av_cmp_q(avctx->sample_aspect_ratio,
494 ctx->last_sample_aspect_ratio))
495 sh->aspect = aspect;
496 ctx->last_sample_aspect_ratio = avctx->sample_aspect_ratio;
497 sh->disp_w = width;
498 sh->disp_h = height;
499 ctx->pix_fmt = pix_fmt;
500 switch(pix_fmt){
501 // YUVJ are YUV formats that use the full Y range and not just
502 // 16 - 235 (see colorspaces.txt).
503 // Currently they are all treated the same way.
504 case PIX_FMT_YUV410P: ctx->best_csp=IMGFMT_YVU9;break; //svq1
505 case PIX_FMT_YUVJ420P:
506 case PIX_FMT_YUV420P: ctx->best_csp=IMGFMT_YV12;break; //mpegs
507 case PIX_FMT_YUVJ422P:
508 case PIX_FMT_YUV422P: ctx->best_csp=IMGFMT_422P;break; //mjpeg / huffyuv
509 case PIX_FMT_YUVJ444P:
510 case PIX_FMT_YUV444P: ctx->best_csp=IMGFMT_444P;break; //photo jpeg
511 case PIX_FMT_YUV411P: ctx->best_csp=IMGFMT_411P;break; //dv ntsc
512 case PIX_FMT_YUYV422: ctx->best_csp=IMGFMT_YUY2;break; //huffyuv perhaps in the future
513 case PIX_FMT_RGB24 : ctx->best_csp=IMGFMT_RGB24;break; //qtrle
514 case PIX_FMT_RGB32: ctx->best_csp=IMGFMT_BGR32;break; //huffyuv / mjpeg
515 case PIX_FMT_BGR24 : ctx->best_csp=IMGFMT_BGR24;break; //8bps
516 case PIX_FMT_RGB555: ctx->best_csp=IMGFMT_BGR15;break; //rpza,cram
517 case PIX_FMT_RGB565: ctx->best_csp=IMGFMT_BGR16;break; //4xm
518 case PIX_FMT_GRAY8: ctx->best_csp=IMGFMT_Y800;break; // gray jpeg
519 case PIX_FMT_PAL8: ctx->best_csp=IMGFMT_BGR8;break; //8bps,mrle,cram
520 #ifdef CONFIG_XVMC
521 case PIX_FMT_XVMC_MPEG2_MC:ctx->best_csp=IMGFMT_XVMC_MOCO_MPEG2;break;
522 case PIX_FMT_XVMC_MPEG2_IDCT:ctx->best_csp=IMGFMT_XVMC_IDCT_MPEG2;break;
523 #endif
524 default:
525 ctx->best_csp=0;
527 if (!mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h, ctx->best_csp))
528 return -1;
529 ctx->vo_initialized = 1;
531 return 0;
534 static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
535 sh_video_t * sh = avctx->opaque;
536 vd_ffmpeg_ctx *ctx = sh->context;
537 mp_image_t* mpi=NULL;
538 int flags= MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE;
539 int type= MP_IMGTYPE_IPB;
540 int width= avctx->width;
541 int height= avctx->height;
542 int align=15;
543 //printf("get_buffer %d %d %d\n", pic->reference, ctx->ip_count, ctx->b_count);
544 if(avctx->pix_fmt == PIX_FMT_YUV410P)
545 align=63; //yes seriously, its really needed (16x16 chroma blocks in SVQ1 -> 64x64)
547 if (pic->buffer_hints) {
548 mp_msg(MSGT_DECVIDEO,MSGL_DBG2, "Buffer hints: %u\n", pic->buffer_hints);
549 type = MP_IMGTYPE_TEMP;
550 if (pic->buffer_hints & FF_BUFFER_HINTS_READABLE)
551 flags |= MP_IMGFLAG_READABLE;
552 if (pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) {
553 type = MP_IMGTYPE_STATIC;
554 flags |= MP_IMGFLAG_PRESERVE;
556 if (pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) {
557 type = MP_IMGTYPE_STATIC;
558 flags |= MP_IMGFLAG_PRESERVE;
560 flags|=(!avctx->hurry_up && ctx->do_slices) ?
561 MP_IMGFLAG_DRAW_CALLBACK:0;
562 mp_msg(MSGT_DECVIDEO,MSGL_DBG2, type == MP_IMGTYPE_STATIC ? "using STATIC\n" : "using TEMP\n");
563 } else {
564 if(!pic->reference){
565 ctx->b_count++;
566 flags|=(!avctx->hurry_up && ctx->do_slices) ?
567 MP_IMGFLAG_DRAW_CALLBACK:0;
568 }else{
569 ctx->ip_count++;
570 flags|= MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE
571 | (ctx->do_slices ? MP_IMGFLAG_DRAW_CALLBACK : 0);
575 if(init_vo(sh,avctx->pix_fmt) < 0){
576 avctx->release_buffer= avcodec_default_release_buffer;
577 avctx->get_buffer= avcodec_default_get_buffer;
578 return avctx->get_buffer(avctx, pic);
581 if (!pic->buffer_hints) {
582 if(ctx->b_count>1 || ctx->ip_count>2){
583 mp_msg(MSGT_DECVIDEO, MSGL_WARN, MSGTR_MPCODECS_DRIFailure);
585 ctx->do_dr1=0; //FIXME
586 avctx->get_buffer= avcodec_default_get_buffer;
587 return avctx->get_buffer(avctx, pic);
590 if(avctx->has_b_frames){
591 type= MP_IMGTYPE_IPB;
592 }else{
593 type= MP_IMGTYPE_IP;
595 mp_msg(MSGT_DECVIDEO,MSGL_DBG2, type== MP_IMGTYPE_IPB ? "using IPB\n" : "using IP\n");
598 mpi= mpcodecs_get_image(sh,type, flags,
599 (width+align)&(~align), (height+align)&(~align));
601 // ok, let's see what did we get:
602 if( mpi->flags&MP_IMGFLAG_DRAW_CALLBACK &&
603 !(mpi->flags&MP_IMGFLAG_DIRECT)){
604 // nice, filter/vo likes draw_callback :)
605 avctx->draw_horiz_band= draw_slice;
606 } else
607 avctx->draw_horiz_band= NULL;
609 // Palette support: libavcodec copies palette to *data[1]
610 if (mpi->bpp == 8)
611 mpi->planes[1] = av_malloc(AVPALETTE_SIZE);
613 pic->data[0]= mpi->planes[0];
614 pic->data[1]= mpi->planes[1];
615 pic->data[2]= mpi->planes[2];
617 #if 0
618 assert(mpi->width >= ((width +align)&(~align)));
619 assert(mpi->height >= ((height+align)&(~align)));
620 assert(mpi->stride[0] >= mpi->width);
621 if(mpi->imgfmt==IMGFMT_I420 || mpi->imgfmt==IMGFMT_YV12 || mpi->imgfmt==IMGFMT_IYUV){
622 const int y_size= mpi->stride[0] * (mpi->h-1) + mpi->w;
623 const int c_size= mpi->stride[1] * ((mpi->h>>1)-1) + (mpi->w>>1);
625 assert(mpi->planes[0] > mpi->planes[1] || mpi->planes[0] + y_size <= mpi->planes[1]);
626 assert(mpi->planes[0] > mpi->planes[2] || mpi->planes[0] + y_size <= mpi->planes[2]);
627 assert(mpi->planes[1] > mpi->planes[0] || mpi->planes[1] + c_size <= mpi->planes[0]);
628 assert(mpi->planes[1] > mpi->planes[2] || mpi->planes[1] + c_size <= mpi->planes[2]);
629 assert(mpi->planes[2] > mpi->planes[0] || mpi->planes[2] + c_size <= mpi->planes[0]);
630 assert(mpi->planes[2] > mpi->planes[1] || mpi->planes[2] + c_size <= mpi->planes[1]);
632 #endif
634 /* Note, some (many) codecs in libavcodec must have stride1==stride2 && no changes between frames
635 * lavc will check that and die with an error message, if its not true
637 pic->linesize[0]= mpi->stride[0];
638 pic->linesize[1]= mpi->stride[1];
639 pic->linesize[2]= mpi->stride[2];
641 pic->opaque = mpi;
642 //printf("%X\n", (int)mpi->planes[0]);
643 #if 0
644 if(mpi->flags&MP_IMGFLAG_DIRECT)
645 printf("D");
646 else if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
647 printf("S");
648 else
649 printf(".");
650 #endif
651 if(pic->reference){
652 pic->age= ctx->ip_age[0];
654 ctx->ip_age[0]= ctx->ip_age[1]+1;
655 ctx->ip_age[1]= 1;
656 ctx->b_age++;
657 }else{
658 pic->age= ctx->b_age;
660 ctx->ip_age[0]++;
661 ctx->ip_age[1]++;
662 ctx->b_age=1;
664 pic->type= FF_BUFFER_TYPE_USER;
665 return 0;
668 static void release_buffer(struct AVCodecContext *avctx, AVFrame *pic){
669 mp_image_t* mpi= pic->opaque;
670 sh_video_t * sh = avctx->opaque;
671 vd_ffmpeg_ctx *ctx = sh->context;
672 int i;
674 //printf("release buffer %d %d %d\n", mpi ? mpi->flags&MP_IMGFLAG_PRESERVE : -99, ctx->ip_count, ctx->b_count);
676 if(ctx->ip_count <= 2 && ctx->b_count<=1){
677 if(mpi->flags&MP_IMGFLAG_PRESERVE)
678 ctx->ip_count--;
679 else
680 ctx->b_count--;
683 // Palette support: free palette buffer allocated in get_buffer
684 if ( mpi && (mpi->bpp == 8))
685 av_freep(&mpi->planes[1]);
687 if(pic->type!=FF_BUFFER_TYPE_USER){
688 avcodec_default_release_buffer(avctx, pic);
689 return;
692 for(i=0; i<4; i++){
693 pic->data[i]= NULL;
695 //printf("R%X %X\n", pic->linesize[0], pic->data[0]);
698 // copypaste from demux_real.c - it should match to get it working!
699 //FIXME put into some header
700 typedef struct dp_hdr_s {
701 uint32_t chunks; // number of chunks
702 uint32_t timestamp; // timestamp from packet header
703 uint32_t len; // length of actual data
704 uint32_t chunktab; // offset to chunk offset array
705 } dp_hdr_t;
707 static void swap_palette(void *pal) {
708 int i;
709 uint32_t *p = pal;
710 for (i = 0; i < AVPALETTE_COUNT; i++)
711 p[i] = le2me_32(p[i]);
714 // decode a frame
715 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
716 int got_picture=0;
717 int ret;
718 vd_ffmpeg_ctx *ctx = sh->context;
719 AVFrame *pic= ctx->pic;
720 AVCodecContext *avctx = ctx->avctx;
721 struct lavc_param *lavc_param = &sh->opts->lavc_param;
722 mp_image_t* mpi=NULL;
723 int dr1= ctx->do_dr1;
725 if(len<=0) return NULL; // skipped frame
727 //ffmpeg interlace (mpeg2) bug have been fixed. no need of -noslices
728 if (!dr1)
729 avctx->draw_horiz_band=NULL;
730 avctx->opaque=sh;
731 if(ctx->vo_initialized && !(flags&3) && !dr1){
732 mpi=mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, MP_IMGFLAG_PRESERVE |
733 (ctx->do_slices?MP_IMGFLAG_DRAW_CALLBACK:0),
734 sh->disp_w, sh->disp_h);
735 if(mpi && mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){
736 // vd core likes slices!
737 avctx->draw_horiz_band=draw_slice;
741 avctx->hurry_up=(flags&3)?((flags&2)?2:1):0;
743 if(sh->ds->demuxer->type != DEMUXER_TYPE_LAVF &&
744 sh->ds->demuxer->type != DEMUXER_TYPE_LAVF_PREFERRED)
745 if( sh->format == mmioFOURCC('R', 'V', '1', '0')
746 || sh->format == mmioFOURCC('R', 'V', '1', '3')
747 || sh->format == mmioFOURCC('R', 'V', '2', '0')
748 || sh->format == mmioFOURCC('R', 'V', '3', '0')
749 || sh->format == mmioFOURCC('R', 'V', '4', '0'))
751 dp_hdr_t *hdr= (dp_hdr_t*)data;
752 uint32_t *offsets = (uint32_t*)((char *)data + hdr->chunktab);
753 uint8_t *offstab = av_malloc((hdr->chunks+1) * 8);
754 uint8_t *buf = data;
755 int chunks = hdr->chunks;
756 int dlen = hdr->len;
758 buf[0] = chunks;
759 memcpy(offstab, offsets, (chunks + 1) * 8);
760 memmove(buf + 1 + (chunks + 1) * 8, (char *)data + sizeof(dp_hdr_t), dlen);
761 memcpy(buf + 1, offstab, (chunks + 1) * 8);
762 av_free(offstab);
765 mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "vd_ffmpeg data: %04x, %04x, %04x, %04x\n",
766 ((int *)data)[0], ((int *)data)[1], ((int *)data)[2], ((int *)data)[3]);
767 ret = avcodec_decode_video(avctx, pic,
768 &got_picture, data, len);
770 dr1= ctx->do_dr1;
771 if(ret<0) mp_msg(MSGT_DECVIDEO,MSGL_WARN, "Error while decoding frame!\n");
772 //printf("repeat: %d\n", pic->repeat_pict);
773 //-- vstats generation
774 while(lavc_param->vstats){ // always one time loop
775 static FILE *fvstats=NULL;
776 char filename[20];
777 static long long int all_len=0;
778 static int frame_number=0;
779 static double all_frametime=0.0;
780 AVFrame *pic= avctx->coded_frame;
781 double quality=0.0;
783 if(!fvstats) {
784 time_t today2;
785 struct tm *today;
786 today2 = time(NULL);
787 today = localtime(&today2);
788 sprintf(filename, "vstats_%02d%02d%02d.log", today->tm_hour,
789 today->tm_min, today->tm_sec);
790 fvstats = fopen(filename,"w");
791 if(!fvstats) {
792 perror("fopen");
793 lavc_param->vstats=0; // disable block
794 break;
795 /*exit(1);*/
799 // average MB quantizer
801 int x, y;
802 int w = ((avctx->width << ctx->lowres)+15) >> 4;
803 int h = ((avctx->height << ctx->lowres)+15) >> 4;
804 int8_t *q = pic->qscale_table;
805 for( y = 0; y < h; y++ ) {
806 for( x = 0; x < w; x++ )
807 quality += (double)*(q+x);
808 q += pic->qstride;
810 quality /= w * h;
813 all_len+=len;
814 all_frametime+=sh->frametime;
815 fprintf(fvstats, "frame= %5d q= %2.2f f_size= %6d s_size= %8.0fkB ",
816 ++frame_number, quality, len, (double)all_len/1024);
817 fprintf(fvstats, "time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
818 all_frametime, (double)(len*8)/sh->frametime/1000.0,
819 (double)(all_len*8)/all_frametime/1000.0);
820 switch(pic->pict_type){
821 case FF_I_TYPE:
822 fprintf(fvstats, "type= I\n");
823 break;
824 case FF_P_TYPE:
825 fprintf(fvstats, "type= P\n");
826 break;
827 case FF_S_TYPE:
828 fprintf(fvstats, "type= S\n");
829 break;
830 case FF_B_TYPE:
831 fprintf(fvstats, "type= B\n");
832 break;
833 default:
834 fprintf(fvstats, "type= ? (%d)\n", pic->pict_type);
835 break;
838 ctx->qp_stat[(int)(quality+0.5)]++;
839 ctx->qp_sum += quality;
840 ctx->inv_qp_sum += 1.0/(double)quality;
842 break;
844 //--
846 if(!got_picture) return NULL; // skipped image
848 if(init_vo(sh,avctx->pix_fmt) < 0) return NULL;
850 if(dr1 && pic->opaque){
851 mpi= (mp_image_t*)pic->opaque;
854 if(!mpi)
855 mpi=mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, MP_IMGFLAG_PRESERVE,
856 avctx->width, avctx->height);
857 if(!mpi){ // temporary!
858 mp_msg(MSGT_DECVIDEO, MSGL_WARN, MSGTR_MPCODECS_CouldntAllocateImageForCodec);
859 return NULL;
862 if(!dr1){
863 mpi->planes[0]=pic->data[0];
864 mpi->planes[1]=pic->data[1];
865 mpi->planes[2]=pic->data[2];
866 mpi->stride[0]=pic->linesize[0];
867 mpi->stride[1]=pic->linesize[1];
868 mpi->stride[2]=pic->linesize[2];
871 if (!mpi->planes[0])
872 return NULL;
874 if(avctx->pix_fmt==PIX_FMT_YUV422P && mpi->chroma_y_shift==1){
875 // we have 422p but user wants 420p
876 mpi->stride[1]*=2;
877 mpi->stride[2]*=2;
880 #ifdef WORDS_BIGENDIAN
881 // FIXME: this might cause problems for buffers with FF_BUFFER_HINTS_PRESERVE
882 if (mpi->bpp == 8)
883 swap_palette(mpi->planes[1]);
884 #endif
885 /* to comfirm with newer lavc style */
886 mpi->qscale =pic->qscale_table;
887 mpi->qstride=pic->qstride;
888 mpi->pict_type=pic->pict_type;
889 mpi->qscale_type= pic->qscale_type;
890 mpi->fields = MP_IMGFIELD_ORDERED;
891 if(pic->interlaced_frame) mpi->fields |= MP_IMGFIELD_INTERLACED;
892 if(pic->top_field_first ) mpi->fields |= MP_IMGFIELD_TOP_FIRST;
893 if(pic->repeat_pict == 1) mpi->fields |= MP_IMGFIELD_REPEAT_FIRST;
895 return mpi;
898 #ifdef CONFIG_XVMC
899 static enum PixelFormat get_format(struct AVCodecContext * avctx,
900 const enum PixelFormat * fmt){
901 sh_video_t * sh = avctx->opaque;
902 int i;
904 if(avctx->xvmc_acceleration){
905 vd_ffmpeg_ctx *ctx = sh->context;
906 avctx->get_buffer= mc_get_buffer;
907 avctx->release_buffer= mc_release_buffer;
908 avctx->draw_horiz_band = mc_render_slice;
909 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCAcceleratedMPEG2);
910 assert(ctx->do_dr1);//these are must to!
911 assert(ctx->do_slices); //it is (vo_)ffmpeg bug if this fails
912 avctx->flags|= CODEC_FLAG_EMU_EDGE;//do i need that??!!
913 avctx->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
915 for(i=0;fmt[i]!=-1;i++){
916 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_TryingPixfmt,i);
917 if( init_vo(sh,fmt[i]) >= 0)
918 return fmt[i];
920 return fmt[0];
923 static int mc_get_buffer(AVCodecContext *avctx, AVFrame *pic){
924 sh_video_t * sh = avctx->opaque;
925 vd_ffmpeg_ctx *ctx = sh->context;
926 mp_image_t* mpi=NULL;
927 struct xvmc_render_state * render;
928 int flags= MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE|
929 MP_IMGFLAG_DRAW_CALLBACK;
931 // printf("vd_ffmpeg::mc_get_buffer (xvmc) %d %d %d\n", pic->reference, ctx->ip_count, ctx->b_count);
932 if(!avctx->xvmc_acceleration){
933 mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_McGetBufferShouldWorkOnlyWithXVMC);
934 assert(0);
935 exit(1);
936 // return -1;//!!fixme check error conditions
938 assert(avctx->draw_horiz_band == mc_render_slice);
939 assert(avctx->release_buffer == mc_release_buffer);
940 if( mp_msg_test(MSGT_DECVIDEO,MSGL_DBG5) )
941 mp_msg(MSGT_DECVIDEO, MSGL_DBG5, "vd_ffmpeg::mc_get_buffer\n");
943 if(init_vo(sh,avctx->pix_fmt) < 0){
944 mp_msg(MSGT_DECVIDEO, MSGL_WARN, MSGTR_MPCODECS_UnexpectedInitVoError);
945 exit(1);
946 // return -1;//!!fixme check error conditions
951 if(!pic->reference){
952 ctx->b_count++;
953 }else{
954 ctx->ip_count++;
955 flags|= MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE;
958 mpi= mpcodecs_get_image(sh, MP_IMGTYPE_IPB,flags ,
959 avctx->width, avctx->height);
960 if(mpi==NULL){
961 mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_MPCODECS_UnrecoverableErrorRenderBuffersNotTaken);
962 assert(0);
963 exit(1);
964 // return -1;//!!fixme check error conditions in ffmpeg
967 if( (mpi->flags & MP_IMGFLAG_DIRECT) == 0){
968 mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_MPCODECS_OnlyBuffersAllocatedByVoXvmcAllowed);
969 assert(0);
970 exit(1);
971 // return -1;//!!fixme check error conditions in ffmpeg
974 pic->data[0]= mpi->planes[0];
975 pic->data[1]= mpi->planes[1];
976 pic->data[2]= mpi->planes[2];
979 /* Note, some (many) codecs in libavcodec must have stride1==stride2 && no changes between frames
980 * lavc will check that and die with an error message, if its not true
982 pic->linesize[0]= mpi->stride[0];
983 pic->linesize[1]= mpi->stride[1];
984 pic->linesize[2]= mpi->stride[2];
986 pic->opaque = mpi;
988 if(pic->reference){
989 //I or P frame
990 pic->age= ctx->ip_age[0];
992 ctx->ip_age[0]= ctx->ip_age[1]+1;
993 ctx->ip_age[1]= 1;
994 ctx->b_age++;
995 }else{
996 //B frame
997 pic->age= ctx->b_age;
999 ctx->ip_age[0]++;
1000 ctx->ip_age[1]++;
1001 ctx->b_age=1;
1004 pic->type= FF_BUFFER_TYPE_USER;
1006 render=(struct xvmc_render_state*)mpi->priv;//same as data[2]
1007 if( mp_msg_test(MSGT_DECVIDEO,MSGL_DBG5) )
1008 mp_msg(MSGT_DECVIDEO, MSGL_DBG5, "vd_ffmpeg::mc_get_buffer (render=%p)\n",render);
1009 assert(render != 0);
1010 assert(render->magic == MP_XVMC_RENDER_MAGIC);
1011 render->state |= MP_XVMC_STATE_PREDICTION;
1012 return 0;
1016 static void mc_release_buffer(AVCodecContext *avctx, AVFrame *pic){
1017 mp_image_t* mpi= pic->opaque;
1018 sh_video_t * sh = avctx->opaque;
1019 vd_ffmpeg_ctx *ctx = sh->context;
1020 struct xvmc_render_state * render;
1021 int i;
1024 if(ctx->ip_count <= 2 && ctx->b_count<=1){
1025 if(mpi->flags&MP_IMGFLAG_PRESERVE)
1026 ctx->ip_count--;
1027 else
1028 ctx->b_count--;
1031 //printf("R%X %X\n", pic->linesize[0], pic->data[0]);
1032 //mark the surface as not requared for prediction
1033 render=(struct xvmc_render_state*)pic->data[2];//same as mpi->priv
1034 if( mp_msg_test(MSGT_DECVIDEO,MSGL_DBG5) )
1035 mp_msg(MSGT_DECVIDEO, MSGL_DBG5, "vd_ffmpeg::mc_release_buffer (render=%p)\n",render);
1036 assert(render!=NULL);
1037 assert(render->magic==MP_XVMC_RENDER_MAGIC);
1038 render->state&=~MP_XVMC_STATE_PREDICTION;
1039 for(i=0; i<4; i++){
1040 pic->data[i]= NULL;
1044 static void mc_render_slice(struct AVCodecContext *s,
1045 const AVFrame *src, int offset[4],
1046 int y, int type, int height){
1047 int width= s->width;
1048 sh_video_t * sh = s->opaque;
1049 uint8_t *source[3]= {src->data[0], src->data[1], src->data[2]};
1051 assert(src->linesize[0]==0 && src->linesize[1]==0 && src->linesize[2]==0);
1052 assert(offset[0]==0 && offset[1]==0 && offset[2]==0);
1054 mpcodecs_draw_slice (sh, source, src->linesize, width, height, 0, y);
1058 #endif /* CONFIG_XVMC */