/src/vlc/modules/codec/avcodec/video.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * video.c: video decoder using the libavcodec library |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 1999-2001 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Gildas Bazin <gbazin@videolan.org> |
8 | | * |
9 | | * This program is free software; you can redistribute it and/or modify it |
10 | | * under the terms of the GNU Lesser General Public License as published by |
11 | | * the Free Software Foundation; either version 2.1 of the License, or |
12 | | * (at your option) any later version. |
13 | | * |
14 | | * This program is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | * GNU Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public License |
20 | | * along with this program; if not, write to the Free Software Foundation, |
21 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
22 | | *****************************************************************************/ |
23 | | |
24 | | /***************************************************************************** |
25 | | * Preamble |
26 | | *****************************************************************************/ |
27 | | #ifdef HAVE_CONFIG_H |
28 | | # include "config.h" |
29 | | #endif |
30 | | |
31 | | #include <stdatomic.h> |
32 | | |
33 | | #include <vlc_common.h> |
34 | | #include <vlc_codec.h> |
35 | | #include <vlc_avcodec.h> |
36 | | #include <vlc_cpu.h> |
37 | | #include <vlc_ancillary.h> |
38 | | #include <assert.h> |
39 | | |
40 | | #include <libavcodec/avcodec.h> |
41 | | #include <libavutil/mem.h> |
42 | | #include <libavutil/pixdesc.h> |
43 | | #include <libavutil/mastering_display_metadata.h> |
44 | | |
45 | | #include "avcodec.h" |
46 | | #include "va.h" |
47 | | |
48 | | #if defined(_WIN32) |
49 | | # include <winapifamily.h> |
50 | | #endif |
51 | | |
52 | | #include <libavutil/stereo3d.h> |
53 | | |
54 | | #if LIBAVUTIL_VERSION_CHECK( 57, 16, 100 ) |
55 | | # include <libavutil/dovi_meta.h> |
56 | | #endif |
57 | | |
58 | | #include <libavutil/hdr_dynamic_metadata.h> |
59 | | |
60 | | #include "../../packetizer/av1_obu.h" |
61 | | #include "../../packetizer/av1.h" |
62 | | #include "../cc.h" |
63 | | |
64 | | #define OPAQUE_REF_ONLY LIBAVCODEC_VERSION_CHECK( 59, 63, 100 ) |
65 | | |
66 | | struct frame_info_s |
67 | | { |
68 | | #if OPAQUE_REF_ONLY |
69 | | uint64_t i_sequence_number; |
70 | | #endif |
71 | | bool b_eos; |
72 | | bool b_display; |
73 | | }; |
74 | | |
75 | | /***************************************************************************** |
76 | | * decoder_sys_t : decoder descriptor |
77 | | *****************************************************************************/ |
78 | | typedef struct |
79 | | { |
80 | | AVCodecContext *p_context; |
81 | | const AVCodec *p_codec; |
82 | | |
83 | | /* Video decoder specific part */ |
84 | | date_t pts; /* Protected by lock */ |
85 | | |
86 | | /* Closed captions for decoders */ |
87 | | cc_data_t cc; |
88 | | |
89 | | /* for frame skipping algo */ |
90 | | bool b_hurry_up; |
91 | | bool b_show_corrupted; |
92 | | bool b_from_preroll; |
93 | | bool b_hardware_only; |
94 | | /* Some codecs carry their whole state (image canvas and/or palette) forward |
95 | | * as deltas and have no recoverable keyframes. Never drop frames for those, |
96 | | * regardless of lateness. */ |
97 | | bool b_no_frame_drop; |
98 | | enum AVDiscard i_skip_frame; |
99 | | |
100 | | #if OPAQUE_REF_ONLY |
101 | | uint64_t i_next_sequence_number; |
102 | | #else |
103 | | # define FRAME_INFO_DEPTH 64 |
104 | | struct frame_info_s frame_info[FRAME_INFO_DEPTH]; |
105 | | #endif |
106 | | |
107 | | enum |
108 | | { |
109 | | FRAMEDROP_NONE, |
110 | | FRAMEDROP_NONREF, |
111 | | FRAMEDROP_AGGRESSIVE_RECOVER, |
112 | | } framedrop; |
113 | | /* how many decoded frames are late */ |
114 | | int i_late_frames; |
115 | | int64_t i_last_output_frame; |
116 | | vlc_tick_t i_last_late_delay; |
117 | | |
118 | | /* for direct rendering */ |
119 | | bool b_direct_rendering; |
120 | | bool b_dr_failure; /* Protected by lock */ |
121 | | |
122 | | /* Hack to force display of still pictures */ |
123 | | bool b_first_frame; |
124 | | |
125 | | |
126 | | /* */ |
127 | | bool palette_sent; |
128 | | |
129 | | /* VA API */ |
130 | | vlc_va_t *p_va; |
131 | | enum AVPixelFormat pix_fmt; |
132 | | int profile; |
133 | | int level; |
134 | | vlc_video_context *vctx_out; |
135 | | bool use_hwframes; |
136 | | |
137 | | // decoder output seen by lavc, regardless of texture padding |
138 | | unsigned decoder_width; |
139 | | unsigned decoder_height; |
140 | | |
141 | | /* Protect dec->fmt_out, decoder_Update*() and decoder_NewPicture() |
142 | | * functions from lavc_GetFrame(). ffmpeg_GetFormat() doesn't need locking |
143 | | * as ffmpeg is taking care of the synchronisation. */ |
144 | | vlc_mutex_t lock; |
145 | | } decoder_sys_t; |
146 | | |
147 | | /***************************************************************************** |
148 | | * Local prototypes |
149 | | *****************************************************************************/ |
150 | | static void ffmpeg_InitCodec ( decoder_t * ); |
151 | | static int lavc_GetFrame(struct AVCodecContext *, AVFrame *, int); |
152 | | static enum AVPixelFormat ffmpeg_GetFormat( AVCodecContext *, |
153 | | const enum AVPixelFormat * ); |
154 | | static int DecodeVideo( decoder_t *, block_t * ); |
155 | | static void Flush( decoder_t * ); |
156 | | |
157 | | static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc ) |
158 | 253k | { |
159 | 253k | uint8_t *p = (uint8_t*)&fcc; |
160 | 253k | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); |
161 | 253k | } |
162 | | |
163 | | /* Codecs whose decoder keeps a persistent state (image canvas and/or palette) |
164 | | * updated as deltas from one frame to the next, and which emit keyframes very |
165 | | * rarely. Dropping a frame corrupts all subsequent output until the next |
166 | | * keyframe. |
167 | | */ |
168 | | static bool ffmpeg_CodecForbidsFrameDrop( enum AVCodecID i_codec ) |
169 | 253k | { |
170 | 253k | switch( i_codec ) |
171 | 253k | { |
172 | | /* FIXME: add more as needed */ |
173 | 0 | case AV_CODEC_ID_ZMBV: |
174 | 0 | return true; |
175 | 253k | default: |
176 | 253k | return false; |
177 | 253k | } |
178 | 253k | } |
179 | | |
180 | | /***************************************************************************** |
181 | | * Local Functions |
182 | | *****************************************************************************/ |
183 | | |
184 | | static void FrameInfoInit( decoder_sys_t *p_sys ) |
185 | 253k | { |
186 | 253k | #if OPAQUE_REF_ONLY |
187 | 253k | p_sys->i_next_sequence_number = 0; |
188 | | #else |
189 | | AVCodecContext *p_context = p_sys->p_context; |
190 | | p_context->reordered_opaque = 0; |
191 | | #endif |
192 | 253k | } |
193 | | |
194 | | static struct frame_info_s * FrameInfoGet( decoder_sys_t *p_sys, AVFrame *frame ) |
195 | 85.7k | { |
196 | 85.7k | #if OPAQUE_REF_ONLY |
197 | 85.7k | (void)p_sys; |
198 | | /* There's no pkt to frame opaque mapping guarantee */ |
199 | 85.7k | return (struct frame_info_s *) frame->opaque_ref->data; |
200 | | #else |
201 | | return &p_sys->frame_info[frame->reordered_opaque % FRAME_INFO_DEPTH]; |
202 | | #endif |
203 | 85.7k | } |
204 | | |
205 | | static struct frame_info_s * FrameInfoAdd( decoder_sys_t *p_sys, AVPacket *pkt ) |
206 | 2.63M | { |
207 | 2.63M | #if OPAQUE_REF_ONLY |
208 | 2.63M | AVBufferRef *bufref = av_buffer_allocz(sizeof(struct frame_info_s)); |
209 | 2.63M | if( !bufref ) |
210 | 0 | return NULL; |
211 | 2.63M | pkt->opaque_ref = bufref; |
212 | | |
213 | 2.63M | struct frame_info_s *p_frame_info = (struct frame_info_s *) bufref->data; |
214 | 2.63M | p_frame_info->i_sequence_number = p_sys->i_next_sequence_number++; |
215 | 2.63M | return p_frame_info; |
216 | | #else |
217 | | VLC_UNUSED(pkt); |
218 | | AVCodecContext *p_context = p_sys->p_context; |
219 | | return &p_sys->frame_info[p_context->reordered_opaque++ % FRAME_INFO_DEPTH]; |
220 | | #endif |
221 | 2.63M | } |
222 | | |
223 | | static bool FrameCanStoreInfo( const AVFrame *frame ) |
224 | 0 | { |
225 | 0 | #if OPAQUE_REF_ONLY |
226 | 0 | return !!frame->opaque_ref; |
227 | | #else |
228 | | return true; |
229 | | #endif |
230 | 0 | } |
231 | | |
232 | | static void FrameSetPicture( AVFrame *frame, picture_t *pic ) |
233 | 398k | { |
234 | 398k | frame->opaque = pic; |
235 | 398k | } |
236 | | |
237 | | static picture_t * FrameGetPicture( AVFrame *frame ) |
238 | 85.1k | { |
239 | 85.1k | return frame->opaque; |
240 | 85.1k | } |
241 | | |
242 | | static int64_t NextPktSequenceNumber( decoder_sys_t *p_sys ) |
243 | 0 | { |
244 | 0 | #if OPAQUE_REF_ONLY |
245 | 0 | return p_sys->i_next_sequence_number; |
246 | | #else |
247 | | AVCodecContext *p_context = p_sys->p_context; |
248 | | return p_context->reordered_opaque; |
249 | | #endif |
250 | 0 | } |
251 | | |
252 | | static int64_t FrameSequenceNumber( const AVFrame *frame, const struct frame_info_s *info ) |
253 | 79.3k | { |
254 | 79.3k | #if OPAQUE_REF_ONLY |
255 | 79.3k | VLC_UNUSED(frame); |
256 | 79.3k | return info->i_sequence_number; |
257 | | #else |
258 | | VLC_UNUSED(info); |
259 | | return frame->reordered_opaque; |
260 | | #endif |
261 | 79.3k | } |
262 | | |
263 | | static void lavc_Frame8PaletteCopy( video_palette_t *dst, const uint8_t *src ) |
264 | 326 | { |
265 | | // (A << 24) | (R << 16) | (G << 8) | B |
266 | | // stored in host endianness |
267 | 326 | const uint8_t *srcp = src; |
268 | 83.7k | for(size_t i=0; i<AVPALETTE_COUNT; i++) |
269 | 83.4k | { |
270 | | // we want RGBA byte order storage |
271 | | #ifdef WORDS_BIGENDIAN |
272 | | // AV mem is ARGB in byte order |
273 | | dst->palette[i][0] = srcp[1]; |
274 | | dst->palette[i][1] = srcp[2]; |
275 | | dst->palette[i][2] = srcp[3]; |
276 | | dst->palette[i][3] = srcp[0]; |
277 | | #else |
278 | | // AV mem is BGRA in byte order |
279 | 83.4k | dst->palette[i][0] = srcp[2]; |
280 | 83.4k | dst->palette[i][1] = srcp[1]; |
281 | 83.4k | dst->palette[i][2] = srcp[0]; |
282 | 83.4k | dst->palette[i][3] = srcp[3]; |
283 | 83.4k | #endif |
284 | 83.4k | srcp += sizeof(dst->palette[0]); |
285 | 83.4k | } |
286 | | |
287 | 326 | dst->i_entries = AVPALETTE_COUNT; |
288 | 326 | } |
289 | | |
290 | | /** |
291 | | * Sets the decoder output format. |
292 | | */ |
293 | | static int lavc_GetVideoFormat(decoder_t *dec, video_format_t *restrict fmt, |
294 | | AVCodecContext *ctx, enum AVPixelFormat pix_fmt, |
295 | | enum AVPixelFormat sw_pix_fmt) |
296 | 202k | { |
297 | 202k | int width = ctx->coded_width; |
298 | 202k | int height = ctx->coded_height; |
299 | | |
300 | 202k | video_format_Init(fmt, 0); |
301 | | |
302 | 202k | if (pix_fmt == sw_pix_fmt) |
303 | 202k | { /* software decoding */ |
304 | 202k | int aligns[AV_NUM_DATA_POINTERS]; |
305 | | |
306 | 202k | if (GetVlcChroma(fmt, pix_fmt)) |
307 | 5 | return -1; |
308 | | |
309 | | /* The libavcodec palette can only be fetched when the first output |
310 | | * frame is decoded. Assume that the current chroma is RGB32 while we |
311 | | * are waiting for a valid palette. Indeed, fmt_out.video.p_palette |
312 | | * doesn't trigger a new vout request, but a new chroma yes. */ |
313 | 202k | if (pix_fmt == AV_PIX_FMT_PAL8 && !dec->fmt_out.video.p_palette) |
314 | 73 | fmt->i_chroma = VLC_CODEC_XRGB; |
315 | | |
316 | 202k | avcodec_align_dimensions2(ctx, &width, &height, aligns); |
317 | 202k | } |
318 | | |
319 | 202k | if( width == 0 || height == 0 || width > 8192 || height > 8192 || |
320 | 198k | width < ctx->width || height < ctx->height ) |
321 | 3.46k | { |
322 | 3.46k | msg_Err(dec, "Invalid frame size %dx%d vsz %dx%d", |
323 | 3.46k | width, height, ctx->width, ctx->height ); |
324 | 3.46k | video_format_Clean(fmt); |
325 | 3.46k | return -1; /* invalid display size */ |
326 | 3.46k | } |
327 | | |
328 | 198k | fmt->i_width = width; |
329 | 198k | fmt->i_height = height; |
330 | 198k | if ( dec->fmt_in->video.i_visible_width != 0 && |
331 | 191k | dec->fmt_in->video.i_visible_width <= (unsigned)ctx->width && |
332 | 183k | dec->fmt_in->video.i_visible_height != 0 && |
333 | 180k | dec->fmt_in->video.i_visible_height <= (unsigned)ctx->height ) |
334 | 173k | { |
335 | | /* the demuxer/packetizer provided crop info that are lost in lavc */ |
336 | 173k | fmt->i_visible_width = dec->fmt_in->video.i_visible_width; |
337 | 173k | fmt->i_visible_height = dec->fmt_in->video.i_visible_height; |
338 | 173k | fmt->i_x_offset = dec->fmt_in->video.i_x_offset; |
339 | 173k | fmt->i_y_offset = dec->fmt_in->video.i_y_offset; |
340 | 173k | } |
341 | 25.3k | else |
342 | 25.3k | { |
343 | 25.3k | fmt->i_visible_width = ctx->width; |
344 | 25.3k | fmt->i_visible_height = ctx->height; |
345 | 25.3k | fmt->i_x_offset = 0; |
346 | 25.3k | fmt->i_y_offset = 0; |
347 | 25.3k | } |
348 | | |
349 | | /* If an aspect-ratio was specified in the input format then force it */ |
350 | 198k | if (dec->fmt_in->video.i_sar_num > 0 && dec->fmt_in->video.i_sar_den > 0) |
351 | 109k | { |
352 | 109k | fmt->i_sar_num = dec->fmt_in->video.i_sar_num; |
353 | 109k | fmt->i_sar_den = dec->fmt_in->video.i_sar_den; |
354 | 109k | } |
355 | 89.5k | else |
356 | 89.5k | { |
357 | 89.5k | fmt->i_sar_num = ctx->sample_aspect_ratio.num; |
358 | 89.5k | fmt->i_sar_den = ctx->sample_aspect_ratio.den; |
359 | | |
360 | 89.5k | if (fmt->i_sar_num == 0 || fmt->i_sar_den == 0) |
361 | 56.7k | fmt->i_sar_num = fmt->i_sar_den = 1; |
362 | 89.5k | } |
363 | | |
364 | 198k | if (dec->fmt_in->video.i_frame_rate > 0 |
365 | 182k | && dec->fmt_in->video.i_frame_rate_base > 0) |
366 | 182k | { |
367 | 182k | fmt->i_frame_rate = dec->fmt_in->video.i_frame_rate; |
368 | 182k | fmt->i_frame_rate_base = dec->fmt_in->video.i_frame_rate_base; |
369 | 182k | } |
370 | 16.9k | else if (ctx->framerate.num > 0 && ctx->framerate.den > 0) |
371 | 12.0k | { |
372 | 12.0k | fmt->i_frame_rate = ctx->framerate.num; |
373 | 12.0k | fmt->i_frame_rate_base = ctx->framerate.den; |
374 | 12.0k | } |
375 | 4.85k | else if (ctx->time_base.num > 0 && ctx->time_base.den > 0) |
376 | 0 | { |
377 | 0 | fmt->i_frame_rate = ctx->time_base.den; |
378 | 0 | fmt->i_frame_rate_base = ctx->time_base.num; |
379 | 0 | } |
380 | | |
381 | 198k | get_video_color_settings(ctx, fmt); |
382 | 198k | return 0; |
383 | 202k | } |
384 | | |
385 | | static int lavc_UpdateVideoFormat(decoder_t *dec, AVCodecContext *ctx, |
386 | | enum AVPixelFormat fmt, |
387 | | enum AVPixelFormat swfmt) |
388 | 202k | { |
389 | 202k | video_format_t fmt_out; |
390 | 202k | int val; |
391 | | |
392 | 202k | val = lavc_GetVideoFormat(dec, &fmt_out, ctx, fmt, swfmt); |
393 | 202k | if (val) |
394 | 3.47k | return val; |
395 | | |
396 | 198k | decoder_sys_t *p_sys = dec->p_sys; |
397 | | |
398 | | /* always have date in fields/ticks units */ |
399 | 198k | if(p_sys->pts.i_divider_num) |
400 | 194k | date_Change(&p_sys->pts, fmt_out.i_frame_rate, |
401 | 194k | fmt_out.i_frame_rate_base); |
402 | 4.54k | else |
403 | 4.54k | date_Init(&p_sys->pts, fmt_out.i_frame_rate, |
404 | 4.54k | fmt_out.i_frame_rate_base); |
405 | | |
406 | 198k | fmt_out.p_palette = dec->fmt_out.video.p_palette; |
407 | 198k | dec->fmt_out.video.p_palette = NULL; |
408 | | |
409 | 198k | vlc_fourcc_t i_chroma; |
410 | 198k | if (fmt == swfmt) |
411 | 198k | i_chroma = fmt_out.i_chroma; |
412 | 0 | else |
413 | 0 | i_chroma = 0; |
414 | 198k | es_format_Change(&dec->fmt_out, VIDEO_ES, i_chroma); |
415 | 198k | dec->fmt_out.video = fmt_out; |
416 | 198k | dec->fmt_out.video.i_chroma = i_chroma; |
417 | 198k | dec->fmt_out.video.orientation = dec->fmt_in->video.orientation; |
418 | 198k | dec->fmt_out.video.projection_mode = dec->fmt_in->video.projection_mode; |
419 | 198k | dec->fmt_out.video.multiview_mode = dec->fmt_in->video.multiview_mode; |
420 | 198k | dec->fmt_out.video.pose = dec->fmt_in->video.pose; |
421 | 198k | if ( dec->fmt_in->video.mastering.max_luminance ) |
422 | 1.80k | dec->fmt_out.video.mastering = dec->fmt_in->video.mastering; |
423 | 198k | if ( dec->fmt_in->video.dovi.version_major ) |
424 | 0 | dec->fmt_out.video.dovi = dec->fmt_in->video.dovi; |
425 | 198k | dec->fmt_out.video.lighting = dec->fmt_in->video.lighting; |
426 | 198k | p_sys->decoder_width = dec->fmt_out.video.i_width; |
427 | 198k | p_sys->decoder_height = dec->fmt_out.video.i_height; |
428 | | |
429 | 198k | return 0; |
430 | 202k | } |
431 | | |
432 | | static bool chroma_compatible(const video_format_t *a, const video_format_t *b) |
433 | 993 | { |
434 | 993 | if (a->i_chroma != b->i_chroma) |
435 | 3 | return false; |
436 | | |
437 | 990 | if (a->color_range != b->color_range && a->color_range != COLOR_RANGE_UNDEF) |
438 | 0 | return false; |
439 | | |
440 | 990 | return true; |
441 | 990 | } |
442 | | |
443 | | /** |
444 | | * Copies a picture from the libavcodec-allocate buffer to a picture_t. |
445 | | * This is used when not in direct rendering mode. |
446 | | */ |
447 | | static int lavc_CopyPicture(decoder_t *dec, picture_t *pic, AVFrame *frame) |
448 | 993 | { |
449 | 993 | decoder_sys_t *sys = dec->p_sys; |
450 | | |
451 | 993 | video_format_t test_chroma; |
452 | 993 | video_format_Init(&test_chroma, 0); |
453 | 993 | if (GetVlcChroma(&test_chroma, frame->format) != VLC_SUCCESS) |
454 | 0 | { |
455 | 0 | const char *name = av_get_pix_fmt_name(frame->format); |
456 | |
|
457 | 0 | msg_Err(dec, "Unsupported decoded output format %d (%s)", |
458 | 0 | sys->p_context->pix_fmt, (name != NULL) ? name : "unknown"); |
459 | 0 | return VLC_EGENERIC; |
460 | 993 | } else if (!chroma_compatible(&test_chroma, &pic->format) |
461 | | /* ensure we never read more than dst lines/pixels from src */ |
462 | 990 | || frame->width != (int) pic->format.i_visible_width |
463 | 929 | || frame->height < (int) pic->format.i_visible_height) |
464 | 64 | { |
465 | 64 | msg_Warn(dec, "dropping frame because the vout changed"); |
466 | 64 | return VLC_EGENERIC; |
467 | 64 | } |
468 | | |
469 | 3.11k | for (int plane = 0; plane < pic->i_planes; plane++) |
470 | 2.18k | { |
471 | 2.18k | const uint8_t *src = frame->data[plane]; |
472 | 2.18k | uint8_t *dst = pic->p[plane].p_pixels; |
473 | 2.18k | size_t src_stride = frame->linesize[plane]; |
474 | 2.18k | size_t dst_stride = pic->p[plane].i_pitch; |
475 | 2.18k | size_t size = __MIN(src_stride, dst_stride); |
476 | | |
477 | 257k | for (int line = 0; line < pic->p[plane].i_visible_lines; line++) |
478 | 255k | { |
479 | 255k | memcpy(dst, src, size); |
480 | 255k | src += src_stride; |
481 | 255k | dst += dst_stride; |
482 | 255k | } |
483 | 2.18k | } |
484 | 929 | return VLC_SUCCESS; |
485 | 993 | } |
486 | | |
487 | | static int OpenVideoCodec( decoder_t *p_dec ) |
488 | 253k | { |
489 | 253k | decoder_sys_t *p_sys = p_dec->p_sys; |
490 | 253k | AVCodecContext *ctx = p_sys->p_context; |
491 | 253k | const AVCodec *codec = p_sys->p_codec; |
492 | 253k | int ret; |
493 | | |
494 | 253k | if( ctx->extradata_size <= 0 ) |
495 | 185k | { |
496 | 185k | if( codec->id == AV_CODEC_ID_VC1 || |
497 | 184k | codec->id == AV_CODEC_ID_THEORA ) |
498 | 477 | { |
499 | 477 | msg_Warn( p_dec, "waiting for extra data for codec %s", |
500 | 477 | codec->name ); |
501 | 477 | return 1; |
502 | 477 | } |
503 | 185k | } |
504 | | |
505 | 252k | ctx->width = p_dec->fmt_in->video.i_visible_width; |
506 | 252k | ctx->height = p_dec->fmt_in->video.i_visible_height; |
507 | | |
508 | 252k | if (!ctx->coded_width || !ctx->coded_height) |
509 | 251k | { |
510 | 251k | ctx->coded_width = p_dec->fmt_in->video.i_width; |
511 | 251k | ctx->coded_height = p_dec->fmt_in->video.i_height; |
512 | 251k | } |
513 | | |
514 | 252k | ctx->bits_per_coded_sample = vlc_fourcc_GetChromaBPP(p_dec->fmt_in->video.i_chroma); |
515 | 252k | if ( ctx->bits_per_coded_sample == 0 && |
516 | 252k | p_dec->fmt_in->i_profile == -1 && p_dec->fmt_in->i_level != -1 ) |
517 | | // HACK: the bits per sample was stored in the i_level |
518 | 0 | ctx->bits_per_coded_sample = p_dec->fmt_in->i_level; |
519 | 252k | p_sys->pix_fmt = AV_PIX_FMT_NONE; |
520 | 252k | cc_Init( &p_sys->cc ); |
521 | | |
522 | 252k | set_video_color_settings( &p_dec->fmt_in->video, ctx ); |
523 | 252k | if( var_InheritBool(p_dec, "low-delay") || |
524 | 252k | ( p_dec->fmt_in->video.i_frame_rate_base && |
525 | 107k | p_dec->fmt_in->video.i_frame_rate && |
526 | 104k | (double) p_dec->fmt_in->video.i_frame_rate / |
527 | 104k | p_dec->fmt_in->video.i_frame_rate_base < 6 ) ) |
528 | 56.0k | { |
529 | 56.0k | ctx->flags |= AV_CODEC_FLAG_LOW_DELAY; |
530 | 56.0k | } |
531 | | |
532 | 252k | ret = ffmpeg_OpenCodec( p_dec, ctx, codec ); |
533 | 252k | if( ret < 0 ) |
534 | 1.94k | return ret; |
535 | | |
536 | 250k | switch( ctx->active_thread_type ) |
537 | 250k | { |
538 | 94.9k | case FF_THREAD_FRAME: |
539 | 94.9k | msg_Dbg( p_dec, "using frame thread mode with %d threads", |
540 | 94.9k | ctx->thread_count ); |
541 | 94.9k | break; |
542 | 3.58k | case FF_THREAD_SLICE: |
543 | 3.58k | msg_Dbg( p_dec, "using slice thread mode with %d threads", |
544 | 3.58k | ctx->thread_count ); |
545 | 3.58k | break; |
546 | 152k | case 0: |
547 | 152k | if( ctx->thread_count > 1 ) |
548 | 152k | msg_Warn( p_dec, "failed to enable threaded decoding" ); |
549 | 152k | break; |
550 | 0 | default: |
551 | 0 | msg_Warn( p_dec, "using unknown thread mode with %d threads", |
552 | 0 | ctx->thread_count ); |
553 | 0 | break; |
554 | 250k | } |
555 | 250k | return 0; |
556 | 250k | } |
557 | | |
558 | | static int InitVideoDecCommon( decoder_t *p_dec ) |
559 | 253k | { |
560 | 253k | decoder_sys_t *p_sys = p_dec->p_sys; |
561 | 253k | AVCodecContext *p_context = p_sys->p_context; |
562 | 253k | const AVCodec *p_codec = p_sys->p_codec; |
563 | 253k | int i_val; |
564 | | |
565 | 253k | p_sys->p_va = NULL; |
566 | 253k | vlc_mutex_init( &p_sys->lock ); |
567 | | |
568 | | /* ***** Fill p_context with init values ***** */ |
569 | 253k | p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in->i_original_fourcc ? |
570 | 253k | p_dec->fmt_in->i_original_fourcc : p_dec->fmt_in->i_codec ); |
571 | | |
572 | | /* ***** Get configuration of ffmpeg plugin ***** */ |
573 | 253k | if( var_CreateGetBool( p_dec, "grayscale" ) ) |
574 | 0 | p_context->flags |= AV_CODEC_FLAG_GRAY; |
575 | | |
576 | | /* ***** Output always the frames ***** */ |
577 | 253k | p_context->flags |= AV_CODEC_FLAG_OUTPUT_CORRUPT; |
578 | | |
579 | 253k | #if OPAQUE_REF_ONLY |
580 | 253k | p_context->flags |= AV_CODEC_FLAG_COPY_OPAQUE; |
581 | 253k | #endif |
582 | | |
583 | 253k | #if LIBAVCODEC_VERSION_CHECK( 61, 03, 100 ) |
584 | 253k | if( p_dec->fmt_in->i_codec == VLC_CODEC_VVC ) |
585 | 0 | p_context->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; |
586 | 253k | #endif |
587 | | |
588 | 253k | i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" ); |
589 | 253k | if( i_val >= 4 ) p_context->skip_loop_filter = AVDISCARD_ALL; |
590 | 253k | else if( i_val == 3 ) p_context->skip_loop_filter = AVDISCARD_NONKEY; |
591 | 253k | else if( i_val == 2 ) p_context->skip_loop_filter = AVDISCARD_BIDIR; |
592 | 253k | else if( i_val == 1 ) p_context->skip_loop_filter = AVDISCARD_NONREF; |
593 | 253k | else p_context->skip_loop_filter = AVDISCARD_DEFAULT; |
594 | | |
595 | | /* ***** libavcodec frame skipping ***** */ |
596 | 253k | p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" ); |
597 | 253k | p_sys->b_show_corrupted = var_CreateGetBool( p_dec, "avcodec-corrupted" ); |
598 | 253k | p_sys->b_no_frame_drop = ffmpeg_CodecForbidsFrameDrop( p_codec->id ); |
599 | 253k | if( p_sys->b_no_frame_drop ) |
600 | 253k | msg_Dbg( p_dec, "frame dropping disabled for this codec (stateful, " |
601 | 253k | "no recoverable keyframes)" ); |
602 | | |
603 | 253k | i_val = var_CreateGetInteger( p_dec, "avcodec-skip-frame" ); |
604 | 253k | if( i_val >= 4 ) p_sys->i_skip_frame = AVDISCARD_ALL; |
605 | 253k | else if( i_val == 3 ) p_sys->i_skip_frame = AVDISCARD_NONKEY; |
606 | 253k | else if( i_val == 2 ) p_sys->i_skip_frame = AVDISCARD_BIDIR; |
607 | 253k | else if( i_val == 1 ) p_sys->i_skip_frame = AVDISCARD_NONREF; |
608 | 253k | else if( i_val == -1 ) p_sys->i_skip_frame = AVDISCARD_NONE; |
609 | 253k | else p_sys->i_skip_frame = AVDISCARD_DEFAULT; |
610 | 253k | p_context->skip_frame = p_sys->i_skip_frame; |
611 | | |
612 | 253k | i_val = var_CreateGetInteger( p_dec, "avcodec-skip-idct" ); |
613 | 253k | if( i_val >= 4 ) p_context->skip_idct = AVDISCARD_ALL; |
614 | 253k | else if( i_val == 3 ) p_context->skip_idct = AVDISCARD_NONKEY; |
615 | 253k | else if( i_val == 2 ) p_context->skip_idct = AVDISCARD_BIDIR; |
616 | 253k | else if( i_val == 1 ) p_context->skip_idct = AVDISCARD_NONREF; |
617 | 253k | else if( i_val == -1 ) p_context->skip_idct = AVDISCARD_NONE; |
618 | 253k | else p_context->skip_idct = AVDISCARD_DEFAULT; |
619 | | |
620 | | /* ***** libavcodec direct rendering ***** */ |
621 | 253k | p_sys->b_direct_rendering = false; |
622 | 253k | p_sys->b_dr_failure = false; |
623 | 253k | if( var_CreateGetBool( p_dec, "avcodec-dr" ) && |
624 | 253k | (p_codec->capabilities & AV_CODEC_CAP_DR1) && |
625 | | /* No idea why ... but this fixes flickering on some TSCC streams */ |
626 | 251k | p_sys->p_codec->id != AV_CODEC_ID_TSCC && |
627 | 251k | p_sys->p_codec->id != AV_CODEC_ID_CSCD && |
628 | 251k | p_sys->p_codec->id != AV_CODEC_ID_CINEPAK ) |
629 | 251k | { |
630 | | /* Some codecs set pix_fmt only after the 1st frame has been decoded, |
631 | | * so we need to do another check in ffmpeg_GetFrameBuf() */ |
632 | 251k | p_sys->b_direct_rendering = true; |
633 | 251k | } |
634 | | |
635 | 253k | p_context->get_format = ffmpeg_GetFormat; |
636 | | /* Always use our get_buffer wrapper so we can calculate the |
637 | | * PTS correctly */ |
638 | 253k | p_context->get_buffer2 = lavc_GetFrame; |
639 | 253k | p_context->opaque = p_dec; |
640 | | |
641 | 253k | FrameInfoInit( p_sys ); |
642 | | |
643 | 253k | int max_thread_count; |
644 | 253k | int i_thread_count = p_sys->b_hardware_only ? 1 : var_InheritInteger( p_dec, "avcodec-threads" ); |
645 | 253k | if( i_thread_count <= 0 ) |
646 | 251k | { |
647 | 251k | i_thread_count = vlc_GetCPUCount(); |
648 | 251k | if( i_thread_count > 1 ) |
649 | 251k | i_thread_count++; |
650 | | |
651 | | //FIXME: take in count the decoding time |
652 | 251k | max_thread_count = p_codec->id == AV_CODEC_ID_HEVC ? 10 : 6; |
653 | | #if defined(_WIN32) |
654 | | # if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
655 | | // reduce memory when decoding on Xbox |
656 | | max_thread_count = 6 ; |
657 | | # endif |
658 | | #endif |
659 | 251k | } |
660 | 1.39k | else |
661 | 1.39k | max_thread_count = p_codec->id == AV_CODEC_ID_HEVC ? 32 : 16; |
662 | 253k | i_thread_count = __MIN( i_thread_count, max_thread_count ); |
663 | 253k | msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count ); |
664 | 253k | p_context->thread_count = i_thread_count; |
665 | | #if LIBAVCODEC_VERSION_MAJOR < 60 |
666 | | p_context->thread_safe_callbacks = true; |
667 | | #endif |
668 | | |
669 | 253k | switch( p_codec->id ) |
670 | 253k | { |
671 | 10.1k | case AV_CODEC_ID_MPEG4: |
672 | 10.1k | case AV_CODEC_ID_H263: |
673 | 10.1k | p_context->thread_type = 0; |
674 | 10.1k | break; |
675 | 0 | case AV_CODEC_ID_MPEG1VIDEO: |
676 | 141k | case AV_CODEC_ID_MPEG2VIDEO: |
677 | 141k | p_context->thread_type &= ~FF_THREAD_SLICE; |
678 | | /* fall through */ |
679 | 243k | default: |
680 | 243k | break; |
681 | 253k | } |
682 | | |
683 | 253k | if( var_InheritBool(p_dec, "low-delay") ) |
684 | 0 | p_context->thread_type &= ~FF_THREAD_FRAME; |
685 | | |
686 | 253k | if( p_context->thread_type & FF_THREAD_FRAME ) |
687 | 243k | p_dec->i_extra_picture_buffers = 2 * p_context->thread_count; |
688 | | |
689 | | /* ***** misc init ***** */ |
690 | 253k | date_Init(&p_sys->pts, 1, 30001); |
691 | 253k | p_sys->b_first_frame = true; |
692 | 253k | p_sys->i_late_frames = 0; |
693 | 253k | p_sys->b_from_preroll = false; |
694 | 253k | p_sys->i_last_output_frame = -1; |
695 | 253k | p_sys->framedrop = FRAMEDROP_NONE; |
696 | | |
697 | | /* Set output properties */ |
698 | 253k | if (GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) == VLC_SUCCESS) |
699 | 0 | p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma; |
700 | | |
701 | 253k | p_dec->fmt_out.video.orientation = p_dec->fmt_in->video.orientation; |
702 | | |
703 | 253k | if( p_dec->fmt_in->video.p_palette ) { |
704 | 0 | p_sys->palette_sent = false; |
705 | 0 | p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) ); |
706 | 0 | if( p_dec->fmt_out.video.p_palette ) |
707 | 0 | *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in->video.p_palette; |
708 | 0 | } else |
709 | 253k | p_sys->palette_sent = true; |
710 | | |
711 | | /* ***** init this codec with special data ***** */ |
712 | 253k | ffmpeg_InitCodec( p_dec ); |
713 | | |
714 | | /* ***** Open the codec ***** */ |
715 | 253k | if( OpenVideoCodec( p_dec ) < 0 ) |
716 | 1.94k | { |
717 | 1.94k | free( p_sys ); |
718 | 1.94k | avcodec_free_context( &p_context ); |
719 | 1.94k | return VLC_EGENERIC; |
720 | 1.94k | } |
721 | | |
722 | 251k | p_dec->pf_decode = DecodeVideo; |
723 | 251k | p_dec->pf_flush = Flush; |
724 | | |
725 | 251k | return VLC_SUCCESS; |
726 | 253k | } |
727 | | |
728 | | static int lavc_UpdateHWVideoFormat(decoder_t *p_dec, AVCodecContext *p_context, |
729 | | enum AVPixelFormat hwfmt, enum AVPixelFormat swfmt, |
730 | | vlc_decoder_device **pp_dec_device) |
731 | 0 | { |
732 | 0 | if( hwfmt == AV_PIX_FMT_NONE ) |
733 | 0 | return VLC_EGENERIC; |
734 | | |
735 | 0 | if (!vlc_va_MightDecode(hwfmt)) |
736 | 0 | return VLC_EGENERIC; /* Unknown brand of hardware acceleration */ |
737 | 0 | if (p_context->width == 0 || p_context->height == 0) |
738 | 0 | { /* should never happen */ |
739 | 0 | msg_Err(p_dec, "unspecified video dimensions"); |
740 | 0 | return VLC_EGENERIC; |
741 | 0 | } |
742 | 0 | const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(hwfmt); |
743 | 0 | msg_Dbg(p_dec, "trying format %s", dsc ? dsc->name : "unknown"); |
744 | 0 | if (lavc_UpdateVideoFormat(p_dec, p_context, hwfmt, swfmt)) |
745 | 0 | return VLC_EGENERIC; /* Unsupported brand of hardware acceleration */ |
746 | | |
747 | 0 | *pp_dec_device = decoder_GetDecoderDevice(p_dec); |
748 | 0 | if (*pp_dec_device == NULL) |
749 | 0 | return VLC_EGENERIC; |
750 | | |
751 | 0 | return VLC_SUCCESS; |
752 | 0 | } |
753 | | |
754 | | static void ffmpeg_CloseVa(decoder_t *p_dec, AVCodecContext *context) |
755 | 0 | { |
756 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
757 | 0 | assert(p_sys->p_va != NULL); |
758 | 0 | assert(p_sys->vctx_out != NULL); |
759 | |
|
760 | 0 | vlc_va_Delete(p_sys->p_va, NULL); |
761 | 0 | p_sys->p_va = NULL; |
762 | 0 | vlc_video_context_Release(p_sys->vctx_out); |
763 | 0 | p_sys->vctx_out = NULL; |
764 | 0 | p_sys->use_hwframes = false; |
765 | |
|
766 | 0 | if (context != NULL) |
767 | 0 | context->hwaccel_context = NULL; |
768 | 0 | } |
769 | | |
770 | | static int ffmpeg_OpenVa(decoder_t *p_dec, AVCodecContext *p_context, |
771 | | enum AVPixelFormat hwfmt, |
772 | | const AVPixFmtDescriptor *src_desc, |
773 | | vlc_decoder_device *dec_device, |
774 | | vlc_video_context *vctx) |
775 | 0 | { |
776 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
777 | |
|
778 | 0 | p_dec->fmt_out.video.i_chroma = 0; // make sure the va sets its output chroma |
779 | 0 | struct vlc_va_cfg cfg = { |
780 | 0 | .avctx = p_context, |
781 | 0 | .hwfmt = hwfmt, |
782 | 0 | .desc = src_desc, |
783 | 0 | .fmt_in = p_dec->fmt_in, |
784 | 0 | .dec_device = dec_device, |
785 | 0 | .video_fmt_out = &p_dec->fmt_out.video, |
786 | 0 | .vctx_prev = vctx, |
787 | 0 | .vctx_out = NULL, |
788 | 0 | .use_hwframes = false, |
789 | 0 | .extra_pictures = 0, |
790 | 0 | }; |
791 | 0 | vlc_va_t *va = vlc_va_New(VLC_OBJECT(p_dec), &cfg); |
792 | |
|
793 | 0 | if (va == NULL) |
794 | 0 | return VLC_EGENERIC; /* Unsupported codec profile or such */ |
795 | 0 | assert(p_dec->fmt_out.video.i_chroma != 0); |
796 | 0 | assert(cfg.vctx_out != NULL); |
797 | 0 | p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma; |
798 | 0 | p_dec->i_extra_picture_buffers += cfg.extra_pictures; |
799 | |
|
800 | 0 | if (decoder_UpdateVideoOutput(p_dec, cfg.vctx_out)) |
801 | 0 | { |
802 | 0 | vlc_va_Delete(va, p_context); |
803 | 0 | return VLC_EGENERIC; /* Unsupported codec profile or such */ |
804 | 0 | } |
805 | | |
806 | 0 | p_sys->p_va = va; |
807 | 0 | p_sys->vctx_out = vlc_video_context_Hold( cfg.vctx_out ); |
808 | 0 | p_sys->pix_fmt = hwfmt; |
809 | 0 | p_sys->use_hwframes = cfg.use_hwframes; |
810 | 0 | return VLC_SUCCESS; |
811 | 0 | } |
812 | | |
813 | | static int ffmpeg_RecreateVa(decoder_t *p_dec, AVCodecContext *p_context, |
814 | | enum AVPixelFormat swfmt) |
815 | 0 | { |
816 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
817 | 0 | assert(p_sys->use_hwframes); |
818 | 0 | assert(p_sys->vctx_out != NULL); |
819 | |
|
820 | 0 | vlc_video_context *vctx = vlc_video_context_Hold(p_sys->vctx_out); |
821 | 0 | vlc_decoder_device *dec_device = |
822 | 0 | vlc_video_context_HoldDevice(p_sys->vctx_out); |
823 | |
|
824 | 0 | ffmpeg_CloseVa(p_dec, p_context); |
825 | |
|
826 | 0 | const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(swfmt); |
827 | |
|
828 | 0 | int ret = ffmpeg_OpenVa(p_dec, p_context, p_sys->pix_fmt, |
829 | 0 | src_desc, dec_device, vctx); |
830 | 0 | if (dec_device != NULL) |
831 | 0 | vlc_decoder_device_Release(dec_device); |
832 | 0 | vlc_video_context_Release(vctx); |
833 | 0 | return ret; |
834 | 0 | } |
835 | | |
836 | | static const enum AVPixelFormat hwfmts[] = |
837 | | { |
838 | | #ifdef _WIN32 |
839 | | AV_PIX_FMT_D3D11VA_VLD, |
840 | | AV_PIX_FMT_DXVA2_VLD, |
841 | | #endif |
842 | | AV_PIX_FMT_VAAPI, |
843 | | AV_PIX_FMT_VDPAU, |
844 | | AV_PIX_FMT_NONE, |
845 | | }; |
846 | | |
847 | | static int ExtractAV1Profile(AVCodecContext *p_context, const es_format_t *fmt_in, decoder_sys_t *p_sys) |
848 | 1.97k | { |
849 | 1.97k | av1_OBU_sequence_header_t *sequence_hdr = NULL; |
850 | 1.97k | unsigned w, h; |
851 | | |
852 | 1.97k | if (fmt_in->i_extra > 4) |
853 | 1.41k | { |
854 | | // in ISOBMFF/WebM/Matroska the first 4 bytes are from the AV1CodecConfigurationRecord |
855 | | // and then one or more OBU |
856 | 1.41k | const uint8_t *obu_start = ((const uint8_t*) fmt_in->p_extra) + 4; |
857 | 1.41k | int obu_size = fmt_in->i_extra - 4; |
858 | 1.41k | if (AV1_OBUIsValid(obu_start, obu_size) && AV1_OBUGetType(obu_start) == AV1_OBU_SEQUENCE_HEADER) |
859 | 1.40k | sequence_hdr = AV1_OBU_parse_sequence_header(obu_start, obu_size); |
860 | 1.41k | } |
861 | | |
862 | 1.97k | if (sequence_hdr == NULL) |
863 | 577 | return VLC_ENOTSUP; |
864 | | |
865 | | // fill the AVCodecContext with the values from the sequence header |
866 | | // so we can create the expected VA right away: |
867 | | // coded_width, coded_height, framerate, profile and sw_pix_fmt |
868 | | |
869 | 1.39k | vlc_fourcc_t chroma = AV1_get_chroma(sequence_hdr); |
870 | 1.39k | if (chroma == 0) |
871 | 0 | { |
872 | 0 | AV1_release_sequence_header(sequence_hdr); |
873 | 0 | return VLC_ENOTSUP; |
874 | 0 | } |
875 | 1.39k | bool uv_flipped; |
876 | 1.39k | p_context->sw_pix_fmt = FindFfmpegChroma(chroma, &uv_flipped); |
877 | 1.39k | if (p_context->sw_pix_fmt == AV_PIX_FMT_NONE) |
878 | 0 | { |
879 | 0 | AV1_release_sequence_header(sequence_hdr); |
880 | 0 | return VLC_ENOTSUP; |
881 | 0 | } |
882 | 1.39k | assert(uv_flipped == false); |
883 | | |
884 | 1.39k | AV1_get_frame_max_dimensions(sequence_hdr, &w, &h); |
885 | | |
886 | 1.39k | p_context->coded_width = p_context->width = w; |
887 | 1.39k | p_context->coded_height = p_context->height = h; |
888 | | |
889 | 1.39k | if (!fmt_in->video.i_frame_rate || !fmt_in->video.i_frame_rate_base) |
890 | 869 | { |
891 | 869 | unsigned num, den; |
892 | 869 | if (AV1_get_frame_rate(sequence_hdr, &num, &den)) |
893 | 0 | { |
894 | 0 | p_context->framerate.num = num; |
895 | 0 | p_context->framerate.den = den; |
896 | 0 | } |
897 | 869 | } |
898 | | |
899 | 1.39k | int tier; |
900 | 1.39k | AV1_get_profile_level(sequence_hdr, &p_sys->profile, &p_sys->level, &tier); |
901 | | |
902 | 1.39k | AV1_release_sequence_header(sequence_hdr); |
903 | | |
904 | 1.39k | return VLC_SUCCESS; |
905 | 1.39k | } |
906 | | |
907 | | int InitVideoHwDec( vlc_object_t *obj ) |
908 | 258k | { |
909 | 258k | decoder_t *p_dec = container_of(obj, decoder_t, obj); |
910 | | |
911 | 258k | if (p_dec->fmt_in->i_codec != VLC_CODEC_AV1) |
912 | 256k | return VLC_EGENERIC; |
913 | | |
914 | 1.97k | decoder_sys_t *p_sys = calloc(1, sizeof(*p_sys)); |
915 | 1.97k | if( unlikely(p_sys == NULL) ) |
916 | 0 | return VLC_ENOMEM; |
917 | | |
918 | 1.97k | const AVCodec *p_codec; |
919 | 1.97k | AVCodecContext *p_context = ffmpeg_AllocContext( p_dec, &p_codec, true ); |
920 | 1.97k | if( unlikely(p_context == NULL) ) |
921 | 0 | { |
922 | 0 | free(p_sys); |
923 | 0 | return VLC_ENOMEM; |
924 | 0 | } |
925 | | |
926 | 1.97k | if (ExtractAV1Profile(p_context, p_dec->fmt_in, p_sys) != VLC_SUCCESS) |
927 | 577 | goto failed; |
928 | | |
929 | 1.39k | p_dec->p_sys = p_sys; |
930 | 1.39k | p_sys->p_context = p_context; |
931 | 1.39k | p_sys->p_codec = p_codec; |
932 | 1.39k | p_sys->pix_fmt = AV_PIX_FMT_NONE; |
933 | 1.39k | p_sys->b_hardware_only = true; |
934 | | |
935 | 1.39k | int res = InitVideoDecCommon( p_dec ); |
936 | 1.39k | if (res != VLC_SUCCESS) |
937 | 1.39k | return res; |
938 | | |
939 | 0 | const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(p_context->sw_pix_fmt); |
940 | |
|
941 | 0 | for( size_t i = 0; hwfmts[i] != AV_PIX_FMT_NONE; i++ ) |
942 | 0 | { |
943 | 0 | vlc_decoder_device *dec_device; |
944 | 0 | int ret = lavc_UpdateHWVideoFormat(p_dec, p_context, hwfmts[i], |
945 | 0 | p_context->sw_pix_fmt, &dec_device); |
946 | 0 | if (ret != VLC_SUCCESS) |
947 | 0 | continue; |
948 | | |
949 | 0 | ret = ffmpeg_OpenVa(p_dec, p_context, hwfmts[i], src_desc, dec_device, |
950 | 0 | NULL); |
951 | 0 | if (dec_device != NULL) |
952 | 0 | vlc_decoder_device_Release(dec_device); |
953 | |
|
954 | 0 | if (ret == VLC_SUCCESS) |
955 | | // we have a matching hardware decoder |
956 | 0 | return VLC_SUCCESS; |
957 | 0 | } |
958 | | |
959 | 0 | EndVideoDec(obj); |
960 | 0 | return VLC_EGENERIC; |
961 | 577 | failed: |
962 | 577 | avcodec_free_context( &p_context ); |
963 | 577 | free(p_sys); |
964 | 577 | return VLC_EGENERIC; |
965 | 0 | } |
966 | | |
967 | | /***************************************************************************** |
968 | | * InitVideo: initialize the video decoder |
969 | | ***************************************************************************** |
970 | | * the ffmpeg codec will be opened, some memory allocated. The vout is not yet |
971 | | * opened (done after the first decoded frame). |
972 | | *****************************************************************************/ |
973 | | int InitVideoDec( vlc_object_t *obj ) |
974 | 252k | { |
975 | 252k | decoder_t *p_dec = (decoder_t *)obj; |
976 | 252k | const AVCodec *p_codec; |
977 | 252k | AVCodecContext *p_context = ffmpeg_AllocContext( p_dec, &p_codec, false ); |
978 | 252k | if( p_context == NULL ) |
979 | 601 | return VLC_EGENERIC; |
980 | | |
981 | | /* Allocate the memory needed to store the decoder's structure */ |
982 | 251k | decoder_sys_t *p_sys = calloc( 1, sizeof(*p_sys) ); |
983 | 251k | if( unlikely(p_sys == NULL) ) |
984 | 0 | { |
985 | 0 | avcodec_free_context( &p_context ); |
986 | 0 | return VLC_ENOMEM; |
987 | 0 | } |
988 | | |
989 | 251k | p_dec->p_sys = p_sys; |
990 | 251k | p_sys->p_context = p_context; |
991 | 251k | p_sys->p_codec = p_codec; |
992 | 251k | p_sys->profile = -1; |
993 | 251k | p_sys->level = -1; |
994 | 251k | p_sys->b_hardware_only = false; |
995 | | |
996 | 251k | return InitVideoDecCommon( p_dec ); |
997 | 251k | } |
998 | | |
999 | | /***************************************************************************** |
1000 | | * Flush: |
1001 | | *****************************************************************************/ |
1002 | | static void Flush( decoder_t *p_dec ) |
1003 | 0 | { |
1004 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
1005 | 0 | AVCodecContext *p_context = p_sys->p_context; |
1006 | |
|
1007 | 0 | p_sys->i_late_frames = 0; |
1008 | 0 | p_sys->framedrop = FRAMEDROP_NONE; |
1009 | 0 | cc_Flush( &p_sys->cc ); |
1010 | | |
1011 | | /* do not flush buffers if codec hasn't been opened (theora/vorbis/VC1) */ |
1012 | 0 | if( avcodec_is_open( p_context ) ) |
1013 | 0 | avcodec_flush_buffers( p_context ); |
1014 | |
|
1015 | 0 | date_Set(&p_sys->pts, VLC_TICK_INVALID); /* To make sure we recover properly */ |
1016 | 0 | } |
1017 | | |
1018 | | static block_t * filter_earlydropped_blocks( decoder_t *p_dec, block_t *block ) |
1019 | 2.63M | { |
1020 | 2.63M | decoder_sys_t *p_sys = p_dec->p_sys; |
1021 | | |
1022 | 2.63M | if( !block ) |
1023 | 302k | return NULL; |
1024 | | |
1025 | 2.33M | if( block->i_flags & BLOCK_FLAG_PREROLL ) |
1026 | 12.5k | { |
1027 | | /* Do not care about late frames when prerolling |
1028 | | * TODO avoid decoding of non reference frame |
1029 | | * (ie all B except for H264 where it depends only on nal_ref_idc) */ |
1030 | 12.5k | p_sys->i_late_frames = 0; |
1031 | 12.5k | p_sys->framedrop = FRAMEDROP_NONE; |
1032 | 12.5k | p_sys->b_from_preroll = true; |
1033 | 12.5k | p_sys->i_last_late_delay = VLC_TICK_MAX; |
1034 | 12.5k | } |
1035 | | |
1036 | 2.33M | if( p_sys->i_late_frames == 0 ) |
1037 | 2.33M | p_sys->framedrop = FRAMEDROP_NONE; |
1038 | | |
1039 | 2.33M | if( p_sys->framedrop == FRAMEDROP_NONE && p_sys->i_late_frames < 11 ) |
1040 | 2.33M | return block; |
1041 | | |
1042 | 0 | if( p_sys->i_last_output_frame >= 0 && |
1043 | 0 | NextPktSequenceNumber( p_sys ) - p_sys->i_last_output_frame > 24 ) |
1044 | 0 | { |
1045 | 0 | p_sys->framedrop = FRAMEDROP_AGGRESSIVE_RECOVER; |
1046 | 0 | } |
1047 | | |
1048 | | /* A good idea could be to decode all I pictures and see for the other */ |
1049 | 0 | if( p_sys->framedrop == FRAMEDROP_AGGRESSIVE_RECOVER ) |
1050 | 0 | { |
1051 | 0 | if( !(block->i_flags & BLOCK_FLAG_TYPE_I) ) |
1052 | 0 | { |
1053 | 0 | msg_Err( p_dec, "more than %"PRId64" frames of late video -> " |
1054 | 0 | "dropping frame (computer too slow ?)", |
1055 | 0 | NextPktSequenceNumber( p_sys ) - p_sys->i_last_output_frame ); |
1056 | |
|
1057 | 0 | vlc_mutex_lock(&p_sys->lock); |
1058 | 0 | date_Set( &p_sys->pts, VLC_TICK_INVALID ); /* To make sure we recover properly */ |
1059 | 0 | vlc_mutex_unlock(&p_sys->lock); |
1060 | 0 | block_Release( block ); |
1061 | 0 | p_sys->i_late_frames--; |
1062 | 0 | return NULL; |
1063 | 0 | } |
1064 | 0 | } |
1065 | | |
1066 | 0 | return block; |
1067 | 0 | } |
1068 | | |
1069 | | static vlc_tick_t interpolate_next_pts( decoder_t *p_dec, AVFrame *frame ) |
1070 | 85.7k | { |
1071 | 85.7k | decoder_sys_t *p_sys = p_dec->p_sys; |
1072 | 85.7k | AVCodecContext *p_context = p_sys->p_context; |
1073 | | |
1074 | 85.7k | if( p_sys->pts.i_divider_num == 0 || |
1075 | 83.6k | date_Get( &p_sys->pts ) == VLC_TICK_INVALID ) |
1076 | 16.9k | return VLC_TICK_INVALID; |
1077 | | |
1078 | 68.8k | #if LIBAVCODEC_VERSION_CHECK( 60, 12, 100 ) |
1079 | 68.8k | int i_tick = p_context->codec_descriptor->props & AV_CODEC_PROP_FIELDS ? 2 : 1; |
1080 | | #else |
1081 | | int i_tick = p_context->ticks_per_frame; |
1082 | | #endif |
1083 | | |
1084 | | /* interpolate the next PTS */ |
1085 | 68.8k | return date_Increment( &p_sys->pts, i_tick + frame->repeat_pict ); |
1086 | 85.7k | } |
1087 | | |
1088 | | static void update_late_frame_count( decoder_t *p_dec, block_t *p_block, |
1089 | | vlc_tick_t current_time, vlc_tick_t i_pts, |
1090 | | vlc_tick_t i_next_pts, int64_t i_fnum ) |
1091 | 79.3k | { |
1092 | 79.3k | decoder_sys_t *p_sys = p_dec->p_sys; |
1093 | | /* Update frame late count (except when doing preroll) */ |
1094 | 79.3k | vlc_tick_t i_display_date = VLC_TICK_INVALID; |
1095 | 79.3k | if( !p_block || !(p_block->i_flags & BLOCK_FLAG_PREROLL) ) |
1096 | 78.7k | i_display_date = decoder_GetDisplayDate( p_dec, current_time, i_pts ); |
1097 | | |
1098 | 79.3k | vlc_tick_t i_threshold = i_next_pts != VLC_TICK_INVALID |
1099 | 79.3k | ? (i_next_pts - i_pts) / 2 : VLC_TICK_FROM_MS(20); |
1100 | | |
1101 | 79.3k | if( i_display_date != VLC_TICK_INVALID && i_display_date + i_threshold <= current_time ) |
1102 | 0 | { |
1103 | | /* Out of preroll, consider only late frames on rising delay */ |
1104 | 0 | if( p_sys->b_from_preroll ) |
1105 | 0 | { |
1106 | 0 | if( p_sys->i_last_late_delay > current_time - i_display_date ) |
1107 | 0 | { |
1108 | 0 | p_sys->i_last_late_delay = current_time - i_display_date; |
1109 | 0 | return; |
1110 | 0 | } |
1111 | 0 | p_sys->b_from_preroll = false; |
1112 | 0 | } |
1113 | | |
1114 | 0 | p_sys->i_late_frames++; |
1115 | 0 | } |
1116 | 79.3k | else |
1117 | 79.3k | { |
1118 | 79.3k | p_sys->i_last_output_frame = i_fnum; |
1119 | 79.3k | p_sys->i_late_frames = 0; |
1120 | 79.3k | } |
1121 | 79.3k | } |
1122 | | |
1123 | | #if LIBAVUTIL_VERSION_CHECK( 57, 16, 100 ) |
1124 | | static void map_dovi_metadata( vlc_video_dovi_metadata_t *out, |
1125 | | const AVDOVIMetadata *data ) |
1126 | 0 | { |
1127 | 0 | const AVDOVIRpuDataHeader *hdr = av_dovi_get_header( data ); |
1128 | 0 | const AVDOVIDataMapping *vdm = av_dovi_get_mapping( data ); |
1129 | 0 | const AVDOVIColorMetadata *color = av_dovi_get_color( data ); |
1130 | 0 | out->bl_bit_depth = hdr->bl_bit_depth; |
1131 | 0 | out->el_bit_depth = hdr->el_bit_depth; |
1132 | 0 | out->coef_log2_denom = hdr->coef_log2_denom; |
1133 | 0 | out->nlq_method_idc = (enum vlc_dovi_nlq_method_t) vdm->nlq_method_idc; |
1134 | 0 | for( size_t i = 0; i < ARRAY_SIZE( out->nonlinear_offset ); i++ ) |
1135 | 0 | out->nonlinear_offset[i] = av_q2d( color->ycc_to_rgb_offset[i] ); |
1136 | 0 | for( size_t i = 0; i < ARRAY_SIZE( out->nonlinear_matrix ); i++ ) |
1137 | 0 | out->nonlinear_matrix[i] = av_q2d( color->ycc_to_rgb_matrix[i] ); |
1138 | 0 | for( size_t i = 0; i < ARRAY_SIZE( out->linear_matrix); i++ ) |
1139 | 0 | out->linear_matrix[i] = av_q2d( color->rgb_to_lms_matrix[i] ); |
1140 | 0 | out->source_min_pq = color->source_min_pq; |
1141 | 0 | out->source_max_pq = color->source_max_pq; |
1142 | |
|
1143 | 0 | static_assert(sizeof(out->curves) == sizeof(vdm->curves), "struct mismatch"); |
1144 | 0 | static_assert(sizeof(out->nlq) == sizeof(vdm->nlq), "struct mismatch"); |
1145 | 0 | memcpy(out->curves, vdm->curves, sizeof(out->curves)); |
1146 | 0 | memcpy(out->nlq, vdm->nlq, sizeof(out->nlq)); |
1147 | 0 | for( size_t i = 0; i < ARRAY_SIZE( out->curves ); i++) |
1148 | 0 | assert( out->curves[i].num_pivots <= ARRAY_SIZE( out->curves[i].pivots )); |
1149 | 0 | } |
1150 | | #endif |
1151 | | |
1152 | | static void map_hdrplus_metadata( vlc_video_hdr_dynamic_metadata_t *out, |
1153 | | const AVDynamicHDRPlus *data ) |
1154 | 0 | { |
1155 | 0 | out->country_code = data->itu_t_t35_country_code; |
1156 | 0 | out->application_version = data->application_version; |
1157 | 0 | out->targeted_luminance = av_q2d( data->targeted_system_display_maximum_luminance ); |
1158 | |
|
1159 | 0 | assert( data->num_windows > 0 ); |
1160 | 0 | const AVHDRPlusColorTransformParams *pars = &data->params[0]; |
1161 | 0 | for ( size_t i = 0; i < ARRAY_SIZE( out->maxscl ); i++ ) |
1162 | 0 | out->maxscl[i] = av_q2d( pars->maxscl[i] ); |
1163 | 0 | out->average_maxrgb = av_q2d( pars->average_maxrgb ); |
1164 | 0 | out->num_histogram = pars->num_distribution_maxrgb_percentiles; |
1165 | 0 | assert( out->num_histogram < ARRAY_SIZE( out->histogram )); |
1166 | 0 | for ( size_t i = 0; i < out->num_histogram; i++ ) { |
1167 | 0 | const AVHDRPlusPercentile pct = pars->distribution_maxrgb[i]; |
1168 | 0 | out->histogram[i].percentage = pct.percentage; |
1169 | 0 | out->histogram[i].percentile = av_q2d( pct.percentile ); |
1170 | 0 | } |
1171 | 0 | out->fraction_bright_pixels = av_q2d( pars->fraction_bright_pixels ); |
1172 | 0 | out->tone_mapping_flag = pars->tone_mapping_flag; |
1173 | 0 | if ( out->tone_mapping_flag ) { |
1174 | 0 | out->knee_point_x = av_q2d( pars->knee_point_x ); |
1175 | 0 | out->knee_point_y = av_q2d( pars->knee_point_y ); |
1176 | 0 | out->num_bezier_anchors = pars->num_bezier_curve_anchors; |
1177 | 0 | assert( out->num_bezier_anchors < ARRAY_SIZE( out->bezier_curve_anchors )); |
1178 | 0 | for ( size_t i = 0; i < out->num_bezier_anchors; i++ ) |
1179 | 0 | out->bezier_curve_anchors[i] = av_q2d( pars->bezier_curve_anchors[i] ); |
1180 | 0 | } |
1181 | 0 | } |
1182 | | |
1183 | | static int DecodeSidedata( decoder_t *p_dec, const AVFrame *frame, picture_t *p_pic ) |
1184 | 84.9k | { |
1185 | 84.9k | decoder_sys_t *p_sys = p_dec->p_sys; |
1186 | 84.9k | bool format_changed = false; |
1187 | | |
1188 | 84.9k | #define FROM_AVRAT(default_factor, avrat) \ |
1189 | 1.48k | (uint64_t)(default_factor) * (avrat).num / (avrat).den |
1190 | 84.9k | const AVFrameSideData *metadata = |
1191 | 84.9k | av_frame_get_side_data( frame, |
1192 | 84.9k | AV_FRAME_DATA_MASTERING_DISPLAY_METADATA ); |
1193 | 84.9k | if ( metadata ) |
1194 | 254 | { |
1195 | 254 | const AVMasteringDisplayMetadata *hdr_meta = |
1196 | 254 | (const AVMasteringDisplayMetadata *) metadata->data; |
1197 | 254 | if ( hdr_meta->has_luminance ) |
1198 | 84 | { |
1199 | 84 | #define ST2086_LUMA_FACTOR 10000 |
1200 | 84 | p_pic->format.mastering.max_luminance = |
1201 | 84 | FROM_AVRAT(ST2086_LUMA_FACTOR, hdr_meta->max_luminance); |
1202 | 84 | p_pic->format.mastering.min_luminance = |
1203 | 84 | FROM_AVRAT(ST2086_LUMA_FACTOR, hdr_meta->min_luminance); |
1204 | 84 | } |
1205 | 254 | if ( hdr_meta->has_primaries ) |
1206 | 165 | { |
1207 | 330 | #define ST2086_RED 2 |
1208 | 330 | #define ST2086_GREEN 0 |
1209 | 330 | #define ST2086_BLUE 1 |
1210 | 165 | #define LAV_RED 0 |
1211 | 165 | #define LAV_GREEN 1 |
1212 | 165 | #define LAV_BLUE 2 |
1213 | 165 | #define ST2086_PRIM_FACTOR 50000 |
1214 | 165 | p_pic->format.mastering.primaries[ST2086_RED*2 + 0] = |
1215 | 165 | FROM_AVRAT(ST2086_PRIM_FACTOR, hdr_meta->display_primaries[LAV_RED][0]); |
1216 | 165 | p_pic->format.mastering.primaries[ST2086_RED*2 + 1] = |
1217 | 165 | FROM_AVRAT(ST2086_PRIM_FACTOR, hdr_meta->display_primaries[LAV_RED][1]); |
1218 | 165 | p_pic->format.mastering.primaries[ST2086_GREEN*2 + 0] = |
1219 | 165 | FROM_AVRAT(ST2086_PRIM_FACTOR, hdr_meta->display_primaries[LAV_GREEN][0]); |
1220 | 165 | p_pic->format.mastering.primaries[ST2086_GREEN*2 + 1] = |
1221 | 165 | FROM_AVRAT(ST2086_PRIM_FACTOR, hdr_meta->display_primaries[LAV_GREEN][1]); |
1222 | 165 | p_pic->format.mastering.primaries[ST2086_BLUE*2 + 0] = |
1223 | 165 | FROM_AVRAT(ST2086_PRIM_FACTOR, hdr_meta->display_primaries[LAV_BLUE][0]); |
1224 | 165 | p_pic->format.mastering.primaries[ST2086_BLUE*2 + 1] = |
1225 | 165 | FROM_AVRAT(ST2086_PRIM_FACTOR, hdr_meta->display_primaries[LAV_BLUE][1]); |
1226 | 165 | p_pic->format.mastering.white_point[0] = |
1227 | 165 | FROM_AVRAT(ST2086_PRIM_FACTOR, hdr_meta->white_point[0]); |
1228 | 165 | p_pic->format.mastering.white_point[1] = |
1229 | 165 | FROM_AVRAT(ST2086_PRIM_FACTOR, hdr_meta->white_point[1]); |
1230 | 165 | } |
1231 | | |
1232 | 254 | if ( memcmp( &p_dec->fmt_out.video.mastering, |
1233 | 254 | &p_pic->format.mastering, |
1234 | 254 | sizeof(p_pic->format.mastering) ) ) |
1235 | 42 | { |
1236 | 42 | p_dec->fmt_out.video.mastering = p_pic->format.mastering; |
1237 | 42 | format_changed = true; |
1238 | 42 | } |
1239 | 254 | #undef FROM_AVRAT |
1240 | 254 | } |
1241 | 84.9k | const AVFrameSideData *metadata_lt = |
1242 | 84.9k | av_frame_get_side_data( frame, |
1243 | 84.9k | AV_FRAME_DATA_CONTENT_LIGHT_LEVEL ); |
1244 | 84.9k | if ( metadata_lt ) |
1245 | 1.16k | { |
1246 | 1.16k | const AVContentLightMetadata *light_meta = |
1247 | 1.16k | (const AVContentLightMetadata *) metadata_lt->data; |
1248 | 1.16k | p_pic->format.lighting.MaxCLL = light_meta->MaxCLL; |
1249 | 1.16k | p_pic->format.lighting.MaxFALL = light_meta->MaxFALL; |
1250 | 1.16k | if ( memcmp( &p_dec->fmt_out.video.lighting, |
1251 | 1.16k | &p_pic->format.lighting, |
1252 | 1.16k | sizeof(p_pic->format.lighting) ) ) |
1253 | 1.02k | { |
1254 | 1.02k | p_dec->fmt_out.video.lighting = p_pic->format.lighting; |
1255 | 1.02k | format_changed = true; |
1256 | 1.02k | } |
1257 | 1.16k | } |
1258 | | |
1259 | 84.9k | const AVFrameSideData *p_stereo3d_data = |
1260 | 84.9k | av_frame_get_side_data( frame, |
1261 | 84.9k | AV_FRAME_DATA_STEREO3D ); |
1262 | 84.9k | if( p_stereo3d_data ) |
1263 | 1.68k | { |
1264 | 1.68k | const struct AVStereo3D *stereo_data = |
1265 | 1.68k | (const AVStereo3D *) p_stereo3d_data->data; |
1266 | 1.68k | switch (stereo_data->type) |
1267 | 1.68k | { |
1268 | 548 | case AV_STEREO3D_SIDEBYSIDE: |
1269 | 548 | p_pic->format.multiview_mode = MULTIVIEW_STEREO_SBS; |
1270 | 548 | break; |
1271 | 451 | case AV_STEREO3D_TOPBOTTOM: |
1272 | 451 | p_pic->format.multiview_mode = MULTIVIEW_STEREO_TB; |
1273 | 451 | break; |
1274 | 0 | case AV_STEREO3D_FRAMESEQUENCE: |
1275 | 0 | p_pic->format.multiview_mode = MULTIVIEW_STEREO_FRAME; |
1276 | 0 | break; |
1277 | 0 | case AV_STEREO3D_COLUMNS: |
1278 | 0 | p_pic->format.multiview_mode = MULTIVIEW_STEREO_ROW; |
1279 | 0 | break; |
1280 | 29 | case AV_STEREO3D_LINES: |
1281 | 29 | p_pic->format.multiview_mode = MULTIVIEW_STEREO_COL; |
1282 | 29 | break; |
1283 | 0 | case AV_STEREO3D_CHECKERBOARD: |
1284 | 0 | p_pic->format.multiview_mode = MULTIVIEW_STEREO_CHECKERBOARD; |
1285 | 0 | break; |
1286 | 1 | default: |
1287 | 652 | case AV_STEREO3D_2D: |
1288 | 652 | p_pic->format.multiview_mode = MULTIVIEW_2D; |
1289 | 652 | break; |
1290 | 1.68k | } |
1291 | 1.68k | p_pic->format.b_multiview_right_eye_first = stereo_data->flags & AV_STEREO3D_FLAG_INVERT; |
1292 | 1.68k | p_pic->b_multiview_left_eye = (stereo_data->view == AV_STEREO3D_VIEW_LEFT); |
1293 | | |
1294 | 1.68k | p_dec->fmt_out.video.b_multiview_right_eye_first = p_pic->format.b_multiview_right_eye_first; |
1295 | | |
1296 | 1.68k | if (p_dec->fmt_out.video.multiview_mode != p_pic->format.multiview_mode) |
1297 | 866 | { |
1298 | 866 | p_dec->fmt_out.video.multiview_mode = p_pic->format.multiview_mode; |
1299 | 866 | format_changed = true; |
1300 | 866 | } |
1301 | 1.68k | } |
1302 | 83.2k | else |
1303 | 83.2k | p_pic->format.multiview_mode = p_dec->fmt_out.video.multiview_mode; |
1304 | | |
1305 | 84.9k | if (format_changed && decoder_UpdateVideoOutput( p_dec, p_sys->vctx_out )) |
1306 | 0 | return -1; |
1307 | | |
1308 | 84.9k | const AVFrameSideData *p_avcc = av_frame_get_side_data( frame, AV_FRAME_DATA_A53_CC ); |
1309 | 84.9k | if( p_avcc ) |
1310 | 6.47k | { |
1311 | 6.47k | cc_Extract( &p_sys->cc, CC_PAYLOAD_RAW, true, p_avcc->data, p_avcc->size ); |
1312 | 6.47k | if( p_sys->cc.b_reorder || p_sys->cc.i_data ) |
1313 | 6.47k | { |
1314 | 6.47k | block_t *p_cc = block_Alloc( p_sys->cc.i_data ); |
1315 | 6.47k | if( p_cc ) |
1316 | 6.47k | { |
1317 | 6.47k | memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data ); |
1318 | 6.47k | if( p_sys->cc.b_reorder ) |
1319 | 6.47k | p_cc->i_dts = p_cc->i_pts = p_pic->date; |
1320 | 0 | else |
1321 | 0 | p_cc->i_pts = p_cc->i_dts; |
1322 | 6.47k | decoder_cc_desc_t desc; |
1323 | 6.47k | desc.i_608_channels = p_sys->cc.i_608channels; |
1324 | 6.47k | desc.i_708_channels = p_sys->cc.i_708channels; |
1325 | 6.47k | desc.i_reorder_depth = 4; |
1326 | 6.47k | decoder_QueueCc( p_dec, p_cc, &desc ); |
1327 | 6.47k | } |
1328 | 6.47k | cc_Flush( &p_sys->cc ); |
1329 | 6.47k | } |
1330 | 6.47k | } |
1331 | | |
1332 | 84.9k | #if LIBAVUTIL_VERSION_CHECK( 57, 16, 100 ) |
1333 | 84.9k | const AVFrameSideData *p_dovi = av_frame_get_side_data( frame, AV_FRAME_DATA_DOVI_METADATA ); |
1334 | 84.9k | if( p_dovi ) |
1335 | 0 | { |
1336 | 0 | vlc_video_dovi_metadata_t *dst; |
1337 | 0 | dst = picture_AttachNewAncillary( p_pic, VLC_ANCILLARY_ID_DOVI, sizeof(*dst) ); |
1338 | 0 | if( !dst ) |
1339 | 0 | return VLC_ENOMEM; |
1340 | 0 | map_dovi_metadata( dst, (AVDOVIMetadata *) p_dovi->data ); |
1341 | 0 | } |
1342 | 84.9k | #endif |
1343 | | |
1344 | 84.9k | const AVFrameSideData *p_hdrplus = av_frame_get_side_data( frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS ); |
1345 | 84.9k | if( p_hdrplus ) |
1346 | 0 | { |
1347 | 0 | vlc_video_hdr_dynamic_metadata_t *dst; |
1348 | 0 | dst = picture_AttachNewAncillary( p_pic, VLC_ANCILLARY_ID_HDR10PLUS, sizeof(*dst) ); |
1349 | 0 | if( !dst ) |
1350 | 0 | return VLC_ENOMEM; |
1351 | 0 | map_hdrplus_metadata( dst, (AVDynamicHDRPlus *) p_hdrplus->data ); |
1352 | 0 | } |
1353 | | |
1354 | 84.9k | const AVFrameSideData *p_icc = av_frame_get_side_data( frame, AV_FRAME_DATA_ICC_PROFILE ); |
1355 | 84.9k | if( p_icc ) |
1356 | 0 | { |
1357 | 0 | vlc_icc_profile_t *icc; |
1358 | 0 | icc = picture_AttachNewAncillary( p_pic, VLC_ANCILLARY_ID_ICC, sizeof(*icc) + p_icc->size ); |
1359 | 0 | if( !icc ) |
1360 | 0 | return VLC_ENOMEM; |
1361 | 0 | memcpy( icc->data, p_icc->data, p_icc->size ); |
1362 | 0 | icc->size = p_icc->size; |
1363 | 0 | } |
1364 | | |
1365 | 84.9k | return 0; |
1366 | 84.9k | } |
1367 | | |
1368 | | /***************************************************************************** |
1369 | | * DecodeBlock: Called to decode one or more frames |
1370 | | * drains if pp_block == NULL |
1371 | | * tries to output only if p_block == NULL |
1372 | | *****************************************************************************/ |
1373 | | static int DecodeBlock( decoder_t *p_dec, block_t **pp_block ) |
1374 | 2.64M | { |
1375 | 2.64M | decoder_sys_t *p_sys = p_dec->p_sys; |
1376 | 2.64M | AVCodecContext *p_context = p_sys->p_context; |
1377 | | /* Boolean if we assume that we should get valid pic as result */ |
1378 | 2.64M | bool b_need_output_picture = true; |
1379 | 2.64M | bool b_error = false; |
1380 | | |
1381 | 2.64M | block_t *p_block = pp_block ? *pp_block : NULL; |
1382 | | |
1383 | 2.64M | if( !p_context->extradata_size && p_dec->fmt_in->i_extra ) |
1384 | 0 | { |
1385 | 0 | ffmpeg_InitCodec( p_dec ); |
1386 | 0 | if( !avcodec_is_open( p_context ) && OpenVideoCodec(p_dec) < 0 ) |
1387 | 0 | { |
1388 | 0 | if( p_block != NULL ) |
1389 | 0 | block_Release( p_block ); |
1390 | 0 | return VLCDEC_ECRITICAL; |
1391 | 0 | } |
1392 | 0 | } |
1393 | | |
1394 | 2.64M | if( !avcodec_is_open( p_context ) ) |
1395 | 478 | { |
1396 | 478 | if( p_block ) |
1397 | 0 | block_Release( p_block ); |
1398 | 478 | return VLCDEC_SUCCESS; |
1399 | 478 | } |
1400 | | |
1401 | | /* Defaults that if we aren't in prerolling, we want output picture |
1402 | | same for if we are flushing (p_block==NULL) */ |
1403 | 2.64M | if( !p_block || !(p_block->i_flags & BLOCK_FLAG_PREROLL) ) |
1404 | 2.62M | b_need_output_picture = true; |
1405 | 12.5k | else |
1406 | 12.5k | b_need_output_picture = false; |
1407 | | |
1408 | | /* Change skip_frame config only if hurry_up is enabled, and never drop |
1409 | | * frames for codecs that cannot recover from it. */ |
1410 | 2.64M | if( p_sys->b_hurry_up && !p_sys->b_no_frame_drop ) |
1411 | 2.64M | { |
1412 | 2.64M | p_context->skip_frame = p_sys->i_skip_frame; |
1413 | | |
1414 | | /* Check also if we should/can drop the block and move to next block |
1415 | | as trying to catchup the speed*/ |
1416 | 2.64M | if( p_dec->b_frame_drop_allowed ) |
1417 | 2.63M | p_block = filter_earlydropped_blocks( p_dec, p_block ); |
1418 | 2.64M | } |
1419 | | |
1420 | 2.64M | if( !p_sys->b_no_frame_drop && |
1421 | 2.64M | ( !b_need_output_picture || p_sys->framedrop == FRAMEDROP_NONREF ) ) |
1422 | 12.5k | { |
1423 | 12.5k | p_context->skip_frame = __MAX( p_context->skip_frame, AVDISCARD_NONREF ); |
1424 | 12.5k | } |
1425 | | |
1426 | | /* |
1427 | | * Do the actual decoding now */ |
1428 | | |
1429 | | /* Don't forget that libavcodec requires a little more bytes |
1430 | | * that the real frame size */ |
1431 | 2.64M | if( p_block && p_block->i_buffer > 0 ) |
1432 | 2.33M | { |
1433 | 2.33M | p_block = block_Realloc( p_block, 0, |
1434 | 2.33M | p_block->i_buffer + AV_INPUT_BUFFER_PADDING_SIZE ); |
1435 | 2.33M | if( !p_block ) |
1436 | 0 | return VLCDEC_ECRITICAL; |
1437 | 2.33M | p_block->i_buffer -= AV_INPUT_BUFFER_PADDING_SIZE; |
1438 | 2.33M | *pp_block = p_block; |
1439 | 2.33M | memset( p_block->p_buffer + p_block->i_buffer, 0, |
1440 | 2.33M | AV_INPUT_BUFFER_PADDING_SIZE ); |
1441 | 2.33M | } |
1442 | | |
1443 | 2.64M | bool b_drain = ( pp_block == NULL ); |
1444 | 2.64M | bool b_drained = false; |
1445 | 2.64M | bool b_first_output_sequence = true; |
1446 | | |
1447 | 2.64M | do |
1448 | 4.83M | { |
1449 | 4.83M | int i_used = 0; |
1450 | | |
1451 | 4.83M | if( (p_block && p_block->i_buffer > 0) || b_drain ) |
1452 | 2.63M | { |
1453 | 2.63M | AVPacket *pkt = av_packet_alloc(); |
1454 | 2.63M | if(!pkt) |
1455 | 0 | { |
1456 | 0 | b_error = true; |
1457 | 0 | break; |
1458 | 0 | } |
1459 | 2.63M | if( p_block && p_block->i_buffer > 0 ) |
1460 | 2.33M | { |
1461 | 2.33M | pkt->data = p_block->p_buffer; |
1462 | 2.33M | pkt->size = p_block->i_buffer; |
1463 | 2.33M | pkt->pts = p_block->i_pts != VLC_TICK_INVALID ? TO_AV_TS(p_block->i_pts) : AV_NOPTS_VALUE; |
1464 | 2.33M | pkt->dts = p_block->i_dts != VLC_TICK_INVALID ? TO_AV_TS(p_block->i_dts) : AV_NOPTS_VALUE; |
1465 | 2.33M | if (p_block->i_flags & BLOCK_FLAG_TYPE_I) |
1466 | 1.88M | pkt->flags |= AV_PKT_FLAG_KEY; |
1467 | 2.33M | } |
1468 | 302k | else |
1469 | 302k | { |
1470 | | /* Drain */ |
1471 | 302k | pkt->data = NULL; |
1472 | 302k | pkt->size = 0; |
1473 | 302k | b_drain = false; |
1474 | 302k | b_drained = true; |
1475 | 302k | } |
1476 | | |
1477 | 2.63M | if( !p_sys->palette_sent ) |
1478 | 0 | { |
1479 | 0 | uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); |
1480 | 0 | if (pal) { |
1481 | 0 | const video_palette_t *p_palette = p_dec->fmt_in->video.p_palette; |
1482 | 0 | for (size_t i=0; i<ARRAY_SIZE(p_palette->palette); i++) |
1483 | 0 | { |
1484 | 0 | memcpy(pal, p_palette->palette[i], sizeof(p_palette->palette[0])); |
1485 | 0 | pal += sizeof(p_palette->palette[0]); |
1486 | 0 | } |
1487 | 0 | p_sys->palette_sent = true; |
1488 | 0 | } |
1489 | 0 | } |
1490 | | |
1491 | | /* Make sure we don't reuse the same timestamps twice */ |
1492 | 2.63M | if( p_block ) |
1493 | 2.33M | { |
1494 | 2.33M | p_block->i_pts = |
1495 | 2.33M | p_block->i_dts = VLC_TICK_INVALID; |
1496 | 2.33M | } |
1497 | | |
1498 | 2.63M | struct frame_info_s *p_frame_info = FrameInfoAdd( p_sys, pkt ); |
1499 | 2.63M | if( !p_frame_info ) |
1500 | 0 | { |
1501 | 0 | av_packet_free( &pkt ); |
1502 | 0 | b_error = true; |
1503 | 0 | break; |
1504 | 0 | } |
1505 | 2.63M | const bool b_eos = p_block && (p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE); |
1506 | 2.63M | p_frame_info->b_eos = b_eos; |
1507 | 2.63M | p_frame_info->b_display = b_need_output_picture; |
1508 | | |
1509 | 2.63M | int ret = avcodec_send_packet(p_context, pkt); |
1510 | 2.63M | if( ret != 0 && ret != AVERROR(EAGAIN) ) |
1511 | 156k | { |
1512 | 156k | if (ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL)) |
1513 | 1.98k | { |
1514 | 1.98k | msg_Err(p_dec, "avcodec_send_packet critical error"); |
1515 | 1.98k | b_error = true; |
1516 | 1.98k | } |
1517 | 156k | av_packet_free( &pkt ); |
1518 | 156k | break; |
1519 | 156k | } |
1520 | | |
1521 | 2.47M | i_used = ret != AVERROR(EAGAIN) ? pkt->size : 0; |
1522 | 2.47M | av_packet_free( &pkt ); |
1523 | | |
1524 | 2.47M | if( b_eos && !b_drained ) |
1525 | 18.0k | { |
1526 | 18.0k | avcodec_send_packet( p_context, NULL ); |
1527 | 18.0k | b_drained = true; |
1528 | 18.0k | } |
1529 | 2.47M | } |
1530 | | |
1531 | 4.67M | AVFrame *frame = av_frame_alloc(); |
1532 | 4.67M | if (unlikely(frame == NULL)) |
1533 | 0 | { |
1534 | 0 | b_error = true; |
1535 | 0 | break; |
1536 | 0 | } |
1537 | | |
1538 | 4.67M | int ret = avcodec_receive_frame(p_context, frame); |
1539 | 4.67M | if( ret != 0 && ret != AVERROR(EAGAIN) ) |
1540 | 323k | { |
1541 | 323k | if (ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL)) |
1542 | 576 | { |
1543 | 576 | msg_Err(p_dec, "avcodec_receive_frame critical error"); |
1544 | 576 | b_error = true; |
1545 | 576 | } |
1546 | 323k | av_frame_free(&frame); |
1547 | 323k | if( ret == AVERROR_EOF ) |
1548 | 301k | break; |
1549 | 323k | } |
1550 | 4.67M | bool not_received_frame = ret; |
1551 | | |
1552 | 4.37M | if( p_block ) |
1553 | 4.33M | { |
1554 | | /* Consumed bytes */ |
1555 | 4.33M | p_block->p_buffer += i_used; |
1556 | 4.33M | p_block->i_buffer -= i_used; |
1557 | 4.33M | } |
1558 | | |
1559 | | /* Nothing to display */ |
1560 | 4.37M | if( not_received_frame ) |
1561 | 4.29M | { |
1562 | 4.29M | av_frame_free(&frame); |
1563 | 4.29M | if( i_used == 0 ) break; |
1564 | 2.11M | continue; |
1565 | 4.29M | } |
1566 | | |
1567 | 85.7k | struct frame_info_s *p_frame_info = FrameInfoGet( p_sys, frame ); |
1568 | 85.7k | if( p_frame_info && p_frame_info->b_eos ) |
1569 | 9.82k | p_sys->b_first_frame = true; |
1570 | | |
1571 | 85.7k | vlc_mutex_lock(&p_sys->lock); |
1572 | | |
1573 | | /* Compute the PTS */ |
1574 | 85.7k | int64_t av_pts = frame->best_effort_timestamp; |
1575 | 85.7k | if( av_pts == AV_NOPTS_VALUE ) |
1576 | 19.2k | av_pts = frame->pkt_dts; |
1577 | | |
1578 | 85.7k | vlc_tick_t i_pts; |
1579 | 85.7k | if( av_pts == AV_NOPTS_VALUE ) |
1580 | 19.2k | i_pts = date_Get( &p_sys->pts ); |
1581 | 66.4k | else |
1582 | 66.4k | i_pts = FROM_AV_TS(av_pts); |
1583 | | |
1584 | | /* Interpolate the next PTS */ |
1585 | 85.7k | if( i_pts != VLC_TICK_INVALID ) |
1586 | 70.9k | date_Set( &p_sys->pts, i_pts ); |
1587 | | |
1588 | 85.7k | const vlc_tick_t i_next_pts = interpolate_next_pts(p_dec, frame); |
1589 | | |
1590 | 85.7k | if( b_first_output_sequence ) |
1591 | 79.3k | { |
1592 | 79.3k | if( p_frame_info ) |
1593 | 79.3k | update_late_frame_count( p_dec, p_block, vlc_tick_now(), i_pts, |
1594 | 79.3k | i_next_pts, FrameSequenceNumber( frame, p_frame_info ) ); |
1595 | 79.3k | b_first_output_sequence = false; |
1596 | 79.3k | } |
1597 | | |
1598 | 85.7k | if( (p_frame_info && !p_frame_info->b_display) || |
1599 | 85.1k | ( !p_sys->p_va && !frame->linesize[0] ) || |
1600 | 85.1k | ( p_dec->b_frame_drop_allowed && (frame->flags & AV_FRAME_FLAG_CORRUPT) && |
1601 | 5.47k | !p_sys->b_show_corrupted ) ) |
1602 | 641 | { |
1603 | 641 | vlc_mutex_unlock(&p_sys->lock); |
1604 | 641 | av_frame_free(&frame); |
1605 | 641 | continue; |
1606 | 641 | } |
1607 | | |
1608 | 85.1k | if( p_context->pix_fmt == AV_PIX_FMT_PAL8 |
1609 | 303 | && !p_dec->fmt_out.video.p_palette ) |
1610 | 23 | { |
1611 | | /* See AV_PIX_FMT_PAL8 comment in avc_GetVideoFormat(): update the |
1612 | | * fmt_out palette and change the fmt_out chroma to request a new |
1613 | | * vout */ |
1614 | 23 | assert( p_dec->fmt_out.video.i_chroma != VLC_CODEC_RGBP ); |
1615 | | |
1616 | 23 | video_palette_t *p_palette; |
1617 | 23 | p_palette = p_dec->fmt_out.video.p_palette |
1618 | 23 | = malloc( sizeof(video_palette_t) ); |
1619 | 23 | if( !p_palette ) |
1620 | 0 | { |
1621 | 0 | vlc_mutex_unlock(&p_sys->lock); |
1622 | 0 | b_error = true; |
1623 | 0 | av_frame_free(&frame); |
1624 | 0 | break; |
1625 | 0 | } |
1626 | 23 | static_assert( sizeof(p_palette->palette) == AVPALETTE_SIZE, |
1627 | 23 | "Palette size mismatch between vlc and libavutil" ); |
1628 | 23 | assert( frame->data[1] != NULL ); |
1629 | 23 | lavc_Frame8PaletteCopy( p_palette, frame->data[1] ); |
1630 | 23 | p_dec->fmt_out.video.i_chroma = VLC_CODEC_RGBP; |
1631 | 23 | if( decoder_UpdateVideoFormat( p_dec ) ) |
1632 | 0 | { |
1633 | 0 | vlc_mutex_unlock(&p_sys->lock); |
1634 | 0 | av_frame_free(&frame); |
1635 | 0 | continue; |
1636 | 0 | } |
1637 | 23 | } |
1638 | | |
1639 | 85.1k | picture_t *p_pic = FrameGetPicture( frame ); |
1640 | 85.1k | if( p_pic == NULL ) |
1641 | 1.14k | { /* When direct rendering is not used, get_format() and get_buffer() |
1642 | | * might not be called. The output video format must be set here |
1643 | | * then picture buffer can be allocated. */ |
1644 | 1.14k | if (p_sys->p_va == NULL |
1645 | 1.14k | && lavc_UpdateVideoFormat(p_dec, p_context, p_context->pix_fmt, |
1646 | 1.14k | p_context->pix_fmt) == 0 |
1647 | 1.14k | && decoder_UpdateVideoOutput(p_dec, NULL) == 0) |
1648 | 1.14k | p_pic = decoder_NewPicture(p_dec); |
1649 | | |
1650 | 1.14k | if( !p_pic ) |
1651 | 153 | { |
1652 | 153 | vlc_mutex_unlock(&p_sys->lock); |
1653 | 153 | av_frame_free(&frame); |
1654 | 153 | break; |
1655 | 153 | } |
1656 | | |
1657 | | /* Fill picture_t from AVFrame */ |
1658 | 993 | if( lavc_CopyPicture( p_dec, p_pic, frame ) != VLC_SUCCESS ) |
1659 | 64 | { |
1660 | 64 | vlc_mutex_unlock(&p_sys->lock); |
1661 | 64 | av_frame_free(&frame); |
1662 | 64 | picture_Release( p_pic ); |
1663 | 64 | break; |
1664 | 64 | } |
1665 | 993 | } |
1666 | 83.9k | else |
1667 | 83.9k | { |
1668 | | /* Some codecs can return the same frame multiple times. By the |
1669 | | * time that the same frame is returned a second time, it will be |
1670 | | * too late to clone the underlying picture. So clone proactively. |
1671 | | * A single picture CANNOT be queued multiple times. |
1672 | | */ |
1673 | 83.9k | p_pic = picture_Clone( p_pic ); |
1674 | 83.9k | if( unlikely(p_pic == NULL) ) |
1675 | 0 | { |
1676 | 0 | vlc_mutex_unlock(&p_sys->lock); |
1677 | 0 | av_frame_free(&frame); |
1678 | 0 | break; |
1679 | 0 | } |
1680 | 83.9k | } |
1681 | | |
1682 | 84.9k | if( !p_dec->fmt_in->video.i_sar_num || !p_dec->fmt_in->video.i_sar_den ) |
1683 | 54.7k | { |
1684 | | /* Fetch again the aspect ratio in case it changed */ |
1685 | 54.7k | p_dec->fmt_out.video.i_sar_num |
1686 | 54.7k | = p_context->sample_aspect_ratio.num; |
1687 | 54.7k | p_dec->fmt_out.video.i_sar_den |
1688 | 54.7k | = p_context->sample_aspect_ratio.den; |
1689 | | |
1690 | 54.7k | if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den ) |
1691 | 30.3k | { |
1692 | 30.3k | p_dec->fmt_out.video.i_sar_num = 1; |
1693 | 30.3k | p_dec->fmt_out.video.i_sar_den = 1; |
1694 | 30.3k | } |
1695 | 54.7k | } |
1696 | | |
1697 | | /* The palette can change on any frame; avcodec exposes the current one |
1698 | | * in frame->data[1]. The fmt_out palette and the chroma converter are |
1699 | | * only set up once (on the first frame above), so refresh the output |
1700 | | * picture's own palette every frame to keep the colors up-to-date. */ |
1701 | 84.9k | if( p_context->pix_fmt == AV_PIX_FMT_PAL8 && frame->data[1] != NULL |
1702 | 303 | && p_pic->format.p_palette != NULL ) |
1703 | 303 | lavc_Frame8PaletteCopy( p_pic->format.p_palette, frame->data[1] ); |
1704 | | |
1705 | 84.9k | p_pic->date = i_pts; |
1706 | | /* Hack to force display of still pictures */ |
1707 | 84.9k | p_pic->b_force = p_sys->b_first_frame; |
1708 | 84.9k | p_pic->i_nb_fields = 2 + frame->repeat_pict; |
1709 | 84.9k | #if LIBAVUTIL_VERSION_CHECK( 58, 7, 100 ) |
1710 | 84.9k | p_pic->b_progressive = !(frame->flags & AV_FRAME_FLAG_INTERLACED); |
1711 | 84.9k | p_pic->b_top_field_first = !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST); |
1712 | | #else |
1713 | | p_pic->b_progressive = !frame->interlaced_frame; |
1714 | | p_pic->b_top_field_first = frame->top_field_first; |
1715 | | #endif |
1716 | 84.9k | p_pic->b_still = p_frame_info && p_frame_info->b_eos; |
1717 | | |
1718 | 84.9k | if (DecodeSidedata(p_dec, frame, p_pic)) |
1719 | 0 | i_pts = VLC_TICK_INVALID; |
1720 | | |
1721 | 84.9k | av_frame_free(&frame); |
1722 | | |
1723 | | /* Send decoded frame to vout */ |
1724 | 84.9k | if (i_pts != VLC_TICK_INVALID) |
1725 | 70.1k | { |
1726 | 70.1k | p_sys->b_first_frame = false; |
1727 | 70.1k | vlc_mutex_unlock(&p_sys->lock); |
1728 | 70.1k | decoder_QueueVideo( p_dec, p_pic ); |
1729 | 70.1k | } |
1730 | 14.7k | else |
1731 | 14.7k | { |
1732 | 14.7k | vlc_mutex_unlock(&p_sys->lock); |
1733 | 14.7k | picture_Release( p_pic ); |
1734 | 14.7k | } |
1735 | 2.64M | } while( true ); |
1736 | | |
1737 | | /* After draining, we need to reset decoder with a flush */ |
1738 | 2.64M | if( b_drained ) |
1739 | 320k | avcodec_flush_buffers( p_sys->p_context ); |
1740 | | |
1741 | 2.64M | if( p_block ) |
1742 | 2.33M | block_Release( p_block ); |
1743 | | |
1744 | 2.64M | return b_error ? VLCDEC_ECRITICAL : VLCDEC_SUCCESS; |
1745 | 2.64M | } |
1746 | | |
1747 | | static int DecodeVideo( decoder_t *p_dec, block_t *p_block ) |
1748 | 2.64M | { |
1749 | 2.64M | decoder_sys_t *p_sys = p_dec->p_sys; |
1750 | 2.64M | block_t **pp_block = p_block ? &p_block : NULL /* drain signal */; |
1751 | | |
1752 | 2.64M | if( p_block && |
1753 | 2.33M | p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) |
1754 | 52.5k | { |
1755 | 52.5k | p_sys->i_late_frames = 0; |
1756 | 52.5k | p_sys->i_last_output_frame = -1; |
1757 | 52.5k | p_sys->framedrop = FRAMEDROP_NONE; |
1758 | | |
1759 | 52.5k | vlc_mutex_lock(&p_sys->lock); |
1760 | 52.5k | date_Set( &p_sys->pts, VLC_TICK_INVALID ); /* To make sure we recover properly */ |
1761 | 52.5k | vlc_mutex_unlock(&p_sys->lock); |
1762 | | |
1763 | 52.5k | cc_Flush( &p_sys->cc ); |
1764 | | |
1765 | 52.5k | if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) |
1766 | 0 | { |
1767 | 0 | block_Release( p_block ); |
1768 | 0 | p_block = NULL; /* output only */ |
1769 | 0 | } |
1770 | 52.5k | } |
1771 | | |
1772 | 2.64M | return DecodeBlock( p_dec, pp_block ); |
1773 | 2.64M | } |
1774 | | |
1775 | | /***************************************************************************** |
1776 | | * EndVideo: decoder destruction |
1777 | | ***************************************************************************** |
1778 | | * This function is called when the thread ends after a successful |
1779 | | * initialization. |
1780 | | *****************************************************************************/ |
1781 | | void EndVideoDec( vlc_object_t *obj ) |
1782 | 251k | { |
1783 | 251k | decoder_t *p_dec = (decoder_t *)obj; |
1784 | 251k | decoder_sys_t *p_sys = p_dec->p_sys; |
1785 | 251k | AVCodecContext *ctx = p_sys->p_context; |
1786 | | |
1787 | 251k | cc_Flush( &p_sys->cc ); |
1788 | 251k | avcodec_free_context( &ctx ); |
1789 | | |
1790 | 251k | if( p_sys->p_va ) |
1791 | 0 | ffmpeg_CloseVa(p_dec, NULL); |
1792 | | |
1793 | 251k | free( p_sys ); |
1794 | 251k | } |
1795 | | |
1796 | | /***************************************************************************** |
1797 | | * ffmpeg_InitCodec: setup codec extra initialization data for ffmpeg |
1798 | | *****************************************************************************/ |
1799 | | static void ffmpeg_InitCodec( decoder_t *p_dec ) |
1800 | 253k | { |
1801 | 253k | decoder_sys_t *p_sys = p_dec->p_sys; |
1802 | 253k | size_t i_size = p_dec->fmt_in->i_extra; |
1803 | | |
1804 | 253k | if( !i_size ) return; |
1805 | | |
1806 | 68.0k | if( p_sys->p_codec->id == AV_CODEC_ID_SVQ3 ) |
1807 | 0 | { |
1808 | 0 | uint8_t *p; |
1809 | |
|
1810 | 0 | p_sys->p_context->extradata_size = i_size + 12; |
1811 | 0 | p = p_sys->p_context->extradata = |
1812 | 0 | av_malloc( p_sys->p_context->extradata_size + |
1813 | 0 | AV_INPUT_BUFFER_PADDING_SIZE ); |
1814 | 0 | if( !p ) |
1815 | 0 | return; |
1816 | | |
1817 | 0 | memcpy( &p[0], "SVQ3", 4 ); |
1818 | 0 | memset( &p[4], 0, 8 ); |
1819 | 0 | memcpy( &p[12], p_dec->fmt_in->p_extra, i_size ); |
1820 | | |
1821 | | /* Now remove all atoms before the SMI one */ |
1822 | 0 | if( p_sys->p_context->extradata_size > 0x5a && |
1823 | 0 | strncmp( (char*)&p[0x56], "SMI ", 4 ) ) |
1824 | 0 | { |
1825 | 0 | uint8_t *psz = &p[0x52]; |
1826 | |
|
1827 | 0 | while( psz < &p[p_sys->p_context->extradata_size - 8] ) |
1828 | 0 | { |
1829 | 0 | uint_fast32_t atom_size = GetDWBE( psz ); |
1830 | 0 | if( atom_size <= 1 ) |
1831 | 0 | { |
1832 | | /* FIXME handle 1 as long size */ |
1833 | 0 | break; |
1834 | 0 | } |
1835 | 0 | if( !strncmp( (char*)&psz[4], "SMI ", 4 ) ) |
1836 | 0 | { |
1837 | 0 | memmove( &p[0x52], psz, |
1838 | 0 | &p[p_sys->p_context->extradata_size] - psz ); |
1839 | 0 | break; |
1840 | 0 | } |
1841 | | |
1842 | 0 | psz += atom_size; |
1843 | 0 | } |
1844 | 0 | } |
1845 | 0 | } |
1846 | 68.0k | else |
1847 | 68.0k | { |
1848 | 68.0k | p_sys->p_context->extradata_size = i_size; |
1849 | 68.0k | p_sys->p_context->extradata = |
1850 | 68.0k | av_malloc( i_size + AV_INPUT_BUFFER_PADDING_SIZE ); |
1851 | 68.0k | if( p_sys->p_context->extradata ) |
1852 | 68.0k | { |
1853 | 68.0k | memcpy( p_sys->p_context->extradata, |
1854 | 68.0k | p_dec->fmt_in->p_extra, i_size ); |
1855 | 68.0k | memset( p_sys->p_context->extradata + i_size, |
1856 | 68.0k | 0, AV_INPUT_BUFFER_PADDING_SIZE ); |
1857 | 68.0k | } |
1858 | 68.0k | } |
1859 | 68.0k | } |
1860 | | |
1861 | | static void lavc_ReleaseFrame(void *opaque, uint8_t *data) |
1862 | 587k | { |
1863 | 587k | (void) data; |
1864 | 587k | picture_t *picture = opaque; |
1865 | | |
1866 | 587k | picture_Release(picture); |
1867 | 587k | } |
1868 | | |
1869 | | static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags) |
1870 | 0 | { |
1871 | 0 | decoder_t *dec = ctx->opaque; |
1872 | 0 | decoder_sys_t *p_sys = dec->p_sys; |
1873 | 0 | vlc_va_t *va = p_sys->p_va; |
1874 | |
|
1875 | 0 | if(!FrameCanStoreInfo(frame)) |
1876 | 0 | return -1; |
1877 | | |
1878 | 0 | picture_t *pic; |
1879 | 0 | pic = decoder_NewPicture(dec); |
1880 | 0 | if (pic == NULL) |
1881 | 0 | return -1; |
1882 | | |
1883 | | /* data[3] will contains the format-specific surface handle. */ |
1884 | 0 | if (vlc_va_Get(va, pic, ctx, frame)) |
1885 | 0 | { |
1886 | 0 | msg_Err(dec, "hardware acceleration picture allocation failed"); |
1887 | 0 | picture_Release(pic); |
1888 | 0 | return -1; |
1889 | 0 | } |
1890 | | |
1891 | 0 | AVBufferRef *buf = av_buffer_create(NULL, 0, lavc_ReleaseFrame, pic, flags); |
1892 | 0 | if (unlikely(buf == NULL)) |
1893 | 0 | { |
1894 | 0 | lavc_ReleaseFrame(pic, NULL); |
1895 | 0 | return -1; |
1896 | 0 | } |
1897 | | |
1898 | | /* frame->buf[0] must be valid but can be previously set by the VA module. */ |
1899 | 0 | if (frame->buf[0] == NULL) |
1900 | 0 | frame->buf[0] = buf; |
1901 | 0 | else |
1902 | 0 | { |
1903 | 0 | AVBufferRef **extended_buf = av_realloc_array(frame->extended_buf, |
1904 | 0 | sizeof(*extended_buf), |
1905 | 0 | frame->nb_extended_buf + 1); |
1906 | 0 | if(!extended_buf) |
1907 | 0 | { |
1908 | 0 | av_buffer_unref(&buf); |
1909 | 0 | return -1; |
1910 | 0 | } |
1911 | 0 | frame->extended_buf = extended_buf; |
1912 | 0 | frame->extended_buf[frame->nb_extended_buf++] = buf; |
1913 | 0 | } |
1914 | | |
1915 | 0 | FrameSetPicture( frame, pic ); |
1916 | 0 | return 0; |
1917 | 0 | } |
1918 | | |
1919 | | static int lavc_dr_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags) |
1920 | 197k | { |
1921 | 197k | decoder_t *dec = ctx->opaque; |
1922 | 197k | decoder_sys_t *sys = dec->p_sys; |
1923 | | |
1924 | 197k | if (sys->b_dr_failure) |
1925 | 0 | return -1; |
1926 | | |
1927 | 197k | if (ctx->pix_fmt == AV_PIX_FMT_PAL8) |
1928 | 416 | return -1; |
1929 | | |
1930 | 197k | picture_t *pic = decoder_NewPicture(dec); |
1931 | 197k | if (pic == NULL) |
1932 | 189 | return -1; |
1933 | | |
1934 | 197k | int width = frame->width; |
1935 | 197k | int height = frame->height; |
1936 | 197k | int aligns[AV_NUM_DATA_POINTERS]; |
1937 | | |
1938 | 197k | avcodec_align_dimensions2(ctx, &width, &height, aligns); |
1939 | | |
1940 | | /* Check that the picture is suitable for libavcodec */ |
1941 | 197k | assert(pic->p[0].i_pitch >= width * pic->p[0].i_pixel_pitch); |
1942 | 197k | assert(pic->p[0].i_lines >= height); |
1943 | | |
1944 | 784k | for (int i = 0; i < pic->i_planes; i++) |
1945 | 587k | { |
1946 | 587k | if (pic->p[i].i_pitch % aligns[i]) |
1947 | 0 | { |
1948 | 0 | msg_Warn(dec, "plane %d: pitch not aligned (%d%%%d): disabling direct rendering", |
1949 | 0 | i, pic->p[i].i_pitch, aligns[i]); |
1950 | 0 | sys->b_dr_failure = true; |
1951 | 0 | goto error; |
1952 | 0 | } |
1953 | 587k | if (((uintptr_t)pic->p[i].p_pixels) % aligns[i]) |
1954 | 0 | { |
1955 | 0 | msg_Warn(dec, "plane %d not aligned: disabling direct rendering", i); |
1956 | 0 | sys->b_dr_failure = true; |
1957 | 0 | goto error; |
1958 | 0 | } |
1959 | 587k | } |
1960 | | |
1961 | | /* Allocate buffer references and initialize planes */ |
1962 | 197k | assert(pic->i_planes < PICTURE_PLANE_MAX); |
1963 | 197k | static_assert(PICTURE_PLANE_MAX <= AV_NUM_DATA_POINTERS, "Oops!"); |
1964 | | |
1965 | 784k | for (int i = 0; i < pic->i_planes; i++) |
1966 | 587k | { |
1967 | 587k | uint8_t *data = pic->p[i].p_pixels; |
1968 | 587k | int size = pic->p[i].i_pitch * pic->p[i].i_lines; |
1969 | | |
1970 | 587k | frame->data[i] = data; |
1971 | 587k | frame->linesize[i] = pic->p[i].i_pitch; |
1972 | 587k | frame->buf[i] = av_buffer_create(data, size, lavc_ReleaseFrame, |
1973 | 587k | pic, flags); |
1974 | 587k | if (unlikely(frame->buf[i] == NULL)) |
1975 | 0 | { |
1976 | 0 | while (i > 0) |
1977 | 0 | av_buffer_unref(&frame->buf[--i]); |
1978 | 0 | goto error; |
1979 | 0 | } |
1980 | 587k | picture_Hold(pic); |
1981 | 587k | } |
1982 | | |
1983 | 197k | FrameSetPicture( frame, pic ); |
1984 | | /* The loop above held one reference to the picture for each plane. */ |
1985 | 197k | assert(pic->i_planes > 0); |
1986 | 197k | picture_Release(pic); |
1987 | 197k | return 0; |
1988 | 0 | error: |
1989 | 0 | picture_Release(pic); |
1990 | 0 | return -1; |
1991 | 197k | } |
1992 | | |
1993 | | /** |
1994 | | * Callback used by libavcodec to get a frame buffer. |
1995 | | * |
1996 | | * It is used for direct rendering as well as to get the right PTS for each |
1997 | | * decoded picture (even in indirect rendering mode). |
1998 | | */ |
1999 | | static int lavc_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags) |
2000 | 201k | { |
2001 | 201k | decoder_t *dec = ctx->opaque; |
2002 | 201k | decoder_sys_t *sys = dec->p_sys; |
2003 | | |
2004 | 1.81M | for (unsigned i = 0; i < AV_NUM_DATA_POINTERS; i++) |
2005 | 1.60M | { |
2006 | 1.60M | frame->data[i] = NULL; |
2007 | 1.60M | frame->linesize[i] = 0; |
2008 | 1.60M | frame->buf[i] = NULL; |
2009 | 1.60M | } |
2010 | 201k | FrameSetPicture( frame, NULL ); |
2011 | | |
2012 | 201k | if (sys->p_va == NULL) |
2013 | 201k | { |
2014 | 201k | if (!sys->b_direct_rendering) |
2015 | 0 | return avcodec_default_get_buffer2(ctx, frame, flags); |
2016 | | |
2017 | 201k | vlc_mutex_lock(&sys->lock); |
2018 | | /* Most unaccelerated decoders do not call get_format(), so we need to |
2019 | | * update the output video format here. The MT semaphore must be held |
2020 | | * to protect p_dec->fmt_out. */ |
2021 | 201k | if (lavc_UpdateVideoFormat(dec, ctx, ctx->pix_fmt, ctx->pix_fmt) || |
2022 | 197k | decoder_UpdateVideoOutput(dec, NULL)) |
2023 | 3.47k | { |
2024 | 3.47k | vlc_mutex_unlock(&sys->lock); |
2025 | 3.47k | return -1; |
2026 | 3.47k | } |
2027 | 197k | vlc_mutex_unlock(&sys->lock); |
2028 | 197k | } |
2029 | | |
2030 | 197k | if (sys->p_va != NULL) |
2031 | 0 | { |
2032 | 0 | int ret = lavc_va_GetFrame(ctx, frame, flags); |
2033 | 0 | return ret; |
2034 | 0 | } |
2035 | | |
2036 | | /* Some codecs set pix_fmt only after the 1st frame has been decoded, |
2037 | | * so we need to check for direct rendering again. */ |
2038 | 197k | int ret = lavc_dr_GetFrame(ctx, frame, flags); |
2039 | 197k | if (ret) |
2040 | 605 | ret = avcodec_default_get_buffer2(ctx, frame, flags); |
2041 | 197k | return ret; |
2042 | 197k | } |
2043 | | |
2044 | | static enum AVPixelFormat ffmpeg_GetFormat( AVCodecContext *p_context, |
2045 | | const enum AVPixelFormat *pi_fmt ) |
2046 | 20.9k | { |
2047 | 20.9k | decoder_t *p_dec = p_context->opaque; |
2048 | 20.9k | decoder_sys_t *p_sys = p_dec->p_sys; |
2049 | 20.9k | video_format_t fmt; |
2050 | | |
2051 | | /* Enumerate available formats */ |
2052 | 20.9k | enum AVPixelFormat defaultfmt = avcodec_default_get_format(p_context, pi_fmt); |
2053 | 20.9k | enum AVPixelFormat swfmt = AV_PIX_FMT_NONE; |
2054 | 20.9k | enum AVPixelFormat skipfmt = AV_PIX_FMT_NONE; |
2055 | 20.9k | bool can_hwaccel = false; |
2056 | | |
2057 | 41.8k | for (size_t i = 0; pi_fmt[i] != AV_PIX_FMT_NONE; i++) |
2058 | 20.9k | { |
2059 | 20.9k | const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(pi_fmt[i]); |
2060 | 20.9k | if (dsc == NULL) |
2061 | 0 | continue; |
2062 | 20.9k | bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0; |
2063 | | |
2064 | 20.9k | msg_Dbg( p_dec, "available %sware decoder output format %d (%s)", |
2065 | 20.9k | hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name ); |
2066 | 20.9k | if (hwaccel) |
2067 | 0 | { |
2068 | | /* The default fmt is a hw format, it can happen with some va |
2069 | | * implementations (when using a hw_device_ctx). */ |
2070 | 0 | if (defaultfmt == pi_fmt[i]) |
2071 | 0 | defaultfmt = AV_PIX_FMT_NONE; |
2072 | |
|
2073 | 0 | can_hwaccel = true; |
2074 | 0 | } |
2075 | 20.9k | else if (swfmt == AV_PIX_FMT_NONE && !p_sys->b_hardware_only) |
2076 | 20.9k | swfmt = pi_fmt[i]; |
2077 | 20.9k | } |
2078 | | |
2079 | | /* Use the default fmt in priority of any sw fmt if the default fmt is a hw |
2080 | | * one */ |
2081 | 20.9k | if (defaultfmt != AV_PIX_FMT_NONE) |
2082 | 20.9k | { |
2083 | 20.9k | if (p_sys->b_hardware_only) |
2084 | 0 | { |
2085 | 0 | if (defaultfmt != p_context->sw_pix_fmt) |
2086 | 0 | { |
2087 | | // the source format changed and we didn't detect it |
2088 | 0 | vlc_assert_unreachable(); |
2089 | 0 | } |
2090 | 0 | } |
2091 | 20.9k | swfmt = defaultfmt; |
2092 | 20.9k | } |
2093 | | |
2094 | 20.9k | if (p_sys->pix_fmt == AV_PIX_FMT_NONE) |
2095 | 20.9k | goto no_reuse; |
2096 | | |
2097 | | /* If the format did not actually change (e.g. seeking), try to reuse the |
2098 | | * existing output format, and if present, hardware acceleration back-end. |
2099 | | * This avoids resetting the pipeline downstream. This also avoids |
2100 | | * needlessly probing for hardware acceleration support. */ |
2101 | 0 | if (lavc_GetVideoFormat(p_dec, &fmt, p_context, p_sys->pix_fmt, swfmt) != 0) |
2102 | 0 | { |
2103 | 0 | msg_Dbg(p_dec, "get format failed"); |
2104 | 0 | goto no_reuse; |
2105 | 0 | } |
2106 | 0 | if (fmt.i_width != p_sys->decoder_width || |
2107 | 0 | fmt.i_height != p_sys->decoder_height) |
2108 | 0 | { |
2109 | 0 | msg_Dbg(p_dec, "mismatched dimensions %ux%u was %ux%u", fmt.i_width, fmt.i_height, |
2110 | 0 | p_sys->decoder_width, p_sys->decoder_height); |
2111 | 0 | goto no_reuse; |
2112 | 0 | } |
2113 | 0 | if (p_context->profile != p_sys->profile || p_context->level > p_sys->level) |
2114 | 0 | { |
2115 | 0 | msg_Dbg(p_dec, "mismatched profile level %d/%d was %d/%d", p_context->profile, |
2116 | 0 | p_context->level, p_sys->profile, p_sys->level); |
2117 | 0 | goto no_reuse; |
2118 | 0 | } |
2119 | | |
2120 | 0 | for (size_t i = 0; pi_fmt[i] != AV_PIX_FMT_NONE; i++) |
2121 | 0 | if (pi_fmt[i] == p_sys->pix_fmt) |
2122 | 0 | { |
2123 | 0 | if (p_sys->use_hwframes) |
2124 | 0 | { |
2125 | | /* When using hwframes API, ffmpeg is reseting the hardware |
2126 | | * context of the AVCodecContext before calling the |
2127 | | * `get_format` callback. Therefore, the va context need to be |
2128 | | * closed and opened again. */ |
2129 | 0 | msg_Dbg(p_dec, "recreating decoder output format %d", pi_fmt[i]); |
2130 | 0 | int ret = ffmpeg_RecreateVa(p_dec, p_context, swfmt); |
2131 | 0 | if (ret != VLC_SUCCESS) |
2132 | 0 | { |
2133 | 0 | msg_Err(p_dec, "error restarting va module"); |
2134 | 0 | skipfmt = p_sys->pix_fmt; /* Don't retry this fmt */ |
2135 | 0 | p_sys->pix_fmt = AV_PIX_FMT_NONE; |
2136 | 0 | goto no_reuse; |
2137 | 0 | } |
2138 | 0 | } |
2139 | 0 | else |
2140 | 0 | msg_Dbg(p_dec, "reusing decoder output format %d", pi_fmt[i]); |
2141 | 0 | return p_sys->pix_fmt; |
2142 | 0 | } |
2143 | | |
2144 | 20.9k | no_reuse: |
2145 | 20.9k | if (p_sys->p_va != NULL) |
2146 | 0 | { |
2147 | 0 | msg_Err(p_dec, "existing hardware acceleration cannot be reused"); |
2148 | | // the decoder changes have to be handled outside of lavc so that |
2149 | | // switching to a software decoder will not silently decode nothing |
2150 | | // (get_format will fail to use AV_PIX_FMT_NONE) |
2151 | 0 | assert(!p_sys->b_hardware_only); |
2152 | 0 | ffmpeg_CloseVa(p_dec, p_context); |
2153 | 0 | } |
2154 | | |
2155 | 20.9k | p_sys->profile = p_context->profile; |
2156 | 20.9k | p_sys->level = p_context->level; |
2157 | | |
2158 | 20.9k | if (!can_hwaccel) |
2159 | 20.9k | return swfmt; |
2160 | | |
2161 | 0 | const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(swfmt); |
2162 | |
|
2163 | 0 | for( size_t i = 0; hwfmts[i] != AV_PIX_FMT_NONE; i++ ) |
2164 | 0 | { |
2165 | 0 | enum AVPixelFormat hwfmt = AV_PIX_FMT_NONE; |
2166 | 0 | for( size_t j = 0; hwfmt == AV_PIX_FMT_NONE && pi_fmt[j] != AV_PIX_FMT_NONE; j++ ) |
2167 | 0 | if( hwfmts[i] == pi_fmt[j] ) |
2168 | 0 | hwfmt = hwfmts[i]; |
2169 | |
|
2170 | 0 | if (hwfmt == skipfmt) |
2171 | 0 | continue; |
2172 | | |
2173 | 0 | vlc_decoder_device *dec_device; |
2174 | 0 | int ret = lavc_UpdateHWVideoFormat(p_dec, p_context, hwfmt, swfmt, |
2175 | 0 | &dec_device); |
2176 | 0 | if (ret != VLC_SUCCESS) |
2177 | 0 | continue; |
2178 | | |
2179 | 0 | ret = ffmpeg_OpenVa(p_dec, p_context, hwfmt, src_desc, dec_device, NULL); |
2180 | 0 | if (dec_device != NULL) |
2181 | 0 | vlc_decoder_device_Release(dec_device); |
2182 | |
|
2183 | 0 | if (ret != VLC_SUCCESS) |
2184 | 0 | continue; |
2185 | | |
2186 | 0 | return hwfmt; |
2187 | 0 | } |
2188 | | |
2189 | | /* Fallback to default behaviour */ |
2190 | 0 | p_sys->pix_fmt = swfmt; |
2191 | 0 | return swfmt; |
2192 | 0 | } |