00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <vlc/vlc.h>
00029 #include <vlc/decoder.h>
00030 #include <vlc/input.h>
00031
00032
00033 #ifdef HAVE_FFMPEG_AVCODEC_H
00034 # include <ffmpeg/avcodec.h>
00035 #else
00036 # include <avcodec.h>
00037 #endif
00038
00039 #include "ffmpeg.h"
00040
00041
00042
00043
00044 struct decoder_sys_t
00045 {
00046
00047 int i_cat;
00048 int i_codec_id;
00049 char *psz_namecodec;
00050
00051 AVCodecContext *p_context;
00052 AVCodec *p_codec;
00053
00054
00055 mtime_t input_pts;
00056 mtime_t input_dts;
00057 mtime_t i_pts;
00058
00059 AVFrame *p_ff_pic;
00060 BITMAPINFOHEADER *p_format;
00061
00062
00063 int b_hurry_up;
00064 int i_frame_skip;
00065
00066
00067 int i_late_frames;
00068 mtime_t i_late_frames_start;
00069
00070
00071 int b_direct_rendering;
00072
00073 vlc_bool_t b_has_b_frames;
00074
00075
00076 vlc_bool_t b_first_frame;
00077
00078 int i_buffer_orig, i_buffer;
00079 char *p_buffer_orig, *p_buffer;
00080
00081
00082 void *p_pp;
00083 vlc_bool_t b_pp;
00084 vlc_bool_t b_pp_async;
00085 vlc_bool_t b_pp_init;
00086 };
00087
00088
00089 static AVPaletteControl palette_control;
00090
00091
00092
00093
00094 static void ffmpeg_InitCodec ( decoder_t * );
00095 static void ffmpeg_CopyPicture ( decoder_t *, picture_t *, AVFrame * );
00096 static int ffmpeg_GetFrameBuf ( struct AVCodecContext *, AVFrame * );
00097 static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * );
00098
00099 static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
00100 {
00101 uint8_t *p = (uint8_t*)&fcc;
00102 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
00103 }
00104
00105
00106
00107
00108 static uint32_t ffmpeg_PixFmtToChroma( int i_ff_chroma )
00109 {
00110 switch( i_ff_chroma )
00111 {
00112 case PIX_FMT_YUV420P:
00113 case PIX_FMT_YUVJ420P:
00114 return VLC_FOURCC('I','4','2','0');
00115 case PIX_FMT_YUV422P:
00116 case PIX_FMT_YUVJ422P:
00117 return VLC_FOURCC('I','4','2','2');
00118 case PIX_FMT_YUV444P:
00119 case PIX_FMT_YUVJ444P:
00120 return VLC_FOURCC('I','4','4','4');
00121
00122 case PIX_FMT_YUV422:
00123 return VLC_FOURCC('Y','U','Y','2');
00124
00125 case PIX_FMT_RGB555:
00126 return VLC_FOURCC('R','V','1','5');
00127 case PIX_FMT_RGB565:
00128 return VLC_FOURCC('R','V','1','6');
00129 case PIX_FMT_RGB24:
00130 return VLC_FOURCC('R','V','2','4');
00131 case PIX_FMT_RGBA32:
00132 return VLC_FOURCC('R','V','3','2');
00133 case PIX_FMT_GRAY8:
00134 return VLC_FOURCC('G','R','E','Y');
00135
00136 case PIX_FMT_YUV410P:
00137 case PIX_FMT_YUV411P:
00138 case PIX_FMT_BGR24:
00139 default:
00140 return 0;
00141 }
00142 }
00143
00144
00145 static inline picture_t *ffmpeg_NewPictBuf( decoder_t *p_dec,
00146 AVCodecContext *p_context )
00147 {
00148 decoder_sys_t *p_sys = p_dec->p_sys;
00149 picture_t *p_pic;
00150
00151 p_dec->fmt_out.video.i_width = p_context->width;
00152 p_dec->fmt_out.video.i_height = p_context->height;
00153 p_dec->fmt_out.i_codec = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
00154
00155 if( !p_context->width || !p_context->height )
00156 {
00157 return NULL;
00158 }
00159
00160 if( !p_dec->fmt_out.i_codec )
00161 {
00162
00163 p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
00164 }
00165
00166
00167 if( p_dec->fmt_in.video.i_aspect )
00168 {
00169 p_dec->fmt_out.video.i_aspect = p_dec->fmt_in.video.i_aspect;
00170 }
00171 else
00172 {
00173 #if LIBAVCODEC_BUILD >= 4687
00174 p_dec->fmt_out.video.i_aspect =
00175 VOUT_ASPECT_FACTOR * ( av_q2d(p_context->sample_aspect_ratio) *
00176 p_context->width / p_context->height );
00177 p_dec->fmt_out.video.i_sar_num = p_context->sample_aspect_ratio.num;
00178 p_dec->fmt_out.video.i_sar_den = p_context->sample_aspect_ratio.den;
00179 #else
00180 p_dec->fmt_out.video.i_aspect =
00181 VOUT_ASPECT_FACTOR * p_context->aspect_ratio;
00182 #endif
00183 if( p_dec->fmt_out.video.i_aspect == 0 )
00184 {
00185 p_dec->fmt_out.video.i_aspect =
00186 VOUT_ASPECT_FACTOR * p_context->width / p_context->height;
00187 }
00188 }
00189
00190 #if LIBAVCODEC_BUILD >= 4754
00191 if( p_context->time_base.num > 0 && p_context->time_base.den > 0 )
00192 {
00193 p_dec->fmt_out.video.i_frame_rate = p_context->time_base.den;
00194 p_dec->fmt_out.video.i_frame_rate_base = p_context->time_base.num;
00195 }
00196 #else
00197 if( p_context->frame_rate > 0 && p_context->frame_rate_base > 0 )
00198 {
00199 p_dec->fmt_out.video.i_frame_rate = p_context->frame_rate;
00200 p_dec->fmt_out.video.i_frame_rate_base = p_context->frame_rate_base;
00201 }
00202 #endif
00203
00204 p_pic = p_dec->pf_vout_buffer_new( p_dec );
00205
00206 #ifdef LIBAVCODEC_PP
00207 if( p_sys->p_pp && p_sys->b_pp && !p_sys->b_pp_init )
00208 {
00209 E_(InitPostproc)( p_dec, p_sys->p_pp, p_context->width,
00210 p_context->height, p_context->pix_fmt );
00211 p_sys->b_pp_init = VLC_TRUE;
00212 }
00213 #endif
00214
00215 return p_pic;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224 int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
00225 AVCodec *p_codec, int i_codec_id, char *psz_namecodec )
00226 {
00227 decoder_sys_t *p_sys;
00228 vlc_value_t lockval;
00229 vlc_value_t val;
00230
00231 var_Get( p_dec->p_libvlc, "avcodec", &lockval );
00232
00233
00234 if( ( p_dec->p_sys = p_sys =
00235 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
00236 {
00237 msg_Err( p_dec, "out of memory" );
00238 return VLC_EGENERIC;
00239 }
00240
00241 p_dec->p_sys->p_context = p_context;
00242 p_dec->p_sys->p_codec = p_codec;
00243 p_dec->p_sys->i_codec_id = i_codec_id;
00244 p_dec->p_sys->psz_namecodec = psz_namecodec;
00245 p_sys->p_ff_pic = avcodec_alloc_frame();
00246
00247
00248
00249 if( p_dec->fmt_in.i_codec != VLC_FOURCC('a','v','c','1') )
00250
00251 p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_codec );
00252 p_sys->p_context->width = p_dec->fmt_in.video.i_width;
00253 p_sys->p_context->height = p_dec->fmt_in.video.i_height;
00254 p_sys->p_context->bits_per_sample = p_dec->fmt_in.video.i_bits_per_pixel;
00255
00256
00257 p_sys->p_context->workaround_bugs =
00258 config_GetInt( p_dec, "ffmpeg-workaround-bugs" );
00259 p_sys->p_context->error_resilience =
00260 config_GetInt( p_dec, "ffmpeg-error-resilience" );
00261
00262 var_Create( p_dec, "grayscale", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
00263 var_Get( p_dec, "grayscale", &val );
00264 if( val.b_bool ) p_sys->p_context->flags |= CODEC_FLAG_GRAY;
00265
00266 var_Create( p_dec, "ffmpeg-vismv", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00267 var_Get( p_dec, "ffmpeg-vismv", &val );
00268 #if LIBAVCODEC_BUILD >= 4698
00269 if( val.i_int ) p_sys->p_context->debug_mv = val.i_int;
00270 #endif
00271
00272 var_Create( p_dec, "ffmpeg-lowres", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00273 var_Get( p_dec, "ffmpeg-lowres", &val );
00274 #if LIBAVCODEC_BUILD >= 4723
00275 if( val.i_int > 0 && val.i_int <= 2 ) p_sys->p_context->lowres = val.i_int;
00276 #endif
00277
00278
00279 var_Create( p_dec, "ffmpeg-hurry-up", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
00280 var_Get( p_dec, "ffmpeg-hurry-up", &val );
00281 p_sys->b_hurry_up = val.b_bool;
00282
00283
00284 p_sys->b_direct_rendering = 0;
00285 var_Create( p_dec, "ffmpeg-dr", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
00286 var_Get( p_dec, "ffmpeg-dr", &val );
00287 if( val.b_bool && (p_sys->p_codec->capabilities & CODEC_CAP_DR1) &&
00288 ffmpeg_PixFmtToChroma( p_sys->p_context->pix_fmt ) &&
00289
00290 p_sys->p_context->pix_fmt != PIX_FMT_YUV422P &&
00291
00292 p_sys->i_codec_id != CODEC_ID_H264 &&
00293 !(p_sys->p_context->width % 16) && !(p_sys->p_context->height % 16) &&
00294 #if LIBAVCODEC_BUILD >= 4698
00295 !p_sys->p_context->debug_mv )
00296 #else
00297 1 )
00298 #endif
00299 {
00300
00301
00302 p_sys->b_direct_rendering = 1;
00303 }
00304
00305 #ifdef LIBAVCODEC_PP
00306 p_sys->p_pp = NULL;
00307 p_sys->b_pp = p_sys->b_pp_async = p_sys->b_pp_init = VLC_FALSE;
00308 p_sys->p_pp = E_(OpenPostproc)( p_dec, &p_sys->b_pp_async );
00309 #endif
00310
00311
00312
00313 if( p_sys->b_direct_rendering )
00314 {
00315 msg_Dbg( p_dec, "using direct rendering" );
00316 p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE;
00317 }
00318
00319
00320
00321 p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
00322 p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
00323 p_sys->p_context->opaque = p_dec;
00324
00325
00326 ffmpeg_InitCodec( p_dec );
00327
00328
00329 p_sys->input_pts = p_sys->input_dts = 0;
00330 p_sys->i_pts = 0;
00331 p_sys->b_has_b_frames = VLC_FALSE;
00332 p_sys->b_first_frame = VLC_TRUE;
00333 p_sys->i_late_frames = 0;
00334 p_sys->i_buffer = 0;
00335 p_sys->i_buffer_orig = 1;
00336 p_sys->p_buffer_orig = p_sys->p_buffer = malloc( p_sys->i_buffer_orig );
00337
00338
00339 p_dec->fmt_out.i_cat = VIDEO_ES;
00340 p_dec->fmt_out.i_codec = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
00341
00342
00343 #if LIBAVCODEC_BUILD >= 4688
00344 if( p_dec->fmt_in.video.p_palette )
00345 p_sys->p_context->palctrl =
00346 (AVPaletteControl *)p_dec->fmt_in.video.p_palette;
00347 else
00348 p_sys->p_context->palctrl = &palette_control;
00349 #endif
00350
00351
00352 vlc_mutex_lock( lockval.p_address );
00353 if( avcodec_open( p_sys->p_context, p_sys->p_codec ) < 0 )
00354 {
00355 vlc_mutex_unlock( lockval.p_address );
00356 msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
00357 free( p_sys );
00358 return VLC_EGENERIC;
00359 }
00360 vlc_mutex_unlock( lockval.p_address );
00361 msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );
00362
00363
00364 return VLC_SUCCESS;
00365 }
00366
00367
00368
00369
00370 picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
00371 {
00372 decoder_sys_t *p_sys = p_dec->p_sys;
00373 int b_drawpicture;
00374 int b_null_size = VLC_FALSE;
00375 block_t *p_block;
00376
00377 if( !pp_block || !*pp_block ) return NULL;
00378
00379 if( !p_sys->p_context->extradata_size && p_dec->fmt_in.i_extra )
00380 ffmpeg_InitCodec( p_dec );
00381
00382 p_block = *pp_block;
00383
00384 if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
00385 {
00386 p_sys->i_buffer = 0;
00387 p_sys->i_pts = 0;
00388
00389 p_sys->input_pts = p_sys->input_dts = 0;
00390 p_sys->i_late_frames = 0;
00391
00392 block_Release( p_block );
00393 return NULL;
00394 }
00395
00396 if( p_block->i_flags & BLOCK_FLAG_PREROLL )
00397 {
00398
00399
00400
00401 p_sys->i_late_frames = 0;
00402 }
00403
00404 if( !p_dec->b_pace_control && p_sys->i_late_frames > 0 &&
00405 mdate() - p_sys->i_late_frames_start > I64C(5000000) )
00406 {
00407 if( p_sys->i_pts )
00408 {
00409 msg_Err( p_dec, "more than 5 seconds of late video -> "
00410 "dropping frame (computer too slow ?)" );
00411 p_sys->i_pts = 0;
00412 }
00413 block_Release( p_block );
00414 p_sys->i_late_frames--;
00415 return NULL;
00416 }
00417
00418 if( p_block->i_pts > 0 || p_block->i_dts > 0 )
00419 {
00420 p_sys->input_pts = p_block->i_pts;
00421 p_sys->input_dts = p_block->i_dts;
00422
00423
00424 p_block->i_pts = p_block->i_dts = 0;
00425 }
00426
00427
00428
00429 if( !p_dec->b_pace_control &&
00430 p_sys->b_hurry_up && p_sys->i_late_frames > 4 )
00431 {
00432 b_drawpicture = 0;
00433 if( p_sys->i_late_frames < 8 )
00434 {
00435 p_sys->p_context->hurry_up = 2;
00436 }
00437 else
00438 {
00439
00440
00441
00442 p_sys->i_late_frames--;
00443 block_Release( p_block );
00444 p_sys->i_buffer = 0;
00445 return NULL;
00446 }
00447 }
00448 else
00449 {
00450 if (!(p_block->i_flags & BLOCK_FLAG_PREROLL))
00451 {
00452 b_drawpicture = 1;
00453 p_sys->p_context->hurry_up = 0;
00454 }
00455 else
00456 {
00457 b_drawpicture = 0;
00458 p_sys->p_context->hurry_up = 1;
00459 }
00460 }
00461
00462
00463 if( p_sys->p_context->width <= 0 || p_sys->p_context->height <= 0 )
00464 {
00465 p_sys->p_context->hurry_up = 5;
00466 b_null_size = VLC_TRUE;
00467 }
00468
00469
00470
00471
00472
00473
00474 p_sys->b_pp = p_sys->b_pp_async;
00475
00476
00477
00478 if( p_block->i_buffer > 0 )
00479 {
00480 p_sys->i_buffer = p_block->i_buffer;
00481 if( p_sys->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE >
00482 p_sys->i_buffer_orig )
00483 {
00484 free( p_sys->p_buffer_orig );
00485 p_sys->i_buffer_orig =
00486 p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE;
00487 p_sys->p_buffer_orig = malloc( p_sys->i_buffer_orig );
00488 }
00489 p_sys->p_buffer = p_sys->p_buffer_orig;
00490 p_sys->i_buffer = p_block->i_buffer;
00491 p_dec->p_vlc->pf_memcpy( p_sys->p_buffer, p_block->p_buffer,
00492 p_block->i_buffer );
00493 memset( p_sys->p_buffer + p_block->i_buffer, 0,
00494 FF_INPUT_BUFFER_PADDING_SIZE );
00495
00496 p_block->i_buffer = 0;
00497 }
00498
00499 while( p_sys->i_buffer > 0 )
00500 {
00501 int i_used, b_gotpicture;
00502 picture_t *p_pic;
00503
00504 i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
00505 &b_gotpicture,
00506 p_sys->p_buffer, p_sys->i_buffer );
00507 if( b_null_size && p_sys->p_context->width > 0 &&
00508 p_sys->p_context->height > 0 )
00509 {
00510
00511 b_null_size = VLC_FALSE;
00512 p_sys->p_context->hurry_up = 0;
00513 i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
00514 &b_gotpicture,
00515 p_sys->p_buffer, p_sys->i_buffer );
00516 }
00517
00518 if( i_used < 0 )
00519 {
00520 msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
00521 p_sys->i_buffer );
00522 block_Release( p_block );
00523 return NULL;
00524 }
00525 else if( i_used > p_sys->i_buffer )
00526 {
00527 i_used = p_sys->i_buffer;
00528 }
00529
00530
00531 p_sys->i_buffer -= i_used;
00532 p_sys->p_buffer += i_used;
00533
00534
00535 if( !b_gotpicture )
00536 {
00537 if( i_used == 0 ) break;
00538 continue;
00539 }
00540
00541
00542 if( p_sys->i_pts && p_sys->i_pts <= mdate() &&
00543 !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
00544 {
00545 p_sys->i_late_frames++;
00546 if( p_sys->i_late_frames == 1 )
00547 p_sys->i_late_frames_start = mdate();
00548 }
00549 else
00550 {
00551 p_sys->i_late_frames = 0;
00552 }
00553
00554 if( !b_drawpicture || !p_sys->p_ff_pic->linesize[0] )
00555 {
00556
00557 continue;
00558 }
00559
00560 if( !p_sys->p_ff_pic->opaque )
00561 {
00562
00563 p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
00564 if( !p_pic )
00565 {
00566 block_Release( p_block );
00567 return NULL;
00568 }
00569
00570
00571
00572 ffmpeg_CopyPicture( p_dec, p_pic, p_sys->p_ff_pic );
00573 }
00574 else
00575 {
00576 p_pic = (picture_t *)p_sys->p_ff_pic->opaque;
00577 }
00578
00579
00580 if( p_sys->p_ff_pic->pts ) p_sys->i_pts = p_sys->p_ff_pic->pts;
00581
00582
00583 if( p_sys->p_ff_pic->pict_type == FF_B_TYPE )
00584 {
00585 p_sys->b_has_b_frames = VLC_TRUE;
00586 }
00587
00588 if( !p_dec->fmt_in.video.i_aspect )
00589 {
00590
00591 #if LIBAVCODEC_BUILD >= 4687
00592 p_dec->fmt_out.video.i_aspect =
00593 VOUT_ASPECT_FACTOR
00594 * ( av_q2d(p_sys->p_context->sample_aspect_ratio)
00595 * p_sys->p_context->width / p_sys->p_context->height );
00596 p_dec->fmt_out.video.i_sar_num
00597 = p_sys->p_context->sample_aspect_ratio.num;
00598 p_dec->fmt_out.video.i_sar_den
00599 = p_sys->p_context->sample_aspect_ratio.den;
00600 #else
00601 p_dec->fmt_out.video.i_aspect =
00602 VOUT_ASPECT_FACTOR * p_sys->p_context->aspect_ratio;
00603 #endif
00604 if( p_dec->fmt_out.video.i_aspect == 0 )
00605 {
00606 p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR
00607 * p_sys->p_context->width / p_sys->p_context->height;
00608 }
00609 }
00610
00611
00612 if( p_sys->i_pts )
00613 {
00614 p_pic->date = p_sys->i_pts;
00615
00616
00617 #if LIBAVCODEC_BUILD >= 4754
00618 if( p_dec->fmt_in.video.i_frame_rate > 0 &&
00619 p_dec->fmt_in.video.i_frame_rate_base > 0 )
00620 {
00621 p_sys->i_pts += I64C(1000000) *
00622 (2 + p_sys->p_ff_pic->repeat_pict) *
00623 p_dec->fmt_in.video.i_frame_rate_base *
00624 p_block->i_rate / INPUT_RATE_DEFAULT /
00625 (2 * p_dec->fmt_in.video.i_frame_rate);
00626 }
00627 else if( p_sys->p_context->time_base.den > 0 )
00628 {
00629 p_sys->i_pts += I64C(1000000) *
00630 (2 + p_sys->p_ff_pic->repeat_pict) *
00631 p_sys->p_context->time_base.num *
00632 p_block->i_rate / INPUT_RATE_DEFAULT /
00633 (2 * p_sys->p_context->time_base.den);
00634 }
00635 #else
00636 if( p_sys->p_context->frame_rate > 0 )
00637 {
00638 p_sys->i_pts += I64C(1000000) *
00639 (2 + p_sys->p_ff_pic->repeat_pict) *
00640 p_sys->p_context->frame_rate_base *
00641 p_block->i_rate / INPUT_RATE_DEFAULT /
00642 (2 * p_sys->p_context->frame_rate);
00643 }
00644 #endif
00645
00646 if( p_sys->b_first_frame )
00647 {
00648
00649 p_sys->b_first_frame = VLC_FALSE;
00650 p_pic->b_force = VLC_TRUE;
00651 }
00652
00653 p_pic->i_nb_fields = 2 + p_sys->p_ff_pic->repeat_pict;
00654 #if LIBAVCODEC_BUILD >= 4685
00655 p_pic->b_progressive = !p_sys->p_ff_pic->interlaced_frame;
00656 p_pic->b_top_field_first = p_sys->p_ff_pic->top_field_first;
00657 #endif
00658
00659 return p_pic;
00660 }
00661 else
00662 {
00663 p_dec->pf_vout_buffer_del( p_dec, p_pic );
00664 }
00665 }
00666
00667 block_Release( p_block );
00668 return NULL;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677 void E_(EndVideoDec)( decoder_t *p_dec )
00678 {
00679 decoder_sys_t *p_sys = p_dec->p_sys;
00680
00681 if( p_sys->p_ff_pic ) av_free( p_sys->p_ff_pic );
00682
00683 #ifdef LIBAVCODEC_PP
00684 E_(ClosePostproc)( p_dec, p_sys->p_pp );
00685 #endif
00686
00687 free( p_sys->p_buffer_orig );
00688 }
00689
00690
00691
00692
00693 static void ffmpeg_InitCodec( decoder_t *p_dec )
00694 {
00695 decoder_sys_t *p_sys = p_dec->p_sys;
00696 int i_size = p_dec->fmt_in.i_extra;
00697
00698 if( !i_size ) return;
00699
00700 if( p_sys->i_codec_id == CODEC_ID_SVQ3 )
00701 {
00702 uint8_t *p;
00703
00704 p_sys->p_context->extradata_size = i_size + 12;
00705 p = p_sys->p_context->extradata =
00706 malloc( p_sys->p_context->extradata_size );
00707
00708 memcpy( &p[0], "SVQ3", 4 );
00709 memset( &p[4], 0, 8 );
00710 memcpy( &p[12], p_dec->fmt_in.p_extra, i_size );
00711
00712
00713 if( p_sys->p_context->extradata_size > 0x5a &&
00714 strncmp( &p[0x56], "SMI ", 4 ) )
00715 {
00716 uint8_t *psz = &p[0x52];
00717
00718 while( psz < &p[p_sys->p_context->extradata_size - 8] )
00719 {
00720 int i_size = GetDWBE( psz );
00721 if( i_size <= 1 )
00722 {
00723
00724 break;
00725 }
00726 if( !strncmp( &psz[4], "SMI ", 4 ) )
00727 {
00728 memmove( &p[0x52], psz,
00729 &p[p_sys->p_context->extradata_size] - psz );
00730 break;
00731 }
00732
00733 psz += i_size;
00734 }
00735 }
00736 }
00737 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'R', 'V', '1', '0' ) ||
00738 p_dec->fmt_in.i_codec == VLC_FOURCC( 'R', 'V', '1', '3' ) ||
00739 p_dec->fmt_in.i_codec == VLC_FOURCC( 'R', 'V', '2', '0' ) )
00740 {
00741 if( p_dec->fmt_in.i_extra == 8 )
00742 {
00743 p_sys->p_context->extradata_size = 8;
00744 p_sys->p_context->extradata = malloc( 8 );
00745
00746 memcpy( p_sys->p_context->extradata,
00747 p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
00748 p_sys->p_context->sub_id= ((uint32_t*)p_dec->fmt_in.p_extra)[1];
00749
00750 msg_Warn( p_dec, "using extra data for RV codec sub_id=%08x",
00751 p_sys->p_context->sub_id );
00752 }
00753 }
00754 else
00755 {
00756 p_sys->p_context->extradata_size = i_size;
00757 p_sys->p_context->extradata =
00758 malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
00759 memcpy( p_sys->p_context->extradata,
00760 p_dec->fmt_in.p_extra, i_size );
00761 memset( &((uint8_t*)p_sys->p_context->extradata)[i_size],
00762 0, FF_INPUT_BUFFER_PADDING_SIZE );
00763 }
00764 }
00765
00766
00767
00768
00769
00770 static void ffmpeg_CopyPicture( decoder_t *p_dec,
00771 picture_t *p_pic, AVFrame *p_ff_pic )
00772 {
00773 decoder_sys_t *p_sys = p_dec->p_sys;
00774
00775 if( ffmpeg_PixFmtToChroma( p_sys->p_context->pix_fmt ) )
00776 {
00777 int i_plane, i_size, i_line;
00778 uint8_t *p_dst, *p_src;
00779 int i_src_stride, i_dst_stride;
00780
00781 #ifdef LIBAVCODEC_PP
00782 if( p_sys->p_pp && p_sys->b_pp )
00783 E_(PostprocPict)( p_dec, p_sys->p_pp, p_pic, p_ff_pic );
00784 else
00785 #endif
00786 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
00787 {
00788 p_src = p_ff_pic->data[i_plane];
00789 p_dst = p_pic->p[i_plane].p_pixels;
00790 i_src_stride = p_ff_pic->linesize[i_plane];
00791 i_dst_stride = p_pic->p[i_plane].i_pitch;
00792
00793 i_size = __MIN( i_src_stride, i_dst_stride );
00794 for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines;
00795 i_line++ )
00796 {
00797 p_dec->p_vlc->pf_memcpy( p_dst, p_src, i_size );
00798 p_src += i_src_stride;
00799 p_dst += i_dst_stride;
00800 }
00801 }
00802 }
00803 else
00804 {
00805 AVPicture dest_pic;
00806 int i;
00807
00808
00809 switch( p_sys->p_context->pix_fmt )
00810 {
00811 case PIX_FMT_YUV410P:
00812 case PIX_FMT_YUV411P:
00813 case PIX_FMT_BGR24:
00814 case PIX_FMT_PAL8:
00815 for( i = 0; i < p_pic->i_planes; i++ )
00816 {
00817 dest_pic.data[i] = p_pic->p[i].p_pixels;
00818 dest_pic.linesize[i] = p_pic->p[i].i_pitch;
00819 }
00820 img_convert( &dest_pic, PIX_FMT_YUV420P,
00821 (AVPicture *)p_ff_pic,
00822 p_sys->p_context->pix_fmt,
00823 p_sys->p_context->width,
00824 p_sys->p_context->height );
00825 break;
00826 default:
00827 msg_Err( p_dec, "don't know how to convert chroma %i",
00828 p_sys->p_context->pix_fmt );
00829 p_dec->b_error = 1;
00830 break;
00831 }
00832 }
00833 }
00834
00835
00836
00837
00838
00839
00840
00841 static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
00842 AVFrame *p_ff_pic )
00843 {
00844 decoder_t *p_dec = (decoder_t *)p_context->opaque;
00845 decoder_sys_t *p_sys = p_dec->p_sys;
00846 picture_t *p_pic;
00847
00848
00849 if( p_sys->input_pts )
00850 {
00851 p_ff_pic->pts = p_sys->input_pts;
00852 }
00853 else if( p_sys->input_dts )
00854 {
00855
00856
00857 if( !p_context->has_b_frames || !p_sys->b_has_b_frames ||
00858 !p_ff_pic->reference || !p_sys->i_pts )
00859 {
00860 p_ff_pic->pts = p_sys->input_dts;
00861 }
00862 else p_ff_pic->pts = 0;
00863 }
00864 else p_ff_pic->pts = 0;
00865
00866 if( p_sys->i_pts )
00867 {
00868 p_sys->input_pts = p_sys->input_dts = 0;
00869 }
00870
00871 p_ff_pic->opaque = 0;
00872
00873
00874 if( !p_sys->b_direct_rendering || p_sys->b_pp )
00875 {
00876 return avcodec_default_get_buffer( p_context, p_ff_pic );
00877 }
00878
00879
00880
00881 if( !ffmpeg_PixFmtToChroma( p_context->pix_fmt ) ||
00882 p_sys->p_context->width % 16 || p_sys->p_context->height % 16 )
00883 {
00884 msg_Dbg( p_dec, "disabling direct rendering" );
00885 p_sys->b_direct_rendering = 0;
00886 return avcodec_default_get_buffer( p_context, p_ff_pic );
00887 }
00888
00889
00890
00891 p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
00892 if( !p_pic )
00893 {
00894 p_sys->b_direct_rendering = 0;
00895 return avcodec_default_get_buffer( p_context, p_ff_pic );
00896 }
00897 p_sys->p_context->draw_horiz_band = NULL;
00898
00899 p_ff_pic->opaque = (void*)p_pic;
00900 p_ff_pic->type = FF_BUFFER_TYPE_USER;
00901 p_ff_pic->data[0] = p_pic->p[0].p_pixels;
00902 p_ff_pic->data[1] = p_pic->p[1].p_pixels;
00903 p_ff_pic->data[2] = p_pic->p[2].p_pixels;
00904 p_ff_pic->data[3] = NULL;
00905
00906 p_ff_pic->linesize[0] = p_pic->p[0].i_pitch;
00907 p_ff_pic->linesize[1] = p_pic->p[1].i_pitch;
00908 p_ff_pic->linesize[2] = p_pic->p[2].i_pitch;
00909 p_ff_pic->linesize[3] = 0;
00910
00911 if( p_ff_pic->reference != 0 )
00912 {
00913 p_dec->pf_picture_link( p_dec, p_pic );
00914 }
00915
00916
00917 p_ff_pic->age = 256*256*256*64;
00918
00919 return 0;
00920 }
00921
00922 static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
00923 AVFrame *p_ff_pic )
00924 {
00925 decoder_t *p_dec = (decoder_t *)p_context->opaque;
00926 picture_t *p_pic;
00927
00928 if( !p_ff_pic->opaque )
00929 {
00930 avcodec_default_release_buffer( p_context, p_ff_pic );
00931 return;
00932 }
00933
00934 p_pic = (picture_t*)p_ff_pic->opaque;
00935
00936 p_ff_pic->data[0] = NULL;
00937 p_ff_pic->data[1] = NULL;
00938 p_ff_pic->data[2] = NULL;
00939 p_ff_pic->data[3] = NULL;
00940
00941 if( p_ff_pic->reference != 0 )
00942 {
00943 p_dec->pf_picture_unlink( p_dec, p_pic );
00944 }
00945 }