/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2009-2019. All rights reserved. * Description: Defines avplay mpi function * Author: Hisilicon * Create: 2009-12-21 * History: */ #include "mpi_avplay_ext.h" #include "avplay_common.h" #include "avplay_config.h" #include "avplay_context.h" #include "avplay_control.h" #include "avplay_adapter.h" #include "avplay_debugger.h" #include "avplay_hal.h" #include "mpi_sync_ext.h" #include "mpi_adec_ext.h" #include "mpi_vdec_ext.h" #include "mpi_win_ext.h" #include "mpi_ao_ext.h" #include "mpi_memory_ext.h" typedef struct { td_u32 inited; td_u32 instance_cnt; avplay_instance instance[AVPLAY_MAX_CNT]; avplay_mutex_t mutex; } avplay_manager; static avplay_manager g_avplay_manager = { .inited = 0, .instance_cnt = 0, .mutex = PTHREAD_MUTEX_INITIALIZER, }; static void avplay_instance_init(void) { td_u32 i = 0; for (; i < AVPLAY_MAX_CNT; i++) { g_avplay_manager.instance[i].handle = TD_INVALID_HANDLE; g_avplay_manager.instance[i].ctx = TD_NULL; avplay_mutex_init(&g_avplay_manager.instance[i].mutex); } } static td_handle avplay_instance_add(avplay_context *ctx, td_handle alloc_handle) { td_handle handle = TD_INVALID_HANDLE; td_u32 i; soc_assert_avplay(ctx != TD_NULL); avplay_mutex_lock(&g_avplay_manager.mutex); if (g_avplay_manager.inited == 0) { ext_err_avplay("Avplay not inited\n"); goto out; } if (alloc_handle != TD_INVALID_HANDLE) { i = avplay_get_id(alloc_handle); if (i >= AVPLAY_MAX_CNT) { ext_err_avplay("Invalid alloc handle [0x%x]\n", alloc_handle); goto out; } handle = alloc_handle; } else { for (i = 0; i < AVPLAY_MAX_CNT; i++) { if (g_avplay_manager.instance[i].handle == TD_INVALID_HANDLE) { break; } } if (i >= AVPLAY_MAX_CNT) { ext_err_avplay("Too many avplays are created, AVPLAY_MAX_CNT = %u, instance cnt = %u\n", AVPLAY_MAX_CNT, g_avplay_manager.instance_cnt); goto out; } handle = avplay_get_handle(i); } g_avplay_manager.instance_cnt++; g_avplay_manager.instance[i].handle = handle; g_avplay_manager.instance[i].ctx = ctx; avplay_mutex_init(&g_avplay_manager.instance[i].mutex); out: avplay_mutex_unlock(&g_avplay_manager.mutex); return handle; } static void avplay_instance_del(td_handle handle) { td_u32 index = avplay_get_id(handle); soc_assert_avplay(index < AVPLAY_MAX_CNT); avplay_mutex_lock(&g_avplay_manager.mutex); g_avplay_manager.instance[index].handle = TD_INVALID_HANDLE; g_avplay_manager.instance[index].ctx = TD_NULL; g_avplay_manager.instance_cnt--; avplay_mutex_unlock(&g_avplay_manager.mutex); } avplay_instance *avplay_instance_get(td_handle handle) { avplay_instance *instance = TD_NULL; td_u32 index = avplay_get_id(handle); if (index >= AVPLAY_MAX_CNT || avplay_get_modid(handle) != SOC_ID_AVPLAY) { ext_err_avplay("Invalid avplay handle[0x%x]\n", handle); return TD_NULL; } avplay_mutex_lock(&g_avplay_manager.mutex); if (g_avplay_manager.inited == 0) { ext_err_avplay("AVPLAY not inited\n"); goto out; } if (g_avplay_manager.instance[index].ctx == TD_NULL) { ext_err_avplay("Invalid avplay handle[0x%x], instance context is NULL\n", handle); } else if (g_avplay_manager.instance[index].handle != handle) { ext_err_avplay("Invalid avplay handle[0x%x] check failed\n", handle); } else { instance = &g_avplay_manager.instance[index]; } out: avplay_mutex_unlock(&g_avplay_manager.mutex); return instance; } #define AVPLAY_CTX (instance->ctx) #define avplay_mpi_do_func(avplay, func) do { \ td_s32 ret = TD_SUCCESS; \ avplay_instance *instance = avplay_instance_get(avplay); \ if (instance == TD_NULL) { \ ext_err_avplay("avplay_instance_get failed.\n"); \ return SOC_ERR_AVPLAY_INVALID_PARA; \ } \ \ avplay_mutex_lock(&instance->mutex); \ if (instance->ctx != TD_NULL) { \ ret = func; \ } else { \ ret = SOC_ERR_AVPLAY_NULL_PTR; \ ext_err_avplay("Instance context is NULL!\n"); \ } \ \ avplay_mutex_unlock(&instance->mutex); \ return ret; \ } while (0) static void register_render_func(void) { win_extern_func win_func = {ext_mpi_avplay_attach_window, ext_mpi_avplay_detach_window, TD_NULL, TD_NULL, TD_NULL}; td_s32 ret = ext_mpi_win_extern_register(MODULE_ID_AVPLAY, &win_func); log_when_error(ret, ext_mpi_win_extern_register); ext_ao_ext_module_fn ao_func = {ext_mpi_avplay_attach_track, ext_mpi_avplay_detach_track}; ret = ext_mpi_ao_register_extern_func(SOC_ID_AVPLAY, &ao_func); log_when_error(ret, ext_mpi_ao_register_extern_func); } static void unregister_render_func(void) { td_s32 ret = ext_mpi_win_extern_unregister(MODULE_ID_AVPLAY); log_when_error(ret, ext_mpi_win_extern_unregister); ret = ext_mpi_ao_unregister_extern_func(SOC_ID_AVPLAY); log_when_error(ret, ext_mpi_ao_unregister_extern_func); } td_s32 ext_mpi_avplay_init(void) { td_s32 ret = TD_SUCCESS; avplay_mutex_lock(&g_avplay_manager.mutex); if (g_avplay_manager.inited > 0) { goto success; } ret = ext_mpi_adec_init(); goto_when_error(ret, ext_mpi_adec_init, fail); ret = ext_mpi_sync_init(); goto_when_error(ret, ext_mpi_sync_init, deinit_adec); ret = avplay_hal_init(); goto_when_error(ret, avplay_hal_init, deinit_sync); avplay_instance_init(); register_render_func(); success: g_avplay_manager.inited++; ext_info_avplay("[PID:%u] Init avplay success, inited : %u\n", avplay_getpid(), g_avplay_manager.inited); avplay_mutex_unlock(&g_avplay_manager.mutex); return TD_SUCCESS; deinit_sync: (void)ext_mpi_sync_deinit(); deinit_adec: (void)ext_mpi_adec_deinit(); fail: ext_err_avplay("[PID:%u] Init avplay failed, return 0x%x, inited : %u\n", avplay_getpid(), ret, g_avplay_manager.inited); avplay_mutex_unlock(&g_avplay_manager.mutex); return ret; } td_s32 ext_mpi_avplay_deinit(void) { td_s32 ret = TD_SUCCESS; avplay_mutex_lock(&g_avplay_manager.mutex); if (g_avplay_manager.inited == 0) { goto out; } if (g_avplay_manager.instance_cnt != 0) { ext_err_avplay("There are %u avplay not been destoryed\n", g_avplay_manager.instance_cnt); ret = SOC_ERR_AVPLAY_INVALID_OPT; goto out; } unregister_render_func(); ret = avplay_hal_deinit(); log_when_error(ret, avplay_hal_deinit); ret = ext_mpi_sync_deinit(); log_when_error(ret, ext_mpi_sync_deinit); ret = ext_mpi_adec_deinit(); log_when_error(ret, ext_mpi_adec_deinit); g_avplay_manager.inited = 0; ret = TD_SUCCESS; /* ignore the error of device deinit */ out: avplay_mutex_unlock(&g_avplay_manager.mutex); return ret; } td_s32 ext_mpi_avplay_get_default_config(uapi_avplay_attr *attr, uapi_avplay_stream_type type) { check_null(attr); check_param(type < UAPI_AVPLAY_STREAM_TYPE_MAX); attr->demux_id = 0; attr->type = type; attr->vid_buf_size = avplay_config_get(AVPLAY_CONFIG_TAG_VID_EB_SIZE); attr->aud_buf_size = avplay_config_get(AVPLAY_CONFIG_TAG_AUD_EB_SIZE); return TD_SUCCESS; } td_s32 ext_mpi_avplay_create(const uapi_avplay_attr *attr, td_handle *avplay) { td_s32 ret; td_handle handle; td_handle alloc_handle = TD_INVALID_HANDLE; avplay_context *ctx = TD_NULL; check_null(attr); check_null(avplay); ret = avplay_check_stream_attr(attr); return_when_error(ret, avplay_check_stream_attr); ret = avplay_hal_create(&alloc_handle); return_when_error(ret, avplay_hal_create); ctx = (avplay_context*)malloc(sizeof(avplay_context)); if (ctx == NULL) { ext_err_avplay("avplay creating malloc context fail\n"); ret = SOC_ERR_AVPLAY_NULL_PTR; goto destory_drv_avplay; } handle = avplay_instance_add(ctx, alloc_handle); if (handle == TD_INVALID_HANDLE) { ret = SOC_ERR_AVPLAY_CREATE_ERR; goto free_context; } avplay_config_init(); ret = avplay_context_init(ctx, handle, attr); goto_when_error(ret, avplay_context_init, deinit_context); debugger_register(ctx); *avplay = handle; return TD_SUCCESS; deinit_context: ret = avplay_context_deinit(ctx); log_when_error(ret, avplay_context_deinit); avplay_instance_del(handle); free_context: free(ctx); ctx = TD_NULL; destory_drv_avplay: ret = avplay_hal_destroy(alloc_handle); log_when_error(ret, avplay_hal_destroy); return ret; } td_s32 ext_mpi_avplay_destroy(td_handle avplay) { td_s32 ret = TD_SUCCESS; avplay_context *ctx = TD_NULL; avplay_instance *instance = avplay_instance_get(avplay); if (instance == TD_NULL) { ext_err_avplay("avplay_instance_get failed.\n"); return SOC_ERR_AVPLAY_INVALID_PARA; } avplay_mutex_lock(&instance->mutex); ctx = instance->ctx; goto_when_ctx_is_null(ctx, ret, out); ret = avplay_context_deinit(ctx); goto_when_error(ret, avplay_context_deinit, out); ret = avplay_hal_destroy(avplay); log_when_error(ret, avplay_hal_destroy); debugger_unregister(ctx); avplay_instance_del(avplay); free(ctx); ctx = TD_NULL; out: avplay_mutex_unlock(&instance->mutex); return ret; } td_s32 ext_mpi_avplay_open_channel(td_handle avplay, uapi_avplay_media_chan chn, const void *param) { avplay_mpi_do_func(avplay, avplay_ctrl_open_channel(AVPLAY_CTX, chn, param)); } td_s32 ext_mpi_avplay_close_channel(td_handle avplay, uapi_avplay_media_chan chn) { avplay_mpi_do_func(avplay, avplay_ctrl_close_channel(AVPLAY_CTX, chn)); } td_s32 ext_mpi_avplay_set_attr(td_handle avplay, uapi_avplay_attr_id id, const void *param) { avplay_mpi_do_func(avplay, avplay_ctrl_set_attr(AVPLAY_CTX, id, param)); } td_s32 ext_mpi_avplay_get_attr(td_handle avplay, uapi_avplay_attr_id id, void *param) { avplay_mpi_do_func(avplay, avplay_ctrl_get_attr(AVPLAY_CTX, id, param)); } td_s32 ext_mpi_avplay_decode_iframe(td_handle avplay, const uapi_avplay_iframe_info *in, uapi_video_frame_info *out) { avplay_mpi_do_func(avplay, avplay_ctrl_decode_iframe(AVPLAY_CTX, in, out)); } td_s32 ext_mpi_avplay_release_iframe(td_handle avplay, uapi_video_frame_info *pic) { avplay_mpi_do_func(avplay, avplay_ctrl_release_iframe(AVPLAY_CTX, pic)); } td_s32 ext_mpi_avplay_set_vcodec_mode(td_handle avplay, uapi_vdec_work_mode mode) { avplay_mpi_do_func(avplay, avplay_ctrl_set_vcodec_mode(AVPLAY_CTX, mode)); } td_s32 ext_mpi_avplay_register_event(td_handle avplay, uapi_avplay_event_type event, uapi_avplay_event_callback_fn callback) { avplay_mpi_do_func(avplay, avplay_ctrl_register_event(AVPLAY_CTX, event, callback)); } td_s32 ext_mpi_avplay_unregister_event(td_handle avplay, uapi_avplay_event_type event) { avplay_mpi_do_func(avplay, avplay_ctrl_unregister_event(AVPLAY_CTX, event)); } td_s32 ext_mpi_avplay_register_acodec_lib(const td_char *lib) { check_null(lib); td_s32 ret = ext_mpi_adec_register_codec(lib, (td_u32)strlen(lib)); if (ret != TD_SUCCESS) { ext_warn_avplay("Register acodec %s failed, ret = 0x%x\n", lib, ret); return ret; } return TD_SUCCESS; } td_s32 ext_mpi_avplay_unregister_acodec_lib(const td_char *lib) { TD_UNUSED(lib); return SOC_ERR_AVPLAY_NOT_SUPPORT; } td_s32 ext_mpi_avplay_register_vcodec_lib(const td_char *lib) { check_null(lib); td_s32 ret = ext_mpi_vdec_register_decoder(lib, (td_u32)strlen(lib)); if (ret != TD_SUCCESS) { ext_warn_avplay("Register vcodec %s failed, ret = 0x%x\n", lib, ret); return ret; } return TD_SUCCESS; } td_s32 ext_mpi_avplay_unregister_vcodec_lib(const td_char *lib) { check_null(lib); td_s32 ret = ext_mpi_vdec_unregister_decoder(lib, (td_u32)strlen(lib)); if (ret != TD_SUCCESS) { ext_warn_avplay("Unregister vcodec %s failed, ret = 0x%x\n", lib, ret); return ret; } return TD_SUCCESS; } td_s32 ext_mpi_avplay_get_acodec_id(const uapi_acodec_format format, td_u32 *acodec_id) { td_s32 ret = ext_mpi_adec_get_codec_id(format, acodec_id); return_when_error(ret, ext_mpi_adec_get_codec_id); return TD_SUCCESS; } td_s32 ext_mpi_avplay_config_acodec(const td_u32 acodec_id, void *config, td_u32 len) { TD_UNUSED(len); td_s32 ret = ext_mpi_adec_config_codec(acodec_id, config); return_when_error(ret, ext_mpi_adec_config_codec); return TD_SUCCESS; } td_s32 ext_mpi_avplay_is_support_acodec(const uapi_acodec_id acodec_id, td_bool *support) { check_null(support); return avplay_adp_check_acodec_support(acodec_id, support); } td_s32 ext_mpi_avplay_prestart(td_handle avplay, uapi_avplay_media_chan chn) { avplay_mpi_do_func(avplay, avplay_ctrl_prestart(AVPLAY_CTX, chn)); } td_s32 ext_mpi_avplay_start(td_handle avplay, uapi_avplay_media_chan chn) { avplay_mpi_do_func(avplay, avplay_ctrl_start(AVPLAY_CTX, chn)); } td_s32 ext_mpi_avplay_stop(td_handle avplay, uapi_avplay_media_chan chn, const uapi_avplay_stop_opt *option) { avplay_mpi_do_func(avplay, avplay_ctrl_stop(AVPLAY_CTX, chn, option)); } td_s32 ext_mpi_avplay_pause(td_handle avplay) { avplay_mpi_do_func(avplay, avplay_ctrl_pause(AVPLAY_CTX)); } td_s32 ext_mpi_avplay_tplay(td_handle avplay, const uapi_avplay_tplay_opt *option) { avplay_mpi_do_func(avplay, avplay_ctrl_tplay(AVPLAY_CTX, option)); } td_s32 ext_mpi_avplay_resume(td_handle avplay) { avplay_mpi_do_func(avplay, avplay_ctrl_resume(AVPLAY_CTX)); } td_s32 ext_mpi_avplay_reset(td_handle avplay, uapi_avplay_media_chan chan, const uapi_avplay_reset_opt *option) { avplay_mpi_do_func(avplay, avplay_ctrl_reset(AVPLAY_CTX, chan, option)); } td_s32 ext_mpi_avplay_getbuf(td_handle avplay, uapi_avplay_buf_id buf_id, td_u32 requset_len, uapi_stream_buf *buf, td_u32 timeout_ms) { avplay_mpi_do_func(avplay, avplay_ctrl_getbuf(AVPLAY_CTX, buf_id, requset_len, buf, timeout_ms)); } td_s32 ext_mpi_avplay_putbuf(td_handle avplay, uapi_avplay_buf_id buf_id, td_u32 len, td_s64 pts, const uapi_avplay_put_buf_opt *option) { avplay_mpi_do_func(avplay, avplay_ctrl_putbuf(AVPLAY_CTX, buf_id, len, pts, option)); } td_s32 ext_mpi_avplay_step(td_handle avplay, const uapi_avplay_step_opt *opt) { avplay_mpi_do_func(avplay, avplay_ctrl_step(AVPLAY_CTX, opt)); } td_s32 ext_mpi_avplay_attach_window(td_handle avplay, td_handle window) { avplay_mpi_do_func(avplay, avplay_ctrl_attach_window(AVPLAY_CTX, window)); } td_s32 ext_mpi_avplay_detach_window(td_handle avplay, td_handle window) { avplay_mpi_do_func(avplay, avplay_ctrl_detach_window(AVPLAY_CTX, window)); } td_s32 ext_mpi_avplay_attach_track(td_handle avplay, td_handle track) { avplay_mpi_do_func(avplay, avplay_ctrl_attach_track(AVPLAY_CTX, track)); } td_s32 ext_mpi_avplay_detach_track(td_handle avplay, td_handle track) { avplay_mpi_do_func(avplay, avplay_ctrl_detach_track(AVPLAY_CTX, track)); } td_s32 ext_mpi_avplay_attach_snd(td_handle avplay, td_handle snd) { avplay_mpi_do_func(avplay, avplay_ctrl_attach_snd(AVPLAY_CTX, snd)); } td_s32 ext_mpi_avplay_detach_snd(td_handle avplay, td_handle snd) { avplay_mpi_do_func(avplay, avplay_ctrl_detach_snd(AVPLAY_CTX, snd)); } td_s32 ext_mpi_avplay_attach_render(td_handle avplay, td_handle render) { avplay_mpi_do_func(avplay, avplay_ctrl_attach_render(AVPLAY_CTX, render)); } td_s32 ext_mpi_avplay_dettach_render(td_handle avplay, td_handle render) { avplay_mpi_do_func(avplay, avplay_ctrl_dettach_render(AVPLAY_CTX, render)); } td_s32 ext_mpi_avplay_get_status_info(td_handle avplay, uapi_avplay_status_type type, td_void *status_info) { avplay_mpi_do_func(avplay, avplay_ctrl_get_status_info(AVPLAY_CTX, type, status_info)); } td_s32 ext_mpi_avplay_get_stream_info(td_handle avplay, uapi_avplay_stream_info *stream_info) { avplay_mpi_do_func(avplay, avplay_ctrl_get_stream_info(AVPLAY_CTX, stream_info)); } td_s32 ext_mpi_avplay_switch_to_external_audio(td_handle avplay, td_bool is_switch) { avplay_mpi_do_func(avplay, avplay_ctrl_switch_to_external_audio(AVPLAY_CTX, is_switch)); } td_s32 ext_mpi_avplay_switch_aud_dmx(td_handle avplay, td_handle new_dmx, td_handle *old_dmx) { avplay_mpi_do_func(avplay, avplay_ctrl_switch_aud_dmx(AVPLAY_CTX, new_dmx, old_dmx)); } td_s32 ext_mpi_avplay_acq_user_data(td_handle avplay, uapi_video_userdata_type type, uapi_video_userdata *data) { avplay_mpi_do_func(avplay, avplay_ctrl_acq_user_data(AVPLAY_CTX, type, data)); } td_s32 ext_mpi_avplay_rls_user_data(td_handle avplay, uapi_video_userdata_type type, const uapi_video_userdata *data) { avplay_mpi_do_func(avplay, avplay_ctrl_rls_user_data(AVPLAY_CTX, type, data)); } td_s32 ext_mpi_avplay_set_hdr_info(td_handle avplay, const uapi_hdr_info *hdr, uapi_avplay_hdr_opt *opt) { avplay_mpi_do_func(avplay, avplay_ctrl_set_hdr_info(AVPLAY_CTX, hdr, opt)); } td_s32 ext_mpi_avplay_get_hdr_info(td_handle avplay, uapi_hdr_info *hdr) { avplay_mpi_do_func(avplay, avplay_ctrl_get_hdr_info(AVPLAY_CTX, hdr)); } td_s32 ext_mpi_avplay_flush_stream(td_handle avplay, const uapi_avplay_flush_stream_opt *opt) { avplay_mpi_do_func(avplay, avplay_ctrl_flush_stream(AVPLAY_CTX, opt)); } td_s32 ext_mpi_avplay_is_buffer_empty(td_handle avplay, td_bool *is_empty) { avplay_mpi_do_func(avplay, avplay_ctrl_is_buffer_empty(AVPLAY_CTX, is_empty)); } td_s32 ext_mpi_avplay_is_support_random_stream(td_handle avplay, td_bool *support) { avplay_mpi_do_func(avplay, avplay_ctrl_is_support_random_stream(AVPLAY_CTX, support)); } td_s32 ext_mpi_avplay_get_dmx_handle(td_handle avplay, uapi_avplay_demux_handle_type id, td_handle *vid_dmx) { avplay_mpi_do_func(avplay, avplay_ctrl_get_dmx_handle(AVPLAY_CTX, id, vid_dmx)); } td_s32 ext_mpi_avplay_set_framebuffer_mode(td_handle avplay, ext_avplay_framebuffer_mode mode) { avplay_mpi_do_func(avplay, avplay_ctrl_set_framebuffer_mode(AVPLAY_CTX, mode)); } td_s32 ext_mpi_avplay_set_external_framebuffer(td_handle avplay, const ext_avplay_framebuffer_info *fb, td_u32 cnt) { avplay_mpi_do_func(avplay, avplay_ctrl_set_external_framebuffer(AVPLAY_CTX, fb, cnt)); } td_s32 ext_mpi_avplay_unset_external_framebuffer(td_handle avplay, const ext_avplay_framebuffer_info *fb, td_u32 cnt) { avplay_mpi_do_func(avplay, avplay_ctrl_unset_external_framebuffer(AVPLAY_CTX, fb, cnt)); } td_s32 ext_mpi_avplay_set_disp_ctrl(td_handle avplay, td_bool is_stream_continuos, const uapi_avplay_tplay_opt *option) { avplay_mpi_do_func(avplay, avplay_ctrl_set_disp_ctrl(AVPLAY_CTX, is_stream_continuos, option)); } td_s32 ext_mpi_avplay_set_session_info(td_handle avplay, const uapi_avplay_session_info *info) { avplay_mpi_do_func(avplay, avplay_ctrl_set_session_info(AVPLAY_CTX, info)); } td_s32 ext_mpi_avplay_get_aud_status(td_handle avplay, uapi_avplay_aud_chan_status *status) { avplay_mpi_do_func(avplay, avplay_ctrl_get_aud_status(AVPLAY_CTX, status)); } td_s32 ext_mpi_avplay_get_snd_handle(td_handle avplay, td_handle *snd) { avplay_mpi_do_func(avplay, avplay_ctrl_get_snd_handle(AVPLAY_CTX, snd)); } td_s32 ext_mpi_avplay_get_win_handle(td_handle avplay, td_handle *win) { avplay_mpi_do_func(avplay, avplay_ctrl_get_win_handle(AVPLAY_CTX, win)); } td_s32 ext_mpi_avplay_invoke(td_handle avplay, uapi_avplay_invoke_type invoke_type, void *param) { if (invoke_type == UAPI_AVPLAY_INVOKE_GET_GLOBAL_PLAYINFO) { check_null(param); return avplay_hal_get_global_play_info(avplay, (avplay_global_play_info*)param); } avplay_mpi_do_func(avplay, avplay_ctrl_invoke(AVPLAY_CTX, invoke_type, param)); } td_s32 ext_mpi_avplay_get_handle_by_window(td_handle win, td_handle *avplay) { check_null(avplay); *avplay = TD_INVALID_HANDLE; return avplay_hal_get_resource(win, AVPLAY_RESOURCE_TYPE_AVPLAY, avplay); } td_s32 ext_mpi_avplay_get_video_frame_info(td_handle avplay, uapi_video_frame_info *info) { check_null(info); avplay_video_info video_info = {0}; td_s32 ret = avplay_hal_get_video_info(avplay, &video_info); if (ret != TD_SUCCESS) { return ret; } info->decode_width = video_info.width; info->decode_height = video_info.height; info->aspect_width = video_info.aspect_width; info->aspect_height = video_info.aspect_height; info->frame_rate = video_info.fps; info->scan_type = video_info.sampling_type; return TD_SUCCESS; } td_s32 ext_mpi_avplay_get_vdec_capability(uapi_vcodec_type type, uapi_vdec_output_capability *capability) { check_null(capability); return avplay_adp_get_vdec_capability(type, capability); }