1 /*****************************************************************************
2 * video.c: video decoder using the ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2001 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Gildas Bazin <gbazin@videolan.org>
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_codec.h>
34 #include <vlc_avcodec.h>
39 #ifdef HAVE_LIBAVCODEC_AVCODEC_H
40 # include <libavcodec/avcodec.h>
41 # ifdef HAVE_AVCODEC_VAAPI
42 # include <libavcodec/vaapi.h>
44 # ifdef HAVE_AVCODEC_DXVA2
45 # include <libavcodec/dxva2.h>
47 #elif defined(HAVE_FFMPEG_AVCODEC_H)
48 # include <ffmpeg/avcodec.h>
55 #if defined(HAVE_AVCODEC_VAAPI) || defined(HAVE_AVCODEC_DXVA2)
56 # define HAVE_AVCODEC_VA
58 #if defined(FF_THREAD_FRAME)
59 # define HAVE_AVCODEC_MT
62 /*****************************************************************************
63 * decoder_sys_t : decoder descriptor
64 *****************************************************************************/
69 /* Video decoder specific part */
74 /* for frame skipping algo */
76 enum AVDiscard i_skip_frame
;
77 enum AVDiscard i_skip_idct
;
79 /* how many decoded frames are late */
81 mtime_t i_late_frames_start
;
83 /* for direct rendering */
84 bool b_direct_rendering
;
85 int i_direct_rendering_used
;
89 /* Hack to force display of still pictures */
93 AVPaletteControl palette
;
104 #ifdef HAVE_AVCODEC_MT
105 # define wait_mt(s) vlc_sem_wait( &s->sem_mt )
106 # define post_mt(s) vlc_sem_post( &s->sem_mt )
112 /* FIXME (dummy palette for now) */
113 static const AVPaletteControl palette_control
;
115 /*****************************************************************************
117 *****************************************************************************/
118 static void ffmpeg_InitCodec ( decoder_t
* );
119 static void ffmpeg_CopyPicture ( decoder_t
*, picture_t
*, AVFrame
* );
120 static int ffmpeg_GetFrameBuf ( struct AVCodecContext
*, AVFrame
* );
121 static int ffmpeg_ReGetFrameBuf( struct AVCodecContext
*, AVFrame
* );
122 static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext
*, AVFrame
* );
124 #ifdef HAVE_AVCODEC_VA
125 static enum PixelFormat
ffmpeg_GetFormat( AVCodecContext
*,
126 const enum PixelFormat
* );
129 static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc
)
131 uint8_t *p
= (uint8_t*)&fcc
;
132 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
135 /*****************************************************************************
137 *****************************************************************************/
139 /* Returns a new picture buffer */
140 static inline picture_t
*ffmpeg_NewPictBuf( decoder_t
*p_dec
,
141 AVCodecContext
*p_context
)
143 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
145 p_dec
->fmt_out
.video
.i_width
= p_context
->width
;
146 p_dec
->fmt_out
.video
.i_height
= p_context
->height
;
148 if( !p_context
->width
|| !p_context
->height
)
150 return NULL
; /* invalid display size */
153 if( !p_sys
->p_va
&& GetVlcChroma( &p_dec
->fmt_out
.video
, p_context
->pix_fmt
) )
155 /* we are doomed, but not really, because most codecs set their pix_fmt
157 * FIXME does it make sense here ? */
158 p_dec
->fmt_out
.video
.i_chroma
= VLC_CODEC_I420
;
160 p_dec
->fmt_out
.i_codec
= p_dec
->fmt_out
.video
.i_chroma
;
162 /* If an aspect-ratio was specified in the input format then force it */
163 if( p_dec
->fmt_in
.video
.i_sar_num
> 0 && p_dec
->fmt_in
.video
.i_sar_den
> 0 )
165 p_dec
->fmt_out
.video
.i_sar_num
= p_dec
->fmt_in
.video
.i_sar_num
;
166 p_dec
->fmt_out
.video
.i_sar_den
= p_dec
->fmt_in
.video
.i_sar_den
;
170 p_dec
->fmt_out
.video
.i_sar_num
= p_context
->sample_aspect_ratio
.num
;
171 p_dec
->fmt_out
.video
.i_sar_den
= p_context
->sample_aspect_ratio
.den
;
173 if( !p_dec
->fmt_out
.video
.i_sar_num
|| !p_dec
->fmt_out
.video
.i_sar_den
)
175 p_dec
->fmt_out
.video
.i_sar_num
= 1;
176 p_dec
->fmt_out
.video
.i_sar_den
= 1;
180 if( p_dec
->fmt_in
.video
.i_frame_rate
> 0 &&
181 p_dec
->fmt_in
.video
.i_frame_rate_base
> 0 )
183 p_dec
->fmt_out
.video
.i_frame_rate
=
184 p_dec
->fmt_in
.video
.i_frame_rate
;
185 p_dec
->fmt_out
.video
.i_frame_rate_base
=
186 p_dec
->fmt_in
.video
.i_frame_rate_base
;
188 else if( p_context
->time_base
.num
> 0 && p_context
->time_base
.den
> 0 )
190 p_dec
->fmt_out
.video
.i_frame_rate
= p_context
->time_base
.den
;
191 p_dec
->fmt_out
.video
.i_frame_rate_base
= p_context
->time_base
.num
;
194 return decoder_NewPicture( p_dec
);
197 /*****************************************************************************
198 * InitVideo: initialize the video decoder
199 *****************************************************************************
200 * the ffmpeg codec will be opened, some memory allocated. The vout is not yet
201 * opened (done after the first decoded frame).
202 *****************************************************************************/
203 int InitVideoDec( decoder_t
*p_dec
, AVCodecContext
*p_context
,
204 AVCodec
*p_codec
, int i_codec_id
, const char *psz_namecodec
)
206 decoder_sys_t
*p_sys
;
209 /* Allocate the memory needed to store the decoder's structure */
210 if( ( p_dec
->p_sys
= p_sys
= calloc( 1, sizeof(decoder_sys_t
) ) ) == NULL
)
213 p_codec
->type
= CODEC_TYPE_VIDEO
;
214 p_context
->codec_type
= CODEC_TYPE_VIDEO
;
215 p_context
->codec_id
= i_codec_id
;
216 p_sys
->p_context
= p_context
;
217 p_sys
->p_codec
= p_codec
;
218 p_sys
->i_codec_id
= i_codec_id
;
219 p_sys
->psz_namecodec
= psz_namecodec
;
220 p_sys
->p_ff_pic
= avcodec_alloc_frame();
221 p_sys
->b_delayed_open
= true;
223 vlc_sem_init( &p_sys
->sem_mt
, 0 );
225 /* ***** Fill p_context with init values ***** */
226 p_sys
->p_context
->codec_tag
= ffmpeg_CodecTag( p_dec
->fmt_in
.i_original_fourcc
?: p_dec
->fmt_in
.i_codec
);
228 /* ***** Get configuration of ffmpeg plugin ***** */
229 p_sys
->p_context
->workaround_bugs
=
230 var_InheritInteger( p_dec
, "ffmpeg-workaround-bugs" );
231 p_sys
->p_context
->error_recognition
=
232 var_InheritInteger( p_dec
, "ffmpeg-error-resilience" );
234 if( var_CreateGetBool( p_dec
, "grayscale" ) )
235 p_sys
->p_context
->flags
|= CODEC_FLAG_GRAY
;
237 i_val
= var_CreateGetInteger( p_dec
, "ffmpeg-vismv" );
238 if( i_val
) p_sys
->p_context
->debug_mv
= i_val
;
240 i_val
= var_CreateGetInteger( p_dec
, "ffmpeg-lowres" );
241 if( i_val
> 0 && i_val
<= 2 ) p_sys
->p_context
->lowres
= i_val
;
243 i_val
= var_CreateGetInteger( p_dec
, "ffmpeg-skiploopfilter" );
244 if( i_val
>= 4 ) p_sys
->p_context
->skip_loop_filter
= AVDISCARD_ALL
;
245 else if( i_val
== 3 ) p_sys
->p_context
->skip_loop_filter
= AVDISCARD_NONKEY
;
246 else if( i_val
== 2 ) p_sys
->p_context
->skip_loop_filter
= AVDISCARD_BIDIR
;
247 else if( i_val
== 1 ) p_sys
->p_context
->skip_loop_filter
= AVDISCARD_NONREF
;
249 if( var_CreateGetBool( p_dec
, "ffmpeg-fast" ) )
250 p_sys
->p_context
->flags2
|= CODEC_FLAG2_FAST
;
252 /* ***** ffmpeg frame skipping ***** */
253 p_sys
->b_hurry_up
= var_CreateGetBool( p_dec
, "ffmpeg-hurry-up" );
255 switch( var_CreateGetInteger( p_dec
, "ffmpeg-skip-frame" ) )
258 p_sys
->p_context
->skip_frame
= AVDISCARD_NONE
;
261 p_sys
->p_context
->skip_frame
= AVDISCARD_DEFAULT
;
264 p_sys
->p_context
->skip_frame
= AVDISCARD_BIDIR
;
267 p_sys
->p_context
->skip_frame
= AVDISCARD_NONKEY
;
270 p_sys
->p_context
->skip_frame
= AVDISCARD_ALL
;
273 p_sys
->p_context
->skip_frame
= AVDISCARD_NONE
;
276 p_sys
->i_skip_frame
= p_sys
->p_context
->skip_frame
;
278 switch( var_CreateGetInteger( p_dec
, "ffmpeg-skip-idct" ) )
281 p_sys
->p_context
->skip_idct
= AVDISCARD_NONE
;
284 p_sys
->p_context
->skip_idct
= AVDISCARD_DEFAULT
;
287 p_sys
->p_context
->skip_idct
= AVDISCARD_BIDIR
;
290 p_sys
->p_context
->skip_idct
= AVDISCARD_NONKEY
;
293 p_sys
->p_context
->skip_idct
= AVDISCARD_ALL
;
296 p_sys
->p_context
->skip_idct
= AVDISCARD_NONE
;
299 p_sys
->i_skip_idct
= p_sys
->p_context
->skip_idct
;
301 /* ***** ffmpeg direct rendering ***** */
302 p_sys
->b_direct_rendering
= false;
303 p_sys
->i_direct_rendering_used
= -1;
304 if( var_CreateGetBool( p_dec
, "ffmpeg-dr" ) &&
305 (p_sys
->p_codec
->capabilities
& CODEC_CAP_DR1
) &&
306 /* No idea why ... but this fixes flickering on some TSCC streams */
307 p_sys
->i_codec_id
!= CODEC_ID_TSCC
&&
308 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 52, 68, 2 )
309 /* avcodec native vp8 decode doesn't handle EMU_EDGE flag, and I
310 don't have idea howto implement fallback to libvpx decoder */
311 p_sys
->i_codec_id
!= CODEC_ID_VP8
&&
313 !p_sys
->p_context
->debug_mv
)
315 /* Some codecs set pix_fmt only after the 1st frame has been decoded,
316 * so we need to do another check in ffmpeg_GetFrameBuf() */
317 p_sys
->b_direct_rendering
= true;
320 /* ffmpeg doesn't properly release old pictures when frames are skipped */
321 //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false;
322 if( p_sys
->b_direct_rendering
)
324 msg_Dbg( p_dec
, "trying to use direct rendering" );
325 p_sys
->p_context
->flags
|= CODEC_FLAG_EMU_EDGE
;
329 msg_Dbg( p_dec
, "direct rendering is disabled" );
332 /* Always use our get_buffer wrapper so we can calculate the
334 p_sys
->p_context
->get_buffer
= ffmpeg_GetFrameBuf
;
335 p_sys
->p_context
->reget_buffer
= ffmpeg_ReGetFrameBuf
;
336 p_sys
->p_context
->release_buffer
= ffmpeg_ReleaseFrameBuf
;
337 p_sys
->p_context
->opaque
= p_dec
;
339 #ifdef HAVE_AVCODEC_MT
340 int i_thread_count
= var_InheritInteger( p_dec
, "ffmpeg-threads" );
341 if( i_thread_count
<= 0 )
342 i_thread_count
= vlc_GetCPUCount();
343 msg_Dbg( p_dec
, "allowing %d thread(s) for decoding", i_thread_count
);
344 p_sys
->p_context
->thread_count
= i_thread_count
;
347 #ifdef HAVE_AVCODEC_VA
348 const bool b_use_hw
= var_CreateGetBool( p_dec
, "ffmpeg-hw" );
351 #ifdef HAVE_AVCODEC_MT
352 msg_Err( p_dec
, "ffmpeg-hw is not compatible with ffmpeg-mt" );
354 p_sys
->p_context
->get_format
= ffmpeg_GetFormat
;
359 /* ***** misc init ***** */
360 p_sys
->i_pts
= VLC_TS_INVALID
;
361 p_sys
->b_has_b_frames
= false;
362 p_sys
->b_first_frame
= true;
363 p_sys
->b_flush
= false;
364 p_sys
->i_late_frames
= 0;
366 /* Set output properties */
367 p_dec
->fmt_out
.i_cat
= VIDEO_ES
;
368 if( GetVlcChroma( &p_dec
->fmt_out
.video
, p_context
->pix_fmt
) != VLC_SUCCESS
)
370 /* we are doomed. but not really, because most codecs set their pix_fmt later on */
371 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I420
;
373 p_dec
->fmt_out
.i_codec
= p_dec
->fmt_out
.video
.i_chroma
;
376 memset( &p_sys
->palette
, 0, sizeof(p_sys
->palette
) );
377 if( p_dec
->fmt_in
.video
.p_palette
)
379 p_sys
->palette
.palette_changed
= 1;
381 for( int i
= 0; i
< __MIN( AVPALETTE_COUNT
, p_dec
->fmt_in
.video
.p_palette
->i_entries
); i
++ )
387 c
.a
[0] = p_dec
->fmt_in
.video
.p_palette
->palette
[i
][0];
388 c
.a
[1] = p_dec
->fmt_in
.video
.p_palette
->palette
[i
][1];
389 c
.a
[2] = p_dec
->fmt_in
.video
.p_palette
->palette
[i
][2];
390 c
.a
[3] = p_dec
->fmt_in
.video
.p_palette
->palette
[i
][3];
392 p_sys
->palette
.palette
[i
] = c
.u
;
394 p_sys
->p_context
->palctrl
= &p_sys
->palette
;
396 p_dec
->fmt_out
.video
.p_palette
= malloc( sizeof(video_palette_t
) );
397 if( p_dec
->fmt_out
.video
.p_palette
)
398 *p_dec
->fmt_out
.video
.p_palette
= *p_dec
->fmt_in
.video
.p_palette
;
400 else if( p_sys
->i_codec_id
!= CODEC_ID_MSVIDEO1
&& p_sys
->i_codec_id
!= CODEC_ID_CINEPAK
)
402 p_sys
->p_context
->palctrl
= &p_sys
->palette
;
405 /* ***** init this codec with special data ***** */
406 ffmpeg_InitCodec( p_dec
);
408 /* ***** Open the codec ***** */
409 if( ffmpeg_OpenCodec( p_dec
) < 0 )
411 msg_Err( p_dec
, "cannot open codec (%s)", p_sys
->psz_namecodec
);
412 av_free( p_sys
->p_ff_pic
);
413 vlc_sem_destroy( &p_sys
->sem_mt
);
421 /*****************************************************************************
422 * DecodeVideo: Called to decode one or more frames
423 *****************************************************************************/
424 picture_t
*DecodeVideo( decoder_t
*p_dec
, block_t
**pp_block
)
426 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
427 AVCodecContext
*p_context
= p_sys
->p_context
;
429 int b_null_size
= false;
432 if( !pp_block
|| !*pp_block
)
435 if( !p_context
->extradata_size
&& p_dec
->fmt_in
.i_extra
)
437 ffmpeg_InitCodec( p_dec
);
438 if( p_sys
->b_delayed_open
)
440 if( ffmpeg_OpenCodec( p_dec
) )
441 msg_Err( p_dec
, "cannot open codec (%s)", p_sys
->psz_namecodec
);
446 if( p_sys
->b_delayed_open
)
448 block_Release( p_block
);
452 if( p_block
->i_flags
& (BLOCK_FLAG_DISCONTINUITY
|BLOCK_FLAG_CORRUPTED
) )
454 p_sys
->i_pts
= VLC_TS_INVALID
; /* To make sure we recover properly */
456 p_sys
->i_late_frames
= 0;
458 if( p_block
->i_flags
& BLOCK_FLAG_DISCONTINUITY
)
459 avcodec_flush_buffers( p_context
);
461 block_Release( p_block
);
465 if( p_block
->i_flags
& BLOCK_FLAG_PREROLL
)
467 /* Do not care about late frames when prerolling
468 * TODO avoid decoding of non reference frame
469 * (ie all B except for H264 where it depends only on nal_ref_idc) */
470 p_sys
->i_late_frames
= 0;
473 if( !p_dec
->b_pace_control
&& (p_sys
->i_late_frames
> 0) &&
474 (mdate() - p_sys
->i_late_frames_start
> INT64_C(5000000)) )
476 if( p_sys
->i_pts
> VLC_TS_INVALID
)
478 msg_Err( p_dec
, "more than 5 seconds of late video -> "
479 "dropping frame (computer too slow ?)" );
480 p_sys
->i_pts
= VLC_TS_INVALID
; /* To make sure we recover properly */
482 block_Release( p_block
);
483 p_sys
->i_late_frames
--;
487 /* A good idea could be to decode all I pictures and see for the other */
488 if( !p_dec
->b_pace_control
&&
490 (p_sys
->i_late_frames
> 4) )
493 if( p_sys
->i_late_frames
< 12 )
495 p_context
->skip_frame
=
496 (p_sys
->i_skip_frame
<= AVDISCARD_BIDIR
) ?
497 AVDISCARD_BIDIR
: p_sys
->i_skip_frame
;
501 /* picture too late, won't decode
502 * but break picture until a new I, and for mpeg4 ...*/
503 p_sys
->i_late_frames
--; /* needed else it will never be decrease */
504 block_Release( p_block
);
510 if( p_sys
->b_hurry_up
)
511 p_context
->skip_frame
= p_sys
->i_skip_frame
;
512 if( !(p_block
->i_flags
& BLOCK_FLAG_PREROLL
) )
518 if( p_context
->width
<= 0 || p_context
->height
<= 0 )
520 if( p_sys
->b_hurry_up
)
521 p_context
->skip_frame
= p_sys
->i_skip_frame
;
524 else if( !b_drawpicture
)
526 /* It creates broken picture
527 * FIXME either our parser or ffmpeg is broken */
529 if( p_sys
->b_hurry_up
)
530 p_context
->skip_frame
= __MAX( p_context
->skip_frame
,
536 * Do the actual decoding now */
538 /* Don't forget that ffmpeg requires a little more bytes
539 * that the real frame size */
540 if( p_block
->i_buffer
> 0 )
542 p_sys
->b_flush
= ( p_block
->i_flags
& BLOCK_FLAG_END_OF_SEQUENCE
) != 0;
544 p_block
= block_Realloc( p_block
, 0,
545 p_block
->i_buffer
+ FF_INPUT_BUFFER_PADDING_SIZE
);
548 p_block
->i_buffer
-= FF_INPUT_BUFFER_PADDING_SIZE
;
550 memset( p_block
->p_buffer
+ p_block
->i_buffer
, 0,
551 FF_INPUT_BUFFER_PADDING_SIZE
);
554 while( p_block
->i_buffer
> 0 || p_sys
->b_flush
)
556 int i_used
, b_gotpicture
;
559 /* Set the PTS/DTS in the context reordered_opaque field */
560 if( p_block
->i_pts
> VLC_TS_INVALID
)
561 p_context
->reordered_opaque
= (p_block
->i_pts
<< 1) | 0;
562 else if( p_block
->i_dts
> VLC_TS_INVALID
)
563 p_context
->reordered_opaque
= (p_block
->i_dts
<< 1) | 1;
565 p_context
->reordered_opaque
= INT64_MIN
;
566 p_sys
->p_ff_pic
->reordered_opaque
= p_context
->reordered_opaque
;
568 /* Make sure we don't reuse the same timestamps twice */
570 p_block
->i_dts
= VLC_TS_INVALID
;
574 i_used
= avcodec_decode_video( p_context
, p_sys
->p_ff_pic
,
576 p_block
->i_buffer
<= 0 && p_sys
->b_flush
? NULL
: p_block
->p_buffer
, p_block
->i_buffer
);
578 if( b_null_size
&& !p_sys
->b_flush
&&
579 p_context
->width
> 0 && p_context
->height
> 0 )
581 /* Reparse it to not drop the I frame */
583 if( p_sys
->b_hurry_up
)
584 p_context
->skip_frame
= p_sys
->i_skip_frame
;
585 i_used
= avcodec_decode_video( p_context
, p_sys
->p_ff_pic
,
586 &b_gotpicture
, p_block
->p_buffer
,
592 p_sys
->b_first_frame
= true;
594 if( p_block
->i_buffer
<= 0 )
595 p_sys
->b_flush
= false;
600 msg_Warn( p_dec
, "cannot decode one frame (%zu bytes)",
602 block_Release( p_block
);
605 else if( i_used
> p_block
->i_buffer
||
606 p_context
->thread_count
> 1 )
608 i_used
= p_block
->i_buffer
;
612 p_block
->i_buffer
-= i_used
;
613 p_block
->p_buffer
+= i_used
;
615 /* Nothing to display */
618 if( i_used
== 0 ) break;
622 /* Sanity check (seems to be needed for some streams) */
623 if( p_sys
->p_ff_pic
->pict_type
== FF_B_TYPE
)
625 p_sys
->b_has_b_frames
= true;
628 /* Compute the PTS */
629 mtime_t i_pts
= VLC_TS_INVALID
;
630 if( p_sys
->p_ff_pic
->reordered_opaque
!= INT64_MIN
)
632 mtime_t i_ts
= p_sys
->p_ff_pic
->reordered_opaque
>> 1;
633 bool b_dts
= p_sys
->p_ff_pic
->reordered_opaque
& 1;
636 if( !p_context
->has_b_frames
||
637 !p_sys
->b_has_b_frames
||
638 !p_sys
->p_ff_pic
->reference
||
639 p_sys
->i_pts
<= VLC_TS_INVALID
)
642 /* Guess what ? The rules are different for Real Video :( */
643 if( (p_dec
->fmt_in
.i_codec
== VLC_CODEC_RV30
||
644 p_dec
->fmt_in
.i_codec
== VLC_CODEC_RV40
) &&
645 p_sys
->b_has_b_frames
)
647 i_pts
= VLC_TS_INVALID
;
648 if(p_sys
->p_ff_pic
->reference
) i_pts
= i_ts
;
656 if( i_pts
<= VLC_TS_INVALID
)
657 i_pts
= p_sys
->i_pts
;
659 /* Interpolate the next PTS */
660 if( i_pts
> VLC_TS_INVALID
)
661 p_sys
->i_pts
= i_pts
;
662 if( p_sys
->i_pts
> VLC_TS_INVALID
)
664 /* interpolate the next PTS */
665 if( p_dec
->fmt_in
.video
.i_frame_rate
> 0 &&
666 p_dec
->fmt_in
.video
.i_frame_rate_base
> 0 )
668 p_sys
->i_pts
+= INT64_C(1000000) *
669 (2 + p_sys
->p_ff_pic
->repeat_pict
) *
670 p_dec
->fmt_in
.video
.i_frame_rate_base
/
671 (2 * p_dec
->fmt_in
.video
.i_frame_rate
);
673 else if( p_context
->time_base
.den
> 0 )
675 int i_tick
= p_context
->ticks_per_frame
;
679 p_sys
->i_pts
+= INT64_C(1000000) *
680 (2 + p_sys
->p_ff_pic
->repeat_pict
) *
681 i_tick
* p_context
->time_base
.num
/
682 (2 * p_context
->time_base
.den
);
686 /* Update frame late count (except when doing preroll) */
687 mtime_t i_display_date
= 0;
688 if( !(p_block
->i_flags
& BLOCK_FLAG_PREROLL
) )
689 i_display_date
= decoder_GetDisplayDate( p_dec
, i_pts
);
691 if( i_display_date
> 0 && i_display_date
<= mdate() )
693 p_sys
->i_late_frames
++;
694 if( p_sys
->i_late_frames
== 1 )
695 p_sys
->i_late_frames_start
= mdate();
699 p_sys
->i_late_frames
= 0;
702 if( !b_drawpicture
|| ( !p_sys
->p_va
&& !p_sys
->p_ff_pic
->linesize
[0] ) )
705 if( !p_sys
->p_ff_pic
->opaque
)
707 /* Get a new picture */
708 p_pic
= ffmpeg_NewPictBuf( p_dec
, p_context
);
711 block_Release( p_block
);
715 /* Fill p_picture_t from AVVideoFrame and do chroma conversion
717 ffmpeg_CopyPicture( p_dec
, p_pic
, p_sys
->p_ff_pic
);
721 p_pic
= (picture_t
*)p_sys
->p_ff_pic
->opaque
;
722 decoder_LinkPicture( p_dec
, p_pic
);
725 if( !p_dec
->fmt_in
.video
.i_sar_num
|| !p_dec
->fmt_in
.video
.i_sar_den
)
727 /* Fetch again the aspect ratio in case it changed */
728 p_dec
->fmt_out
.video
.i_sar_num
729 = p_context
->sample_aspect_ratio
.num
;
730 p_dec
->fmt_out
.video
.i_sar_den
731 = p_context
->sample_aspect_ratio
.den
;
733 if( !p_dec
->fmt_out
.video
.i_sar_num
|| !p_dec
->fmt_out
.video
.i_sar_den
)
735 p_dec
->fmt_out
.video
.i_sar_num
= 1;
736 p_dec
->fmt_out
.video
.i_sar_den
= 1;
740 /* Send decoded frame to vout */
741 if( i_pts
> VLC_TS_INVALID
)
745 if( p_sys
->b_first_frame
)
747 /* Hack to force display of still pictures */
748 p_sys
->b_first_frame
= false;
749 p_pic
->b_force
= true;
752 p_pic
->i_nb_fields
= 2 + p_sys
->p_ff_pic
->repeat_pict
;
753 p_pic
->b_progressive
= !p_sys
->p_ff_pic
->interlaced_frame
;
754 p_pic
->b_top_field_first
= p_sys
->p_ff_pic
->top_field_first
;
756 p_pic
->i_qstride
= p_sys
->p_ff_pic
->qstride
;
757 int i_mb_h
= ( p_pic
->format
.i_height
+ 15 ) / 16;
758 p_pic
->p_q
= malloc( p_pic
->i_qstride
* i_mb_h
);
759 memcpy( p_pic
->p_q
, p_sys
->p_ff_pic
->qscale_table
,
760 p_pic
->i_qstride
* i_mb_h
);
761 switch( p_sys
->p_ff_pic
->qscale_type
)
763 case FF_QSCALE_TYPE_MPEG1
:
764 p_pic
->i_qtype
= QTYPE_MPEG1
;
766 case FF_QSCALE_TYPE_MPEG2
:
767 p_pic
->i_qtype
= QTYPE_MPEG2
;
769 case FF_QSCALE_TYPE_H264
:
770 p_pic
->i_qtype
= QTYPE_H264
;
778 decoder_DeletePicture( p_dec
, p_pic
);
782 block_Release( p_block
);
786 /*****************************************************************************
787 * EndVideo: decoder destruction
788 *****************************************************************************
789 * This function is called when the thread ends after a successful
791 *****************************************************************************/
792 void EndVideoDec( decoder_t
*p_dec
)
794 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
798 /* do not flush buffers if codec hasn't been opened (theora/vorbis/VC1) */
799 if( p_sys
->p_context
->codec
)
800 avcodec_flush_buffers( p_sys
->p_context
);
804 if( p_sys
->p_ff_pic
) av_free( p_sys
->p_ff_pic
);
808 vlc_va_Delete( p_sys
->p_va
);
811 vlc_sem_destroy( &p_sys
->sem_mt
);
814 /*****************************************************************************
815 * ffmpeg_InitCodec: setup codec extra initialization data for ffmpeg
816 *****************************************************************************/
817 static void ffmpeg_InitCodec( decoder_t
*p_dec
)
819 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
820 int i_size
= p_dec
->fmt_in
.i_extra
;
822 if( !i_size
) return;
824 if( p_sys
->i_codec_id
== CODEC_ID_SVQ3
)
828 p_sys
->p_context
->extradata_size
= i_size
+ 12;
829 p
= p_sys
->p_context
->extradata
=
830 malloc( p_sys
->p_context
->extradata_size
);
834 memcpy( &p
[0], "SVQ3", 4 );
835 memset( &p
[4], 0, 8 );
836 memcpy( &p
[12], p_dec
->fmt_in
.p_extra
, i_size
);
838 /* Now remove all atoms before the SMI one */
839 if( p_sys
->p_context
->extradata_size
> 0x5a &&
840 strncmp( (char*)&p
[0x56], "SMI ", 4 ) )
842 uint8_t *psz
= &p
[0x52];
844 while( psz
< &p
[p_sys
->p_context
->extradata_size
- 8] )
846 int i_size
= GetDWBE( psz
);
849 /* FIXME handle 1 as long size */
852 if( !strncmp( (char*)&psz
[4], "SMI ", 4 ) )
854 memmove( &p
[0x52], psz
,
855 &p
[p_sys
->p_context
->extradata_size
] - psz
);
865 p_sys
->p_context
->extradata_size
= i_size
;
866 p_sys
->p_context
->extradata
=
867 malloc( i_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
868 if( p_sys
->p_context
->extradata
)
870 memcpy( p_sys
->p_context
->extradata
,
871 p_dec
->fmt_in
.p_extra
, i_size
);
872 memset( &((uint8_t*)p_sys
->p_context
->extradata
)[i_size
],
873 0, FF_INPUT_BUFFER_PADDING_SIZE
);
878 /*****************************************************************************
879 * ffmpeg_CopyPicture: copy a picture from ffmpeg internal buffers to a
880 * picture_t structure (when not in direct rendering mode).
881 *****************************************************************************/
882 static void ffmpeg_CopyPicture( decoder_t
*p_dec
,
883 picture_t
*p_pic
, AVFrame
*p_ff_pic
)
885 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
889 vlc_va_Extract( p_sys
->p_va
, p_pic
, p_ff_pic
);
891 else if( TestFfmpegChroma( p_sys
->p_context
->pix_fmt
, -1 ) == VLC_SUCCESS
)
893 int i_plane
, i_size
, i_line
;
894 uint8_t *p_dst
, *p_src
;
895 int i_src_stride
, i_dst_stride
;
897 for( i_plane
= 0; i_plane
< p_pic
->i_planes
; i_plane
++ )
899 p_src
= p_ff_pic
->data
[i_plane
];
900 p_dst
= p_pic
->p
[i_plane
].p_pixels
;
901 i_src_stride
= p_ff_pic
->linesize
[i_plane
];
902 i_dst_stride
= p_pic
->p
[i_plane
].i_pitch
;
904 i_size
= __MIN( i_src_stride
, i_dst_stride
);
905 for( i_line
= 0; i_line
< p_pic
->p
[i_plane
].i_visible_lines
;
908 vlc_memcpy( p_dst
, p_src
, i_size
);
909 p_src
+= i_src_stride
;
910 p_dst
+= i_dst_stride
;
916 msg_Err( p_dec
, "don't know how to convert chroma %i",
917 p_sys
->p_context
->pix_fmt
);
922 /*****************************************************************************
923 * ffmpeg_GetFrameBuf: callback used by ffmpeg to get a frame buffer.
924 *****************************************************************************
925 * It is used for direct rendering as well as to get the right PTS for each
926 * decoded picture (even in indirect rendering mode).
927 *****************************************************************************/
928 static int ffmpeg_GetFrameBuf( struct AVCodecContext
*p_context
,
931 decoder_t
*p_dec
= (decoder_t
*)p_context
->opaque
;
932 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
936 p_ff_pic
->reordered_opaque
= p_context
->reordered_opaque
;
937 p_ff_pic
->opaque
= NULL
;
941 #ifdef HAVE_AVCODEC_VA
942 /* hwaccel_context is not present in old fffmpeg version */
943 if( vlc_va_Setup( p_sys
->p_va
,
944 &p_sys
->p_context
->hwaccel_context
, &p_dec
->fmt_out
.video
.i_chroma
,
945 p_sys
->p_context
->width
, p_sys
->p_context
->height
) )
947 msg_Err( p_dec
, "vlc_va_Setup failed" );
955 p_ff_pic
->type
= FF_BUFFER_TYPE_USER
;
956 /* FIXME what is that, should give good value */
957 p_ff_pic
->age
= 256*256*256*64; // FIXME FIXME from ffmpeg
959 if( vlc_va_Get( p_sys
->p_va
, p_ff_pic
) )
961 msg_Err( p_dec
, "VaGrabSurface failed" );
966 else if( !p_sys
->b_direct_rendering
)
968 /* Not much to do in indirect rendering mode. */
969 return avcodec_default_get_buffer( p_context
, p_ff_pic
);
974 /* Some codecs set pix_fmt only after the 1st frame has been decoded,
975 * so we need to check for direct rendering again. */
977 int i_width
= p_sys
->p_context
->width
;
978 int i_height
= p_sys
->p_context
->height
;
979 avcodec_align_dimensions( p_sys
->p_context
, &i_width
, &i_height
);
981 if( GetVlcChroma( &p_dec
->fmt_out
.video
, p_context
->pix_fmt
) != VLC_SUCCESS
||
982 p_context
->pix_fmt
== PIX_FMT_PAL8
)
985 p_dec
->fmt_out
.i_codec
= p_dec
->fmt_out
.video
.i_chroma
;
987 /* Get a new picture */
988 p_pic
= ffmpeg_NewPictBuf( p_dec
, p_sys
->p_context
);
991 bool b_compatible
= true;
992 if( p_pic
->p
[0].i_pitch
/ p_pic
->p
[0].i_pixel_pitch
< i_width
||
993 p_pic
->p
[0].i_lines
< i_height
)
994 b_compatible
= false;
995 for( int i
= 0; i
< p_pic
->i_planes
&& b_compatible
; i
++ )
998 switch( p_sys
->i_codec_id
)
1008 i_align
= i
== 0 ? 16 : 8;
1011 if( p_pic
->p
[i
].i_pitch
% i_align
)
1012 b_compatible
= false;
1013 if( (intptr_t)p_pic
->p
[i
].p_pixels
% i_align
)
1014 b_compatible
= false;
1016 if( p_context
->pix_fmt
== PIX_FMT_YUV422P
&& b_compatible
)
1018 if( 2 * p_pic
->p
[1].i_pitch
!= p_pic
->p
[0].i_pitch
||
1019 2 * p_pic
->p
[2].i_pitch
!= p_pic
->p
[0].i_pitch
)
1020 b_compatible
= false;
1024 decoder_DeletePicture( p_dec
, p_pic
);
1028 if( p_sys
->i_direct_rendering_used
!= 1 )
1030 msg_Dbg( p_dec
, "using direct rendering" );
1031 p_sys
->i_direct_rendering_used
= 1;
1034 p_sys
->p_context
->draw_horiz_band
= NULL
;
1036 p_ff_pic
->opaque
= (void*)p_pic
;
1037 p_ff_pic
->type
= FF_BUFFER_TYPE_USER
;
1038 p_ff_pic
->data
[0] = p_pic
->p
[0].p_pixels
;
1039 p_ff_pic
->data
[1] = p_pic
->p
[1].p_pixels
;
1040 p_ff_pic
->data
[2] = p_pic
->p
[2].p_pixels
;
1041 p_ff_pic
->data
[3] = NULL
; /* alpha channel but I'm not sure */
1043 p_ff_pic
->linesize
[0] = p_pic
->p
[0].i_pitch
;
1044 p_ff_pic
->linesize
[1] = p_pic
->p
[1].i_pitch
;
1045 p_ff_pic
->linesize
[2] = p_pic
->p
[2].i_pitch
;
1046 p_ff_pic
->linesize
[3] = 0;
1048 /* FIXME what is that, should give good value */
1049 p_ff_pic
->age
= 256*256*256*64; // FIXME FIXME from ffmpeg
1055 if( p_sys
->i_direct_rendering_used
!= 0 )
1057 msg_Warn( p_dec
, "disabling direct rendering" );
1058 p_sys
->i_direct_rendering_used
= 0;
1061 return avcodec_default_get_buffer( p_context
, p_ff_pic
);
1063 static int ffmpeg_ReGetFrameBuf( struct AVCodecContext
*p_context
, AVFrame
*p_ff_pic
)
1065 p_ff_pic
->reordered_opaque
= p_context
->reordered_opaque
;
1067 /* We always use default reget function, it works perfectly fine */
1068 return avcodec_default_reget_buffer( p_context
, p_ff_pic
);
1071 static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext
*p_context
,
1074 decoder_t
*p_dec
= (decoder_t
*)p_context
->opaque
;
1075 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
1079 vlc_va_Release( p_sys
->p_va
, p_ff_pic
);
1081 else if( !p_ff_pic
->opaque
)
1083 /* We can end up here without the AVFrame being allocated by
1084 * avcodec_default_get_buffer() if VA is used and the frame is
1085 * released when the decoder is closed
1087 if( p_ff_pic
->type
== FF_BUFFER_TYPE_INTERNAL
)
1088 avcodec_default_release_buffer( p_context
, p_ff_pic
);
1092 picture_t
*p_pic
= (picture_t
*)p_ff_pic
->opaque
;
1094 decoder_UnlinkPicture( p_dec
, p_pic
);
1096 for( int i
= 0; i
< 4; i
++ )
1097 p_ff_pic
->data
[i
] = NULL
;
1100 #ifdef HAVE_AVCODEC_VA
1101 static enum PixelFormat
ffmpeg_GetFormat( AVCodecContext
*p_codec
,
1102 const enum PixelFormat
*pi_fmt
)
1104 decoder_t
*p_dec
= p_codec
->opaque
;
1105 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
1109 vlc_va_Delete( p_sys
->p_va
);
1113 /* Try too look for a supported hw acceleration */
1114 for( int i
= 0; pi_fmt
[i
] != PIX_FMT_NONE
; i
++ )
1116 static const char *ppsz_name
[PIX_FMT_NB
] = {
1117 [PIX_FMT_VDPAU_H264
] = "PIX_FMT_VDPAU_H264",
1118 [PIX_FMT_VAAPI_IDCT
] = "PIX_FMT_VAAPI_IDCT",
1119 [PIX_FMT_VAAPI_VLD
] = "PIX_FMT_VAAPI_VLD",
1120 [PIX_FMT_VAAPI_MOCO
] = "PIX_FMT_VAAPI_MOCO",
1121 #ifdef HAVE_AVCODEC_DXVA2
1122 [PIX_FMT_DXVA2_VLD
] = "PIX_FMT_DXVA2_VLD",
1124 [PIX_FMT_YUYV422
] = "PIX_FMT_YUYV422",
1125 [PIX_FMT_YUV420P
] = "PIX_FMT_YUV420P",
1127 msg_Dbg( p_dec
, "Available decoder output format %d (%s)", pi_fmt
[i
], ppsz_name
[pi_fmt
[i
]] ?: "Unknown" );
1129 /* Only VLD supported */
1130 if( pi_fmt
[i
] == PIX_FMT_VAAPI_VLD
)
1132 if( !var_InheritBool( p_dec
, "xlib" ) )
1134 msg_Warn( p_dec
, "Ignoring VA API" );
1137 #ifdef HAVE_AVCODEC_VAAPI
1138 msg_Dbg( p_dec
, "Trying VA API" );
1139 p_sys
->p_va
= vlc_va_NewVaapi( p_sys
->i_codec_id
);
1141 msg_Warn( p_dec
, "Failed to open VA API" );
1146 #ifdef HAVE_AVCODEC_DXVA2
1147 if( pi_fmt
[i
] == PIX_FMT_DXVA2_VLD
)
1149 msg_Dbg( p_dec
, "Trying DXVA2" );
1150 p_sys
->p_va
= vlc_va_NewDxva2( VLC_OBJECT(p_dec
), p_sys
->i_codec_id
);
1152 msg_Warn( p_dec
, "Failed to open DXVA2" );
1157 p_sys
->p_context
->width
> 0 && p_sys
->p_context
->height
> 0 )
1159 /* We try to call vlc_va_Setup when possible to detect errors when
1160 * possible (later is too late) */
1161 if( vlc_va_Setup( p_sys
->p_va
,
1162 &p_sys
->p_context
->hwaccel_context
,
1163 &p_dec
->fmt_out
.video
.i_chroma
,
1164 p_sys
->p_context
->width
, p_sys
->p_context
->height
) )
1166 msg_Err( p_dec
, "vlc_va_Setup failed" );
1167 vlc_va_Delete( p_sys
->p_va
);
1174 if( p_sys
->p_va
->description
)
1175 msg_Info( p_dec
, "Using %s for hardware decoding.", p_sys
->p_va
->description
);
1177 /* FIXME this will disabled direct rendering
1178 * even if a new pixel format is renegociated
1180 p_sys
->b_direct_rendering
= false;
1181 p_sys
->p_context
->draw_horiz_band
= NULL
;
1186 /* Fallback to default behaviour */
1187 return avcodec_default_get_format( p_codec
, pi_fmt
);