input: add an input_item_t arg to input_CreateFilename()
[vlc.git] / modules / codec / omxil / mediacodec.c
blob2a87dbe5c00c7386b849e9a741f050013d0a8fad
1 /*****************************************************************************
2 * mediacodec.c: Video decoder module using the Android MediaCodec API
3 *****************************************************************************
4 * Copyright (C) 2012 Martin Storsjo
6 * Authors: Martin Storsjo <martin@martin.st>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 /*****************************************************************************
24 * Preamble
25 *****************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
30 #include <stdint.h>
31 #include <assert.h>
33 #include <vlc_common.h>
34 #include <vlc_aout.h>
35 #include <vlc_plugin.h>
36 #include <vlc_codec.h>
37 #include <vlc_block_helper.h>
38 #include <vlc_timestamp_helper.h>
39 #include <vlc_threads.h>
40 #include <vlc_bits.h>
42 #include "mediacodec.h"
43 #include "../codec/hxxx_helper.h"
44 #include <OMX_Core.h>
45 #include <OMX_Component.h>
46 #include "omxil_utils.h"
47 #include "../../video_output/android/display.h"
49 #define BLOCK_FLAG_CSD (0x01 << BLOCK_FLAG_PRIVATE_SHIFT)
51 #define DECODE_FLAG_RESTART (0x01)
52 #define DECODE_FLAG_DRAIN (0x02)
53 /**
54 * Callback called when a new block is processed from DecodeBlock.
55 * It returns -1 in case of error, 0 if block should be dropped, 1 otherwise.
57 typedef int (*dec_on_new_block_cb)(decoder_t *, block_t **);
59 /**
60 * Callback called when decoder is flushing.
62 typedef void (*dec_on_flush_cb)(decoder_t *);
64 /**
65 * Callback called when DecodeBlock try to get an output buffer (pic or block).
66 * It returns -1 in case of error, or the number of output buffer returned.
68 typedef int (*dec_process_output_cb)(decoder_t *, mc_api_out *, picture_t **,
69 block_t **);
71 typedef struct
73 mc_api api;
75 /* Codec Specific Data buffer: sent in DecodeBlock after a start or a flush
76 * with the BUFFER_FLAG_CODEC_CONFIG flag.*/
77 #define MAX_CSD_COUNT 3
78 block_t *pp_csd[MAX_CSD_COUNT];
79 size_t i_csd_count;
80 size_t i_csd_send;
82 bool b_has_format;
84 int64_t i_preroll_end;
85 int i_quirks;
87 /* Specific Audio/Video callbacks */
88 dec_on_new_block_cb pf_on_new_block;
89 dec_on_flush_cb pf_on_flush;
90 dec_process_output_cb pf_process_output;
92 vlc_mutex_t lock;
93 vlc_thread_t out_thread;
94 /* Cond used to signal the output thread */
95 vlc_cond_t cond;
96 /* Cond used to signal the decoder thread */
97 vlc_cond_t dec_cond;
98 /* Set to true by pf_flush to signal the output thread to flush */
99 bool b_flush_out;
100 /* If true, the output thread will start to dequeue output pictures */
101 bool b_output_ready;
102 /* If true, the first input block was successfully dequeued */
103 bool b_input_dequeued;
104 bool b_aborted;
105 bool b_drained;
106 bool b_adaptive;
107 int i_decode_flags;
109 union
111 struct
113 void *p_surface, *p_jsurface;
114 unsigned i_angle;
115 unsigned i_input_width, i_input_height;
116 unsigned int i_stride, i_slice_height;
117 int i_pixel_format;
118 struct hxxx_helper hh;
119 /* stores the inflight picture for each output buffer or NULL */
120 picture_sys_t** pp_inflight_pictures;
121 unsigned int i_inflight_pictures;
122 timestamp_fifo_t *timestamp_fifo;
123 int i_mpeg_dar_num, i_mpeg_dar_den;
124 } video;
125 struct {
126 date_t i_end_date;
127 int i_channels;
128 bool b_extract;
129 /* Some audio decoders need a valid channel count */
130 bool b_need_channels;
131 int pi_extraction[AOUT_CHAN_MAX];
132 } audio;
134 } decoder_sys_t;
136 /*****************************************************************************
137 * Local prototypes
138 *****************************************************************************/
139 static int OpenDecoderJni(vlc_object_t *);
140 static int OpenDecoderNdk(vlc_object_t *);
141 static void CleanDecoder(decoder_t *);
142 static void CloseDecoder(vlc_object_t *);
144 static int Video_OnNewBlock(decoder_t *, block_t **);
145 static int VideoHXXX_OnNewBlock(decoder_t *, block_t **);
146 static int VideoMPEG2_OnNewBlock(decoder_t *, block_t **);
147 static int VideoVC1_OnNewBlock(decoder_t *, block_t **);
148 static void Video_OnFlush(decoder_t *);
149 static int Video_ProcessOutput(decoder_t *, mc_api_out *, picture_t **,
150 block_t **);
151 static int DecodeBlock(decoder_t *, block_t *);
153 static int Audio_OnNewBlock(decoder_t *, block_t **);
154 static void Audio_OnFlush(decoder_t *);
155 static int Audio_ProcessOutput(decoder_t *, mc_api_out *, picture_t **,
156 block_t **);
158 static void DecodeFlushLocked(decoder_t *);
159 static void DecodeFlush(decoder_t *);
160 static void StopMediaCodec(decoder_t *);
161 static void *OutThread(void *);
163 static void InvalidateAllPictures(decoder_t *);
164 static void RemoveInflightPictures(decoder_t *);
166 /*****************************************************************************
167 * Module descriptor
168 *****************************************************************************/
169 #define MEDIACODEC_ENABLE_TEXT N_("Enable hardware acceleration")
171 #define DIRECTRENDERING_TEXT "Android direct rendering"
172 #define DIRECTRENDERING_LONGTEXT \
173 "Enable Android direct rendering using opaque buffers."
175 #define MEDIACODEC_AUDIO_TEXT "Use MediaCodec for audio decoding"
176 #define MEDIACODEC_AUDIO_LONGTEXT "Still experimental."
178 #define MEDIACODEC_TUNNELEDPLAYBACK_TEXT "Use a tunneled surface for playback"
180 #define CFG_PREFIX "mediacodec-"
182 vlc_module_begin ()
183 set_description("Video decoder using Android MediaCodec via NDK")
184 set_category(CAT_INPUT)
185 set_subcategory(SUBCAT_INPUT_VCODEC)
186 set_section(N_("Decoding"), NULL)
187 set_capability("video decoder", 800)
188 add_bool("mediacodec", true, MEDIACODEC_ENABLE_TEXT, NULL, false)
189 add_bool(CFG_PREFIX "dr", true,
190 DIRECTRENDERING_TEXT, DIRECTRENDERING_LONGTEXT, true)
191 add_bool(CFG_PREFIX "audio", false,
192 MEDIACODEC_AUDIO_TEXT, MEDIACODEC_AUDIO_LONGTEXT, true)
193 add_bool(CFG_PREFIX "tunneled-playback", false,
194 MEDIACODEC_TUNNELEDPLAYBACK_TEXT, NULL, true)
195 set_callbacks(OpenDecoderNdk, CloseDecoder)
196 add_shortcut("mediacodec_ndk")
197 add_submodule ()
198 set_capability("audio decoder", 0)
199 set_callbacks(OpenDecoderNdk, CloseDecoder)
200 add_shortcut("mediacodec_ndk")
201 add_submodule ()
202 set_description("Video decoder using Android MediaCodec via JNI")
203 set_capability("video decoder", 0)
204 set_callbacks(OpenDecoderJni, CloseDecoder)
205 add_shortcut("mediacodec_jni")
206 add_submodule ()
207 set_capability("audio decoder", 0)
208 set_callbacks(OpenDecoderJni, CloseDecoder)
209 add_shortcut("mediacodec_jni")
210 vlc_module_end ()
212 static void CSDFree(decoder_t *p_dec)
214 decoder_sys_t *p_sys = p_dec->p_sys;
216 for (unsigned int i = 0; i < p_sys->i_csd_count; ++i)
217 block_Release(p_sys->pp_csd[i]);
218 p_sys->i_csd_count = 0;
221 /* Init the p_sys->p_csd that will be sent from DecodeBlock */
222 static void CSDInit(decoder_t *p_dec, block_t *p_blocks, size_t i_count)
224 decoder_sys_t *p_sys = p_dec->p_sys;
225 assert(i_count >= 0 && i_count <= 3);
227 CSDFree(p_dec);
229 for (size_t i = 0; i < i_count; ++i)
231 assert(p_blocks != NULL);
232 p_sys->pp_csd[i] = p_blocks;
233 p_sys->pp_csd[i]->i_flags = BLOCK_FLAG_CSD;
234 p_blocks = p_blocks->p_next;
235 p_sys->pp_csd[i]->p_next = NULL;
238 p_sys->i_csd_count = i_count;
239 p_sys->i_csd_send = 0;
242 static int CSDDup(decoder_t *p_dec, const void *p_buf, size_t i_buf)
244 block_t *p_block = block_Alloc(i_buf);
245 if (!p_block)
246 return VLC_ENOMEM;
247 memcpy(p_block->p_buffer, p_buf, i_buf);
249 CSDInit(p_dec, p_block, 1);
250 return VLC_SUCCESS;
253 static void HXXXInitSize(decoder_t *p_dec, bool *p_size_changed)
255 if (p_size_changed)
257 decoder_sys_t *p_sys = p_dec->p_sys;
258 struct hxxx_helper *hh = &p_sys->video.hh;
259 unsigned i_w, i_h, i_vw, i_vh;
260 hxxx_helper_get_current_picture_size(hh, &i_w, &i_h, &i_vw, &i_vh);
262 *p_size_changed = (i_w != p_sys->video.i_input_width
263 || i_h != p_sys->video.i_input_height);
264 p_sys->video.i_input_width = i_w;
265 p_sys->video.i_input_height = i_h;
266 /* fmt_out video size will be updated by mediacodec output callback */
270 /* Fill the p_sys->p_csd struct with H264 Parameter Sets */
271 static int H264SetCSD(decoder_t *p_dec, bool *p_size_changed)
273 decoder_sys_t *p_sys = p_dec->p_sys;
274 struct hxxx_helper *hh = &p_sys->video.hh;
275 assert(hh->h264.i_sps_count > 0 || hh->h264.i_pps_count > 0);
277 block_t *p_spspps_blocks = h264_helper_get_annexb_config(hh);
279 if (p_spspps_blocks != NULL)
280 CSDInit(p_dec, p_spspps_blocks, 2);
282 HXXXInitSize(p_dec, p_size_changed);
284 return VLC_SUCCESS;
287 /* Fill the p_sys->p_csd struct with HEVC Parameter Sets */
288 static int HEVCSetCSD(decoder_t *p_dec, bool *p_size_changed)
290 decoder_sys_t *p_sys = p_dec->p_sys;
291 struct hxxx_helper *hh = &p_sys->video.hh;
293 assert(hh->hevc.i_vps_count > 0 || hh->hevc.i_sps_count > 0 ||
294 hh->hevc.i_pps_count > 0 );
296 block_t *p_xps_blocks = hevc_helper_get_annexb_config(hh);
297 if (p_xps_blocks != NULL)
299 block_t *p_monolith = block_ChainGather(p_xps_blocks);
300 if (p_monolith == NULL)
302 block_ChainRelease(p_xps_blocks);
303 return VLC_ENOMEM;
305 CSDInit(p_dec, p_monolith, 1);
308 HXXXInitSize(p_dec, p_size_changed);
309 return VLC_SUCCESS;
312 static int ParseVideoExtraH264(decoder_t *p_dec, uint8_t *p_extra, int i_extra)
314 decoder_sys_t *p_sys = p_dec->p_sys;
315 struct hxxx_helper *hh = &p_sys->video.hh;
317 int i_ret = hxxx_helper_set_extra(hh, p_extra, i_extra);
318 if (i_ret != VLC_SUCCESS)
319 return i_ret;
320 assert(hh->pf_process_block != NULL);
322 if (p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_ADAPTIVE)
323 p_sys->b_adaptive = true;
325 p_sys->pf_on_new_block = VideoHXXX_OnNewBlock;
327 if (hh->h264.i_sps_count > 0 || hh->h264.i_pps_count > 0)
328 return H264SetCSD(p_dec, NULL);
329 return VLC_SUCCESS;
332 static int ParseVideoExtraHEVC(decoder_t *p_dec, uint8_t *p_extra, int i_extra)
334 decoder_sys_t *p_sys = p_dec->p_sys;
335 struct hxxx_helper *hh = &p_sys->video.hh;
337 int i_ret = hxxx_helper_set_extra(hh, p_extra, i_extra);
338 if (i_ret != VLC_SUCCESS)
339 return i_ret;
340 assert(hh->pf_process_block != NULL);
342 if (p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_ADAPTIVE)
343 p_sys->b_adaptive = true;
345 p_sys->pf_on_new_block = VideoHXXX_OnNewBlock;
347 if (hh->hevc.i_vps_count > 0 || hh->hevc.i_sps_count > 0 ||
348 hh->hevc.i_pps_count > 0 )
349 return HEVCSetCSD(p_dec, NULL);
350 return VLC_SUCCESS;
353 static int ParseVideoExtraVc1(decoder_t *p_dec, uint8_t *p_extra, int i_extra)
355 decoder_sys_t *p_sys = p_dec->p_sys;
356 int offset = 0;
358 if (i_extra < 4)
359 return VLC_EGENERIC;
361 /* Initialisation data starts with : 0x00 0x00 0x01 0x0f */
362 /* Skipping unecessary data */
363 static const uint8_t vc1_start_code[4] = {0x00, 0x00, 0x01, 0x0f};
364 for (; offset < i_extra - 4 ; ++offset)
366 if (!memcmp(&p_extra[offset], vc1_start_code, 4))
367 break;
370 /* Could not find the sequence header start code */
371 if (offset >= i_extra - 4)
372 return VLC_EGENERIC;
374 p_sys->pf_on_new_block = VideoVC1_OnNewBlock;
375 return CSDDup(p_dec, p_extra + offset, i_extra - offset);
378 static int ParseVideoExtraWmv3(decoder_t *p_dec, uint8_t *p_extra, int i_extra)
380 /* WMV3 initialisation data :
381 * 8 fixed bytes
382 * 4 extradata bytes
383 * 4 height bytes (little endian)
384 * 4 width bytes (little endian)
385 * 16 fixed bytes */
387 if (i_extra < 4)
388 return VLC_EGENERIC;
390 uint8_t p_data[36] = {
391 0x8e, 0x01, 0x00, 0xc5, /* Fixed bytes values */
392 0x04, 0x00, 0x00, 0x00, /* Same */
393 0x00, 0x00, 0x00, 0x00, /* extradata emplacement */
394 0x00, 0x00, 0x00, 0x00, /* height emplacement (little endian) */
395 0x00, 0x00, 0x00, 0x00, /* width emplacement (little endian) */
396 0x0c, 0x00, 0x00, 0x00, /* Fixed byte pattern */
397 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00
402 /* Adding extradata */
403 memcpy(&p_data[8], p_extra, 4);
404 /* Adding height and width, little endian */
405 SetDWLE(&(p_data[12]), p_dec->fmt_in.video.i_height);
406 SetDWLE(&(p_data[16]), p_dec->fmt_in.video.i_width);
408 return CSDDup(p_dec, p_data, sizeof(p_data));
411 static int ParseExtra(decoder_t *p_dec)
413 decoder_sys_t *p_sys = p_dec->p_sys;
414 uint8_t *p_extra = p_dec->fmt_in.p_extra;
415 int i_extra = p_dec->fmt_in.i_extra;
417 switch (p_dec->fmt_in.i_codec)
419 case VLC_CODEC_H264:
420 return ParseVideoExtraH264(p_dec, p_extra, i_extra);
421 case VLC_CODEC_HEVC:
422 return ParseVideoExtraHEVC(p_dec, p_extra, i_extra);
423 case VLC_CODEC_WMV3:
424 return ParseVideoExtraWmv3(p_dec, p_extra, i_extra);
425 case VLC_CODEC_VC1:
426 return ParseVideoExtraVc1(p_dec, p_extra, i_extra);
427 case VLC_CODEC_MP4V:
428 if (!i_extra && p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_ADAPTIVE)
429 p_sys->b_adaptive = true;
430 break;
431 case VLC_CODEC_MPGV:
432 case VLC_CODEC_MP2V:
433 p_sys->pf_on_new_block = VideoMPEG2_OnNewBlock;
434 break;
436 /* Set default CSD */
437 if (p_dec->fmt_in.i_extra)
438 return CSDDup(p_dec, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra);
439 else
440 return VLC_SUCCESS;
443 static int UpdateVout(decoder_t *p_dec)
445 decoder_sys_t *p_sys = p_dec->p_sys;
447 if ((p_dec->fmt_in.i_codec == VLC_CODEC_MPGV ||
448 p_dec->fmt_in.i_codec == VLC_CODEC_MP2V) &&
449 (p_sys->video.i_mpeg_dar_num * p_sys->video.i_mpeg_dar_den != 0))
451 p_dec->fmt_out.video.i_sar_num =
452 p_sys->video.i_mpeg_dar_num * p_dec->fmt_out.video.i_height;
453 p_dec->fmt_out.video.i_sar_den =
454 p_sys->video.i_mpeg_dar_den * p_dec->fmt_out.video.i_width;
457 /* If MediaCodec can handle the rotation, reset the orientation to
458 * Normal in order to ask the vout not to rotate. */
459 if (p_sys->video.i_angle != 0)
461 assert(p_dec->fmt_out.i_codec == VLC_CODEC_ANDROID_OPAQUE);
462 p_dec->fmt_out.video.orientation = p_dec->fmt_in.video.orientation;
463 video_format_TransformTo(&p_dec->fmt_out.video, ORIENT_NORMAL);
466 if (decoder_UpdateVideoFormat(p_dec) != 0)
467 return VLC_EGENERIC;
469 if (p_dec->fmt_out.i_codec != VLC_CODEC_ANDROID_OPAQUE)
470 return VLC_SUCCESS;
472 /* Direct rendering: get the surface attached to the VOUT */
473 picture_t *p_dummy_hwpic = decoder_NewPicture(p_dec);
474 if (p_dummy_hwpic == NULL)
475 return VLC_EGENERIC;
477 picture_sys_t *p_picsys = p_dummy_hwpic->p_sys;
478 assert(p_picsys);
479 assert(p_picsys->hw.p_surface);
480 assert(p_picsys->hw.p_jsurface);
482 p_sys->video.p_surface = p_picsys->hw.p_surface;
483 p_sys->video.p_jsurface = p_picsys->hw.p_jsurface;
484 picture_Release(p_dummy_hwpic);
485 return VLC_SUCCESS;
488 /*****************************************************************************
489 * StartMediaCodec: Create the mediacodec instance
490 *****************************************************************************/
491 static int StartMediaCodec(decoder_t *p_dec)
493 decoder_sys_t *p_sys = p_dec->p_sys;
494 union mc_api_args args;
496 if (p_dec->fmt_in.i_cat == VIDEO_ES)
498 args.video.i_width = p_dec->fmt_out.video.i_width;
499 args.video.i_height = p_dec->fmt_out.video.i_height;
500 args.video.i_angle = p_sys->video.i_angle;
502 args.video.p_surface = p_sys->video.p_surface;
503 args.video.p_jsurface = p_sys->video.p_jsurface;
504 args.video.b_tunneled_playback = args.video.p_surface ?
505 var_InheritBool(p_dec, CFG_PREFIX "tunneled-playback") : false;
506 if (p_sys->b_adaptive)
507 msg_Dbg(p_dec, "mediacodec configured for adaptative playback");
508 args.video.b_adaptive_playback = p_sys->b_adaptive;
510 else
512 date_Set(&p_sys->audio.i_end_date, VLC_TICK_INVALID);
514 args.audio.i_sample_rate = p_dec->fmt_in.audio.i_rate;
515 args.audio.i_channel_count = p_sys->audio.i_channels;
518 if (p_sys->api.configure_decoder(&p_sys->api, &args) != 0)
520 return MC_API_ERROR;
523 return p_sys->api.start(&p_sys->api);
526 /*****************************************************************************
527 * StopMediaCodec: Close the mediacodec instance
528 *****************************************************************************/
529 static void StopMediaCodec(decoder_t *p_dec)
531 decoder_sys_t *p_sys = p_dec->p_sys;
533 /* Remove all pictures that are currently in flight in order
534 * to prevent the vout from using destroyed output buffers. */
535 if (p_sys->api.b_direct_rendering)
536 RemoveInflightPictures(p_dec);
538 p_sys->api.stop(&p_sys->api);
541 /*****************************************************************************
542 * OpenDecoder: Create the decoder instance
543 *****************************************************************************/
544 static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
546 decoder_t *p_dec = (decoder_t *)p_this;
548 if (!var_InheritBool(p_dec, "mediacodec"))
549 return VLC_EGENERIC;
551 decoder_sys_t *p_sys;
552 int i_ret;
553 int i_profile = p_dec->fmt_in.i_profile;
554 const char *mime = NULL;
556 /* Video or Audio if "mediacodec-audio" bool is true */
557 if (p_dec->fmt_in.i_cat != VIDEO_ES && (p_dec->fmt_in.i_cat != AUDIO_ES
558 || !var_InheritBool(p_dec, CFG_PREFIX "audio")))
559 return VLC_EGENERIC;
561 /* Fail if this module already failed to decode this ES */
562 if (var_Type(p_dec, "mediacodec-failed") != 0)
563 return VLC_EGENERIC;
565 if (p_dec->fmt_in.i_cat == VIDEO_ES)
567 /* Not all mediacodec versions can handle a size of 0. Hopefully, the
568 * packetizer will trigger a decoder restart when a new video size is
569 * found. */
570 if (!p_dec->fmt_in.video.i_width || !p_dec->fmt_in.video.i_height)
571 return VLC_EGENERIC;
573 switch (p_dec->fmt_in.i_codec) {
574 case VLC_CODEC_HEVC:
575 if (i_profile == -1)
577 uint8_t i_hevc_profile;
578 if (hevc_get_profile_level(&p_dec->fmt_in, &i_hevc_profile, NULL, NULL))
579 i_profile = i_hevc_profile;
581 mime = "video/hevc";
582 break;
583 case VLC_CODEC_H264:
584 if (i_profile == -1)
586 uint8_t i_h264_profile;
587 if (h264_get_profile_level(&p_dec->fmt_in, &i_h264_profile, NULL, NULL))
588 i_profile = i_h264_profile;
590 mime = "video/avc";
591 break;
592 case VLC_CODEC_H263: mime = "video/3gpp"; break;
593 case VLC_CODEC_MP4V: mime = "video/mp4v-es"; break;
594 case VLC_CODEC_MPGV:
595 case VLC_CODEC_MP2V:
596 mime = "video/mpeg2";
597 break;
598 case VLC_CODEC_WMV3: mime = "video/x-ms-wmv"; break;
599 case VLC_CODEC_VC1: mime = "video/wvc1"; break;
600 case VLC_CODEC_VP8: mime = "video/x-vnd.on2.vp8"; break;
601 case VLC_CODEC_VP9: mime = "video/x-vnd.on2.vp9"; break;
604 else
606 switch (p_dec->fmt_in.i_codec) {
607 case VLC_CODEC_AMR_NB: mime = "audio/3gpp"; break;
608 case VLC_CODEC_AMR_WB: mime = "audio/amr-wb"; break;
609 case VLC_CODEC_MPGA:
610 case VLC_CODEC_MP3: mime = "audio/mpeg"; break;
611 case VLC_CODEC_MP2: mime = "audio/mpeg-L2"; break;
612 case VLC_CODEC_MP4A: mime = "audio/mp4a-latm"; break;
613 case VLC_CODEC_QCELP: mime = "audio/qcelp"; break;
614 case VLC_CODEC_VORBIS: mime = "audio/vorbis"; break;
615 case VLC_CODEC_OPUS: mime = "audio/opus"; break;
616 case VLC_CODEC_ALAW: mime = "audio/g711-alaw"; break;
617 case VLC_CODEC_MULAW: mime = "audio/g711-mlaw"; break;
618 case VLC_CODEC_FLAC: mime = "audio/flac"; break;
619 case VLC_CODEC_GSM: mime = "audio/gsm"; break;
620 case VLC_CODEC_A52: mime = "audio/ac3"; break;
621 case VLC_CODEC_EAC3: mime = "audio/eac3"; break;
622 case VLC_CODEC_ALAC: mime = "audio/alac"; break;
623 case VLC_CODEC_DTS: mime = "audio/vnd.dts"; break;
624 /* case VLC_CODEC_: mime = "audio/mpeg-L1"; break; */
625 /* case VLC_CODEC_: mime = "audio/aac-adts"; break; */
628 if (!mime)
630 msg_Dbg(p_dec, "codec %4.4s not supported",
631 (char *)&p_dec->fmt_in.i_codec);
632 return VLC_EGENERIC;
635 /* Allocate the memory needed to store the decoder's structure */
636 if ((p_sys = calloc(1, sizeof(*p_sys))) == NULL)
637 return VLC_ENOMEM;
639 p_sys->api.p_obj = p_this;
640 p_sys->api.i_codec = p_dec->fmt_in.i_codec;
641 p_sys->api.i_cat = p_dec->fmt_in.i_cat;
642 p_sys->api.psz_mime = mime;
643 p_sys->video.i_mpeg_dar_num = 0;
644 p_sys->video.i_mpeg_dar_den = 0;
646 if (pf_init(&p_sys->api) != 0)
648 free(p_sys);
649 return VLC_EGENERIC;
651 if (p_sys->api.prepare(&p_sys->api, i_profile) != 0)
653 /* If the device can't handle video/wvc1,
654 * it can probably handle video/x-ms-wmv */
655 if (!strcmp(mime, "video/wvc1") && p_dec->fmt_in.i_codec == VLC_CODEC_VC1)
657 p_sys->api.psz_mime = "video/x-ms-wmv";
658 if (p_sys->api.prepare(&p_sys->api, i_profile) != 0)
660 p_sys->api.clean(&p_sys->api);
661 free(p_sys);
662 return (VLC_EGENERIC);
665 else
667 p_sys->api.clean(&p_sys->api);
668 free(p_sys);
669 return VLC_EGENERIC;
673 p_dec->p_sys = p_sys;
675 vlc_mutex_init(&p_sys->lock);
676 vlc_cond_init(&p_sys->cond);
677 vlc_cond_init(&p_sys->dec_cond);
679 if (p_dec->fmt_in.i_cat == VIDEO_ES)
681 switch (p_dec->fmt_in.i_codec)
683 case VLC_CODEC_H264:
684 case VLC_CODEC_HEVC:
685 hxxx_helper_init(&p_sys->video.hh, VLC_OBJECT(p_dec),
686 p_dec->fmt_in.i_codec, false);
687 break;
689 p_sys->pf_on_new_block = Video_OnNewBlock;
690 p_sys->pf_on_flush = Video_OnFlush;
691 p_sys->pf_process_output = Video_ProcessOutput;
693 p_sys->video.timestamp_fifo = timestamp_FifoNew(32);
694 if (!p_sys->video.timestamp_fifo)
695 goto bailout;
697 TAB_INIT(p_sys->video.i_inflight_pictures,
698 p_sys->video.pp_inflight_pictures);
700 if (var_InheritBool(p_dec, CFG_PREFIX "dr"))
702 /* Direct rendering: Request a valid OPAQUE Vout in order to get
703 * the surface attached to it */
704 p_dec->fmt_out.i_codec = VLC_CODEC_ANDROID_OPAQUE;
706 if (p_sys->api.b_support_rotation)
708 switch (p_dec->fmt_out.video.orientation)
710 case ORIENT_ROTATED_90:
711 p_sys->video.i_angle = 90;
712 break;
713 case ORIENT_ROTATED_180:
714 p_sys->video.i_angle = 180;
715 break;
716 case ORIENT_ROTATED_270:
717 p_sys->video.i_angle = 270;
718 break;
719 default:
720 p_sys->video.i_angle = 0;
721 break;
724 else
725 p_sys->video.i_angle = 0;
727 p_dec->fmt_out.video = p_dec->fmt_in.video;
728 if (p_dec->fmt_out.video.i_sar_num * p_dec->fmt_out.video.i_sar_den == 0)
730 p_dec->fmt_out.video.i_sar_num = 1;
731 p_dec->fmt_out.video.i_sar_den = 1;
734 p_sys->video.i_input_width =
735 p_dec->fmt_out.video.i_visible_width = p_dec->fmt_out.video.i_width;
736 p_sys->video.i_input_height =
737 p_dec->fmt_out.video.i_visible_height = p_dec->fmt_out.video.i_height;
739 if (UpdateVout(p_dec) != VLC_SUCCESS)
741 msg_Err(p_dec, "Opaque Vout request failed");
742 goto bailout;
746 else
748 p_sys->pf_on_new_block = Audio_OnNewBlock;
749 p_sys->pf_on_flush = Audio_OnFlush;
750 p_sys->pf_process_output = Audio_ProcessOutput;
751 p_sys->audio.i_channels = p_dec->fmt_in.audio.i_channels;
753 if ((p_sys->api.i_quirks & MC_API_AUDIO_QUIRKS_NEED_CHANNELS)
754 && !p_sys->audio.i_channels)
756 msg_Warn(p_dec, "codec need a valid channel count");
757 goto bailout;
760 p_dec->fmt_out.audio = p_dec->fmt_in.audio;
763 /* Try first to configure CSD */
764 if (ParseExtra(p_dec) != VLC_SUCCESS)
765 goto bailout;
767 if ((p_sys->api.i_quirks & MC_API_QUIRKS_NEED_CSD) && !p_sys->i_csd_count
768 && !p_sys->b_adaptive)
770 switch (p_dec->fmt_in.i_codec)
772 case VLC_CODEC_H264:
773 case VLC_CODEC_HEVC:
774 break; /* CSDs will come from hxxx_helper */
775 default:
776 msg_Warn(p_dec, "Not CSD found for %4.4s",
777 (const char *) &p_dec->fmt_in.i_codec);
778 goto bailout;
782 i_ret = StartMediaCodec(p_dec);
783 if (i_ret != VLC_SUCCESS)
785 msg_Err(p_dec, "StartMediaCodec failed");
786 goto bailout;
789 if (vlc_clone(&p_sys->out_thread, OutThread, p_dec,
790 VLC_THREAD_PRIORITY_LOW))
792 msg_Err(p_dec, "vlc_clone failed");
793 vlc_mutex_unlock(&p_sys->lock);
794 goto bailout;
797 p_dec->pf_decode = DecodeBlock;
798 p_dec->pf_flush = DecodeFlush;
800 return VLC_SUCCESS;
802 bailout:
803 CleanDecoder(p_dec);
804 return VLC_EGENERIC;
807 static int OpenDecoderNdk(vlc_object_t *p_this)
809 return OpenDecoder(p_this, MediaCodecNdk_Init);
812 static int OpenDecoderJni(vlc_object_t *p_this)
814 return OpenDecoder(p_this, MediaCodecJni_Init);
817 static void AbortDecoderLocked(decoder_t *p_dec)
819 decoder_sys_t *p_sys = p_dec->p_sys;
821 if (!p_sys->b_aborted)
823 p_sys->b_aborted = true;
824 vlc_cancel(p_sys->out_thread);
828 static void CleanDecoder(decoder_t *p_dec)
830 decoder_sys_t *p_sys = p_dec->p_sys;
832 vlc_mutex_destroy(&p_sys->lock);
833 vlc_cond_destroy(&p_sys->cond);
834 vlc_cond_destroy(&p_sys->dec_cond);
836 StopMediaCodec(p_dec);
838 CSDFree(p_dec);
839 p_sys->api.clean(&p_sys->api);
841 if (p_dec->fmt_in.i_cat == VIDEO_ES)
843 if (p_dec->fmt_in.i_codec == VLC_CODEC_H264
844 || p_dec->fmt_in.i_codec == VLC_CODEC_HEVC)
845 hxxx_helper_clean(&p_sys->video.hh);
847 if (p_sys->video.timestamp_fifo)
848 timestamp_FifoRelease(p_sys->video.timestamp_fifo);
850 free(p_sys);
853 /*****************************************************************************
854 * CloseDecoder: Close the decoder instance
855 *****************************************************************************/
856 static void CloseDecoder(vlc_object_t *p_this)
858 decoder_t *p_dec = (decoder_t *)p_this;
859 decoder_sys_t *p_sys = p_dec->p_sys;
861 vlc_mutex_lock(&p_sys->lock);
862 /* Unblock output thread waiting in dequeue_out */
863 DecodeFlushLocked(p_dec);
864 /* Cancel the output thread */
865 AbortDecoderLocked(p_dec);
866 vlc_mutex_unlock(&p_sys->lock);
868 vlc_join(p_sys->out_thread, NULL);
870 CleanDecoder(p_dec);
873 /*****************************************************************************
874 * vout callbacks
875 *****************************************************************************/
876 static void ReleasePicture(decoder_t *p_dec, unsigned i_index, bool b_render)
878 decoder_sys_t *p_sys = p_dec->p_sys;
880 p_sys->api.release_out(&p_sys->api, i_index, b_render);
883 static void ReleasePictureTs(decoder_t *p_dec, unsigned i_index, vlc_tick_t i_ts)
885 decoder_sys_t *p_sys = p_dec->p_sys;
886 assert(p_sys->api.release_out_ts);
888 p_sys->api.release_out_ts(&p_sys->api, i_index, i_ts * INT64_C(1000));
891 static void InvalidateAllPictures(decoder_t *p_dec)
893 decoder_sys_t *p_sys = p_dec->p_sys;
895 for (unsigned int i = 0; i < p_sys->video.i_inflight_pictures; ++i)
896 AndroidOpaquePicture_Release(p_sys->video.pp_inflight_pictures[i],
897 false);
900 static int InsertInflightPicture(decoder_t *p_dec, picture_sys_t *p_picsys)
902 decoder_sys_t *p_sys = p_dec->p_sys;
904 if (!p_picsys->hw.p_dec)
906 p_picsys->hw.p_dec = p_dec;
907 p_picsys->hw.pf_release = ReleasePicture;
908 if (p_sys->api.release_out_ts)
909 p_picsys->hw.pf_release_ts = ReleasePictureTs;
910 TAB_APPEND_CAST((picture_sys_t **),
911 p_sys->video.i_inflight_pictures,
912 p_sys->video.pp_inflight_pictures,
913 p_picsys);
914 } /* else already attached */
915 return 0;
918 static void RemoveInflightPictures(decoder_t *p_dec)
920 decoder_sys_t *p_sys = p_dec->p_sys;
922 for (unsigned int i = 0; i < p_sys->video.i_inflight_pictures; ++i)
923 AndroidOpaquePicture_DetachDecoder(p_sys->video.pp_inflight_pictures[i]);
924 TAB_CLEAN(p_sys->video.i_inflight_pictures,
925 p_sys->video.pp_inflight_pictures);
928 static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out,
929 picture_t **pp_out_pic, block_t **pp_out_block)
931 decoder_sys_t *p_sys = p_dec->p_sys;
932 (void) pp_out_block;
933 assert(pp_out_pic);
935 if (p_out->type == MC_OUT_TYPE_BUF)
937 picture_t *p_pic = NULL;
939 /* If the oldest input block had no PTS, the timestamp of
940 * the frame returned by MediaCodec might be wrong so we
941 * overwrite it with the corresponding dts. Call FifoGet
942 * first in order to avoid a gap if buffers are released
943 * due to an invalid format or a preroll */
944 int64_t forced_ts = timestamp_FifoGet(p_sys->video.timestamp_fifo);
946 if (!p_sys->b_has_format) {
947 msg_Warn(p_dec, "Buffers returned before output format is set, dropping frame");
948 return p_sys->api.release_out(&p_sys->api, p_out->buf.i_index, false);
951 if (p_out->buf.i_ts <= p_sys->i_preroll_end)
952 return p_sys->api.release_out(&p_sys->api, p_out->buf.i_index, false);
954 if (!p_sys->api.b_direct_rendering && p_out->buf.p_ptr == NULL)
956 /* This can happen when receiving an EOS buffer */
957 msg_Warn(p_dec, "Invalid buffer, dropping frame");
958 return p_sys->api.release_out(&p_sys->api, p_out->buf.i_index, false);
961 p_pic = decoder_NewPicture(p_dec);
962 if (!p_pic) {
963 msg_Warn(p_dec, "NewPicture failed");
964 return p_sys->api.release_out(&p_sys->api, p_out->buf.i_index, false);
967 if (forced_ts == VLC_TICK_INVALID)
968 p_pic->date = p_out->buf.i_ts;
969 else
970 p_pic->date = forced_ts;
971 p_pic->b_progressive = true;
973 if (p_sys->api.b_direct_rendering)
975 picture_sys_t *p_picsys = p_pic->p_sys;
976 p_picsys->hw.i_index = p_out->buf.i_index;
977 InsertInflightPicture(p_dec, p_pic->p_sys);
978 } else {
979 unsigned int chroma_div;
980 GetVlcChromaSizes(p_dec->fmt_out.i_codec,
981 p_dec->fmt_out.video.i_width,
982 p_dec->fmt_out.video.i_height,
983 NULL, NULL, &chroma_div);
984 CopyOmxPicture(p_sys->video.i_pixel_format, p_pic,
985 p_sys->video.i_slice_height, p_sys->video.i_stride,
986 (uint8_t *)p_out->buf.p_ptr, chroma_div, NULL);
988 if (p_sys->api.release_out(&p_sys->api, p_out->buf.i_index, false))
990 picture_Release(p_pic);
991 return -1;
994 assert(!(*pp_out_pic));
995 *pp_out_pic = p_pic;
996 return 1;
997 } else {
998 assert(p_out->type == MC_OUT_TYPE_CONF);
999 p_sys->video.i_pixel_format = p_out->conf.video.pixel_format;
1001 const char *name = "unknown";
1002 if (!p_sys->api.b_direct_rendering
1003 && !GetVlcChromaFormat(p_sys->video.i_pixel_format,
1004 &p_dec->fmt_out.i_codec, &name))
1006 msg_Err(p_dec, "color-format not recognized");
1007 return -1;
1010 msg_Err(p_dec, "output: %d %s, %dx%d stride %d %d, crop %d %d %d %d",
1011 p_sys->video.i_pixel_format, name,
1012 p_out->conf.video.width, p_out->conf.video.height,
1013 p_out->conf.video.stride, p_out->conf.video.slice_height,
1014 p_out->conf.video.crop_left, p_out->conf.video.crop_top,
1015 p_out->conf.video.crop_right, p_out->conf.video.crop_bottom);
1017 int i_width = p_out->conf.video.crop_right + 1
1018 - p_out->conf.video.crop_left;
1019 int i_height = p_out->conf.video.crop_bottom + 1
1020 - p_out->conf.video.crop_top;
1021 if (i_width <= 1 || i_height <= 1)
1023 i_width = p_out->conf.video.width;
1024 i_height = p_out->conf.video.height;
1027 p_dec->fmt_out.video.i_visible_width =
1028 p_dec->fmt_out.video.i_width = i_width;
1029 p_dec->fmt_out.video.i_visible_height =
1030 p_dec->fmt_out.video.i_height = i_height;
1032 p_sys->video.i_stride = p_out->conf.video.stride;
1033 p_sys->video.i_slice_height = p_out->conf.video.slice_height;
1034 if (p_sys->video.i_stride <= 0)
1035 p_sys->video.i_stride = p_out->conf.video.width;
1036 if (p_sys->video.i_slice_height <= 0)
1037 p_sys->video.i_slice_height = p_out->conf.video.height;
1039 if (p_sys->video.i_pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar)
1040 p_sys->video.i_slice_height -= p_out->conf.video.crop_top/2;
1041 if ((p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_IGNORE_PADDING))
1043 p_sys->video.i_slice_height = 0;
1044 p_sys->video.i_stride = p_dec->fmt_out.video.i_width;
1047 if (UpdateVout(p_dec) != VLC_SUCCESS)
1049 msg_Err(p_dec, "UpdateVout failed");
1050 return -1;
1053 p_sys->b_has_format = true;
1054 return 0;
1058 /* samples will be in the following order: FL FR FC LFE BL BR BC SL SR */
1059 static uint32_t pi_audio_order_src[] =
1061 AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER, AOUT_CHAN_LFE,
1062 AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, AOUT_CHAN_REARCENTER,
1063 AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT,
1066 static int Audio_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out,
1067 picture_t **pp_out_pic, block_t **pp_out_block)
1069 decoder_sys_t *p_sys = p_dec->p_sys;
1070 (void) pp_out_pic;
1071 assert(pp_out_block);
1073 if (p_out->type == MC_OUT_TYPE_BUF)
1075 block_t *p_block = NULL;
1076 if (p_out->buf.p_ptr == NULL)
1078 /* This can happen when receiving an EOS buffer */
1079 msg_Warn(p_dec, "Invalid buffer, dropping frame");
1080 return p_sys->api.release_out(&p_sys->api, p_out->buf.i_index, false);
1083 if (!p_sys->b_has_format) {
1084 msg_Warn(p_dec, "Buffers returned before output format is set, dropping frame");
1085 return p_sys->api.release_out(&p_sys->api, p_out->buf.i_index, false);
1088 p_block = block_Alloc(p_out->buf.i_size);
1089 if (!p_block)
1090 return -1;
1091 p_block->i_nb_samples = p_out->buf.i_size
1092 / p_dec->fmt_out.audio.i_bytes_per_frame;
1094 if (p_sys->audio.b_extract)
1096 aout_ChannelExtract(p_block->p_buffer,
1097 p_dec->fmt_out.audio.i_channels,
1098 p_out->buf.p_ptr, p_sys->audio.i_channels,
1099 p_block->i_nb_samples, p_sys->audio.pi_extraction,
1100 p_dec->fmt_out.audio.i_bitspersample);
1102 else
1103 memcpy(p_block->p_buffer, p_out->buf.p_ptr, p_out->buf.i_size);
1105 if (p_out->buf.i_ts != 0
1106 && p_out->buf.i_ts != date_Get(&p_sys->audio.i_end_date))
1107 date_Set(&p_sys->audio.i_end_date, p_out->buf.i_ts);
1109 p_block->i_pts = date_Get(&p_sys->audio.i_end_date);
1110 p_block->i_length = date_Increment(&p_sys->audio.i_end_date,
1111 p_block->i_nb_samples)
1112 - p_block->i_pts;
1114 if (p_sys->api.release_out(&p_sys->api, p_out->buf.i_index, false))
1116 block_Release(p_block);
1117 return -1;
1119 *pp_out_block = p_block;
1120 return 1;
1121 } else {
1122 uint32_t i_layout_dst;
1123 int i_channels_dst;
1125 assert(p_out->type == MC_OUT_TYPE_CONF);
1127 if (p_out->conf.audio.channel_count <= 0
1128 || p_out->conf.audio.channel_count > 8
1129 || p_out->conf.audio.sample_rate <= 0)
1131 msg_Warn(p_dec, "invalid audio properties channels count %d, sample rate %d",
1132 p_out->conf.audio.channel_count,
1133 p_out->conf.audio.sample_rate);
1134 return -1;
1137 msg_Err(p_dec, "output: channel_count: %d, channel_mask: 0x%X, rate: %d",
1138 p_out->conf.audio.channel_count, p_out->conf.audio.channel_mask,
1139 p_out->conf.audio.sample_rate);
1141 p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
1142 p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
1144 p_dec->fmt_out.audio.i_rate = p_out->conf.audio.sample_rate;
1145 date_Init(&p_sys->audio.i_end_date, p_out->conf.audio.sample_rate, 1);
1147 p_sys->audio.i_channels = p_out->conf.audio.channel_count;
1148 p_sys->audio.b_extract =
1149 aout_CheckChannelExtraction(p_sys->audio.pi_extraction,
1150 &i_layout_dst, &i_channels_dst,
1151 NULL, pi_audio_order_src,
1152 p_sys->audio.i_channels);
1154 if (p_sys->audio.b_extract)
1155 msg_Warn(p_dec, "need channel extraction: %d -> %d",
1156 p_sys->audio.i_channels, i_channels_dst);
1158 p_dec->fmt_out.audio.i_physical_channels = i_layout_dst;
1159 aout_FormatPrepare(&p_dec->fmt_out.audio);
1161 if (decoder_UpdateAudioFormat(p_dec))
1162 return -1;
1164 p_sys->b_has_format = true;
1165 return 0;
1169 static void DecodeFlushLocked(decoder_t *p_dec)
1171 decoder_sys_t *p_sys = p_dec->p_sys;
1172 bool b_had_input = p_sys->b_input_dequeued;
1174 p_sys->b_input_dequeued = false;
1175 p_sys->b_flush_out = true;
1176 p_sys->i_preroll_end = 0;
1177 p_sys->b_output_ready = false;
1178 /* Resend CODEC_CONFIG buffer after a flush */
1179 p_sys->i_csd_send = 0;
1181 p_sys->pf_on_flush(p_dec);
1183 if (b_had_input && p_sys->api.flush(&p_sys->api) != VLC_SUCCESS)
1185 AbortDecoderLocked(p_dec);
1186 return;
1189 vlc_cond_broadcast(&p_sys->cond);
1191 while (!p_sys->b_aborted && p_sys->b_flush_out)
1192 vlc_cond_wait(&p_sys->dec_cond, &p_sys->lock);
1195 static void DecodeFlush(decoder_t *p_dec)
1197 decoder_sys_t *p_sys = p_dec->p_sys;
1199 vlc_mutex_lock(&p_sys->lock);
1200 DecodeFlushLocked(p_dec);
1201 vlc_mutex_unlock(&p_sys->lock);
1204 static void *OutThread(void *data)
1206 decoder_t *p_dec = data;
1207 decoder_sys_t *p_sys = p_dec->p_sys;
1209 vlc_mutex_lock(&p_sys->lock);
1210 mutex_cleanup_push(&p_sys->lock);
1211 for (;;)
1213 int i_index;
1215 /* Wait for output ready */
1216 while (!p_sys->b_flush_out && !p_sys->b_output_ready)
1217 vlc_cond_wait(&p_sys->cond, &p_sys->lock);
1219 if (p_sys->b_flush_out)
1221 /* Acknowledge flushed state */
1222 p_sys->b_flush_out = false;
1223 vlc_cond_broadcast(&p_sys->dec_cond);
1224 continue;
1227 int canc = vlc_savecancel();
1229 vlc_mutex_unlock(&p_sys->lock);
1231 /* Wait for an output buffer. This function returns when a new output
1232 * is available or if output is flushed. */
1233 i_index = p_sys->api.dequeue_out(&p_sys->api, -1);
1235 vlc_mutex_lock(&p_sys->lock);
1237 /* Ignore dequeue_out errors caused by flush */
1238 if (p_sys->b_flush_out)
1240 /* If i_index >= 0, Release it. There is no way to know if i_index
1241 * is owned by us, so don't check the error. */
1242 if (i_index >= 0)
1243 p_sys->api.release_out(&p_sys->api, i_index, false);
1245 /* Parse output format/buffers even when we are flushing */
1246 if (i_index != MC_API_INFO_OUTPUT_FORMAT_CHANGED
1247 && i_index != MC_API_INFO_OUTPUT_BUFFERS_CHANGED)
1249 vlc_restorecancel(canc);
1250 continue;
1254 /* Process output returned by dequeue_out */
1255 if (i_index >= 0 || i_index == MC_API_INFO_OUTPUT_FORMAT_CHANGED
1256 || i_index == MC_API_INFO_OUTPUT_BUFFERS_CHANGED)
1258 struct mc_api_out out;
1259 int i_ret = p_sys->api.get_out(&p_sys->api, i_index, &out);
1261 if (i_ret == 1)
1263 picture_t *p_pic = NULL;
1264 block_t *p_block = NULL;
1266 if (p_sys->pf_process_output(p_dec, &out, &p_pic,
1267 &p_block) == -1 && !out.b_eos)
1269 msg_Err(p_dec, "pf_process_output failed");
1270 vlc_restorecancel(canc);
1271 break;
1273 if (p_pic)
1274 decoder_QueueVideo(p_dec, p_pic);
1275 else if (p_block)
1276 decoder_QueueAudio(p_dec, p_block);
1278 if (out.b_eos)
1280 msg_Warn(p_dec, "EOS received");
1281 p_sys->b_drained = true;
1282 vlc_cond_signal(&p_sys->dec_cond);
1284 } else if (i_ret != 0)
1286 msg_Err(p_dec, "get_out failed");
1287 vlc_restorecancel(canc);
1288 break;
1291 else
1293 vlc_restorecancel(canc);
1294 break;
1296 vlc_restorecancel(canc);
1298 msg_Warn(p_dec, "OutThread stopped");
1300 /* Signal DecoderFlush that the output thread aborted */
1301 p_sys->b_aborted = true;
1302 vlc_cond_signal(&p_sys->dec_cond);
1304 vlc_cleanup_pop();
1305 vlc_mutex_unlock(&p_sys->lock);
1307 return NULL;
1310 static block_t *GetNextBlock(decoder_sys_t *p_sys, block_t *p_block)
1312 if (p_sys->i_csd_send < p_sys->i_csd_count)
1313 return p_sys->pp_csd[p_sys->i_csd_send++];
1314 else
1315 return p_block;
1318 static int QueueBlockLocked(decoder_t *p_dec, block_t *p_in_block,
1319 bool b_drain)
1321 decoder_sys_t *p_sys = p_dec->p_sys;
1322 block_t *p_block = NULL;
1323 bool b_dequeue_timeout = false;
1325 assert(p_sys->api.b_started);
1327 if ((p_sys->api.i_quirks & MC_API_QUIRKS_NEED_CSD) && !p_sys->i_csd_count
1328 && !p_sys->b_adaptive)
1329 return VLC_EGENERIC; /* Wait for CSDs */
1331 /* Queue CSD blocks and input blocks */
1332 while (b_drain || (p_block = GetNextBlock(p_sys, p_in_block)))
1334 int i_index;
1336 vlc_mutex_unlock(&p_sys->lock);
1337 /* Wait for an input buffer. This function returns when a new input
1338 * buffer is available or after 2secs of timeout. */
1339 i_index = p_sys->api.dequeue_in(&p_sys->api,
1340 p_sys->api.b_direct_rendering ?
1341 INT64_C(2000000) : -1);
1342 vlc_mutex_lock(&p_sys->lock);
1344 if (p_sys->b_aborted)
1345 return VLC_EGENERIC;
1347 bool b_config = false;
1348 vlc_tick_t i_ts = 0;
1349 p_sys->b_input_dequeued = true;
1350 const void *p_buf = NULL;
1351 size_t i_size = 0;
1353 if (i_index >= 0)
1355 assert(b_drain || p_block != NULL);
1356 if (p_block != NULL)
1358 b_config = (p_block->i_flags & BLOCK_FLAG_CSD);
1359 if (!b_config)
1361 i_ts = p_block->i_pts;
1362 if (!i_ts && p_block->i_dts)
1363 i_ts = p_block->i_dts;
1365 p_buf = p_block->p_buffer;
1366 i_size = p_block->i_buffer;
1369 if (p_sys->api.queue_in(&p_sys->api, i_index, p_buf, i_size,
1370 i_ts, b_config) == 0)
1372 if (!b_config && p_block != NULL)
1374 if (p_block->i_flags & BLOCK_FLAG_PREROLL)
1375 p_sys->i_preroll_end = i_ts;
1377 /* One input buffer is queued, signal OutThread that will
1378 * fetch output buffers */
1379 p_sys->b_output_ready = true;
1380 vlc_cond_broadcast(&p_sys->cond);
1382 assert(p_block == p_in_block),
1383 p_in_block = NULL;
1385 b_dequeue_timeout = false;
1386 if (b_drain)
1387 break;
1388 } else
1390 msg_Err(p_dec, "queue_in failed");
1391 goto error;
1394 else if (i_index == MC_API_INFO_TRYAGAIN)
1396 /* HACK: When direct rendering is enabled, there is a possible
1397 * deadlock between the Decoder and the Vout. It happens when the
1398 * Vout is paused and when the Decoder is flushing. In that case,
1399 * the Vout won't release any output buffers, therefore MediaCodec
1400 * won't dequeue any input buffers. To work around this issue,
1401 * release all output buffers if DecodeBlock is waiting more than
1402 * 2secs for a new input buffer. */
1403 if (!b_dequeue_timeout)
1405 msg_Warn(p_dec, "Decoder stuck: invalidate all buffers");
1406 InvalidateAllPictures(p_dec);
1407 b_dequeue_timeout = true;
1408 continue;
1410 else
1412 msg_Err(p_dec, "dequeue_in timeout: no input available for 2secs");
1413 goto error;
1416 else
1418 msg_Err(p_dec, "dequeue_in failed");
1419 goto error;
1423 if (b_drain)
1425 msg_Warn(p_dec, "EOS sent, waiting for OutThread");
1427 /* Wait for the OutThread to stop (and process all remaining output
1428 * frames. Use a timeout here since we can't know if all decoders will
1429 * behave correctly. */
1430 vlc_tick_t deadline = vlc_tick_now() + INT64_C(3000000);
1431 while (!p_sys->b_aborted && !p_sys->b_drained
1432 && vlc_cond_timedwait(&p_sys->dec_cond, &p_sys->lock, deadline) == 0);
1434 if (!p_sys->b_drained)
1436 msg_Err(p_dec, "OutThread timed out");
1437 AbortDecoderLocked(p_dec);
1439 p_sys->b_drained = false;
1442 return VLC_SUCCESS;
1444 error:
1445 AbortDecoderLocked(p_dec);
1446 return VLC_EGENERIC;
1449 static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
1451 decoder_sys_t *p_sys = p_dec->p_sys;
1452 int i_ret;
1454 vlc_mutex_lock(&p_sys->lock);
1456 if (p_sys->b_aborted)
1458 if (p_sys->b_has_format)
1459 goto end;
1460 else
1461 goto reload;
1464 if (p_in_block == NULL)
1466 /* No input block, decoder is draining */
1467 msg_Err(p_dec, "Decoder is draining");
1469 if (p_sys->b_output_ready)
1470 QueueBlockLocked(p_dec, NULL, true);
1471 goto end;
1474 if (p_in_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
1476 if (p_sys->b_output_ready)
1477 QueueBlockLocked(p_dec, NULL, true);
1478 DecodeFlushLocked(p_dec);
1479 if (p_sys->b_aborted)
1480 goto end;
1481 if (p_in_block->i_flags & BLOCK_FLAG_CORRUPTED)
1482 goto end;
1485 if (p_in_block->i_flags & BLOCK_FLAG_INTERLACED_MASK
1486 && !(p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_SUPPORT_INTERLACED))
1488 /* Before Android 21 and depending on the vendor, MediaCodec can
1489 * crash or be in an inconsistent state when decoding interlaced
1490 * videos. See OMXCodec_GetQuirks() for a white list of decoders
1491 * that supported interlaced videos before Android 21. */
1492 msg_Warn(p_dec, "codec doesn't support interlaced videos");
1493 goto reload;
1496 /* Parse input block */
1497 if ((i_ret = p_sys->pf_on_new_block(p_dec, &p_in_block)) != 1)
1499 if (i_ret != 0)
1501 AbortDecoderLocked(p_dec);
1502 msg_Err(p_dec, "pf_on_new_block failed");
1504 goto end;
1506 if (p_sys->i_decode_flags & (DECODE_FLAG_DRAIN|DECODE_FLAG_RESTART))
1508 msg_Warn(p_dec, "Draining from DecodeBlock");
1509 const bool b_restart = p_sys->i_decode_flags & DECODE_FLAG_RESTART;
1510 p_sys->i_decode_flags = 0;
1512 /* Drain and flush before restart to unblock OutThread */
1513 if (p_sys->b_output_ready)
1514 QueueBlockLocked(p_dec, NULL, true);
1515 DecodeFlushLocked(p_dec);
1516 if (p_sys->b_aborted)
1517 goto end;
1519 if (b_restart)
1521 StopMediaCodec(p_dec);
1523 int i_ret = StartMediaCodec(p_dec);
1524 switch (i_ret)
1526 case VLC_SUCCESS:
1527 msg_Warn(p_dec, "Restarted from DecodeBlock");
1528 break;
1529 case VLC_ENOOBJ:
1530 break;
1531 default:
1532 msg_Err(p_dec, "StartMediaCodec failed");
1533 AbortDecoderLocked(p_dec);
1534 goto end;
1539 /* Abort if MediaCodec is not yet started */
1540 if (p_sys->api.b_started)
1541 QueueBlockLocked(p_dec, p_in_block, false);
1543 end:
1544 if (p_in_block)
1545 block_Release(p_in_block);
1546 /* Too late to reload here, we already modified/released the input block,
1547 * do it next time. */
1548 int ret = p_sys->b_aborted && p_sys->b_has_format ? VLCDEC_ECRITICAL
1549 : VLCDEC_SUCCESS;
1550 vlc_mutex_unlock(&p_sys->lock);
1551 return ret;
1553 reload:
1554 vlc_mutex_unlock(&p_sys->lock);
1555 /* Add an empty variable so that mediacodec won't be loaded again
1556 * for this ES */
1557 var_Create(p_dec, "mediacodec-failed", VLC_VAR_VOID);
1558 return VLCDEC_RELOAD;
1561 static int Video_OnNewBlock(decoder_t *p_dec, block_t **pp_block)
1563 decoder_sys_t *p_sys = p_dec->p_sys;
1564 block_t *p_block = *pp_block;
1566 timestamp_FifoPut(p_sys->video.timestamp_fifo,
1567 p_block->i_pts ? VLC_TICK_INVALID : p_block->i_dts);
1569 return 1;
1572 static int VideoHXXX_OnNewBlock(decoder_t *p_dec, block_t **pp_block)
1574 decoder_sys_t *p_sys = p_dec->p_sys;
1575 struct hxxx_helper *hh = &p_sys->video.hh;
1576 bool b_config_changed = false;
1577 bool *p_config_changed = p_sys->b_adaptive ? NULL : &b_config_changed;
1579 *pp_block = hh->pf_process_block(hh, *pp_block, p_config_changed);
1580 if (!*pp_block)
1581 return 0;
1582 if (b_config_changed)
1584 bool b_size_changed;
1585 int i_ret;
1586 switch (p_dec->fmt_in.i_codec)
1588 case VLC_CODEC_H264:
1589 if (hh->h264.i_sps_count > 0 || hh->h264.i_pps_count > 0)
1590 i_ret = H264SetCSD(p_dec, &b_size_changed);
1591 else
1592 i_ret = VLC_EGENERIC;
1593 break;
1594 case VLC_CODEC_HEVC:
1595 if (hh->hevc.i_vps_count > 0 || hh->hevc.i_sps_count > 0 ||
1596 hh->hevc.i_pps_count > 0 )
1597 i_ret = HEVCSetCSD(p_dec, &b_size_changed);
1598 else
1599 i_ret = VLC_EGENERIC;
1600 break;
1602 if (i_ret != VLC_SUCCESS)
1603 return i_ret;
1604 if (b_size_changed || !p_sys->api.b_started)
1606 if (p_sys->api.b_started)
1607 msg_Err(p_dec, "SPS/PPS changed during playback and "
1608 "video size are different. Restart it !");
1609 p_sys->i_decode_flags |= DECODE_FLAG_RESTART;
1610 } else
1612 msg_Err(p_dec, "SPS/PPS changed during playback. Drain it");
1613 p_sys->i_decode_flags |= DECODE_FLAG_DRAIN;
1617 return Video_OnNewBlock(p_dec, pp_block);
1620 static int VideoMPEG2_OnNewBlock(decoder_t *p_dec, block_t **pp_block)
1622 if (pp_block == NULL || (*pp_block)->i_buffer <= 7)
1623 return 1;
1625 decoder_sys_t *p_sys = p_dec->p_sys;
1626 const int startcode = (*pp_block)->p_buffer[3];
1628 /* DAR aspect ratio from the DVD MPEG2 standard */
1629 static const int mpeg2_aspect[16][2] =
1631 {0,0}, /* reserved */
1632 {0,0}, /* DAR = 0:0 will result in SAR = 1:1 */
1633 {4,3}, {16,9}, {221,100},
1634 /* reserved */
1635 {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
1636 {0,0}, {0,0}
1639 if (startcode == 0xB3 /* SEQUENCE_HEADER_STARTCODE */)
1641 int mpeg_dar_code = (*pp_block)->p_buffer[7] >> 4;
1643 if (mpeg_dar_code >= 16)
1644 return 0;
1646 p_sys->video.i_mpeg_dar_num = mpeg2_aspect[mpeg_dar_code][0];
1647 p_sys->video.i_mpeg_dar_den = mpeg2_aspect[mpeg_dar_code][1];
1650 return 1;
1653 static int VideoVC1_OnNewBlock(decoder_t *p_dec, block_t **pp_block)
1655 block_t *p_block = *pp_block;
1657 /* Adding frame start code */
1658 p_block = *pp_block = block_Realloc(p_block, 4, p_block->i_buffer);
1659 if (p_block == NULL)
1660 return VLC_ENOMEM;
1661 p_block->p_buffer[0] = 0x00;
1662 p_block->p_buffer[1] = 0x00;
1663 p_block->p_buffer[2] = 0x01;
1664 p_block->p_buffer[3] = 0x0d;
1666 return Video_OnNewBlock(p_dec, pp_block);
1669 static void Video_OnFlush(decoder_t *p_dec)
1671 decoder_sys_t *p_sys = p_dec->p_sys;
1673 timestamp_FifoEmpty(p_sys->video.timestamp_fifo);
1674 /* Invalidate all pictures that are currently in flight
1675 * since flushing make all previous indices returned by
1676 * MediaCodec invalid. */
1677 if (p_sys->api.b_direct_rendering)
1678 InvalidateAllPictures(p_dec);
1681 static int Audio_OnNewBlock(decoder_t *p_dec, block_t **pp_block)
1683 decoder_sys_t *p_sys = p_dec->p_sys;
1684 block_t *p_block = *pp_block;
1686 /* We've just started the stream, wait for the first PTS. */
1687 if (date_Get(&p_sys->audio.i_end_date) == VLC_TICK_INVALID)
1689 if (p_block->i_pts == VLC_TICK_INVALID)
1690 return 0;
1691 date_Set(&p_sys->audio.i_end_date, p_block->i_pts);
1694 return 1;
1697 static void Audio_OnFlush(decoder_t *p_dec)
1699 decoder_sys_t *p_sys = p_dec->p_sys;
1701 date_Set(&p_sys->audio.i_end_date, VLC_TICK_INVALID);