mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 18:38:55 +00:00
1399 lines
49 KiB
C
1399 lines
49 KiB
C
/*
|
|
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Author: <jun.ma@artinchip.com>
|
|
* Desc: aic_player api
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "mm_core.h"
|
|
#include "mpp_dec_type.h"
|
|
#include "mpp_log.h"
|
|
#include "mpp_mem.h"
|
|
#include "mpp_dec_type.h"
|
|
#include "aic_parser.h"
|
|
#include "aic_player.h"
|
|
|
|
#define AIC_PLAYER_STATE_IDLE 0
|
|
#define AIC_PLAYER_STATE_INITIALIZED 1
|
|
#define AIC_PLAYER_STATE_PREPARING 2
|
|
#define AIC_PLAYER_STATE_PREPARED 3
|
|
#define AIC_PLAYER_STATE_STARTED 4
|
|
#define AIC_PLAYER_STATE_PLAYING 5
|
|
#define AIC_PLAYER_STATE_PAUSED 6
|
|
#define AIC_PLAYER_STATE_STOPPED 7
|
|
#define AIC_PLAYER_STATE_PLAYBACK_COMPLETED 8
|
|
|
|
#define AIC_VIDEO 0x01
|
|
#define AIC_AUDIO 0x02
|
|
|
|
#define AIC_PLAYER_PREPARE_FORMAT_DETECTING 0
|
|
#define AIC_PLAYER_PREPARE_FORMAT_DETECTED 1
|
|
#define AIC_PLAYER_PREPARE_FORMAT_NOT_DETECTED 2
|
|
|
|
struct aic_player {
|
|
event_handler event_handle;
|
|
void* app_data;
|
|
mm_handle demuxer_handle;
|
|
mm_handle vdecoder_handle;
|
|
mm_handle adecoder_handle;
|
|
mm_handle video_render_handle;
|
|
mm_handle audio_render_handle;
|
|
mm_handle clock_handle;
|
|
s32 format_detected;//0-dectecting , 1-dectected ,2- not_detected
|
|
struct aic_parser_av_media_info media_info;
|
|
u32 video_audio_end_mask;
|
|
u32 video_audio_seek_mask;
|
|
int state;
|
|
struct mpp_rect disp_rect;
|
|
u32 sync_flag;
|
|
pthread_t threadId;
|
|
s32 thread_runing;
|
|
mm_param_content_uri * uri_param;
|
|
s64 video_pts;
|
|
s64 audio_pts;
|
|
s32 volume;
|
|
s32 rotation_angle;
|
|
s8 mute;
|
|
s8 seeking;
|
|
s8 video_render_keep_last_frame;
|
|
#ifdef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
void *vdec_allocator;
|
|
s8 init_vdec_crop;
|
|
struct mpp_dec_crop_info vdec_crop;
|
|
#endif
|
|
};
|
|
|
|
|
|
#define wait_state(\
|
|
h_component,\
|
|
des_state)\
|
|
{\
|
|
MM_STATE_TYPE state;\
|
|
while(1) {\
|
|
mm_get_state(h_component, &state);\
|
|
if (state == des_state) {\
|
|
break;\
|
|
} else {\
|
|
usleep(1000);\
|
|
}\
|
|
}\
|
|
} /* Macro End */
|
|
|
|
#define _CLOCK_COMPONENT_
|
|
|
|
static s32 component_event_handler (
|
|
mm_handle h_component,
|
|
void* p_app_data,
|
|
MM_EVENT_TYPE event,
|
|
u32 data1,
|
|
u32 data2,
|
|
void* p_event_data)
|
|
{
|
|
s32 error = MM_ERROR_NONE;
|
|
struct aic_player *player = (struct aic_player *)p_app_data;
|
|
//struct aic_parser_av_media_info sMediaInfo;
|
|
|
|
switch((s32)event) {
|
|
case MM_EVENT_CMD_COMPLETE:
|
|
break;
|
|
case MM_EVENT_BUFFER_FLAG:
|
|
if (player->media_info.has_video) {
|
|
if (player->video_render_handle == h_component) {
|
|
player->video_audio_end_mask &= ~AIC_VIDEO;
|
|
logi("[%s:%d]rececive video_render_end,video_audio_end_mask:%d!!!\n",
|
|
__FUNCTION__, __LINE__, player->video_audio_end_mask);
|
|
if (player->video_audio_end_mask == 0) {
|
|
player->event_handle(player->app_data,AIC_PLAYER_EVENT_PLAY_END, 0, 0);
|
|
player->state = AIC_PLAYER_STATE_PLAYBACK_COMPLETED;
|
|
logi("[%s:%d]play end!!!\n",__FUNCTION__,__LINE__);
|
|
}
|
|
}
|
|
}
|
|
if (player->media_info.has_audio) {
|
|
if (player->audio_render_handle == h_component) {
|
|
player->video_audio_end_mask &= ~AIC_AUDIO;
|
|
logi("[%s:%d]rececive audio_render_handle,video_audio_end_mask:%d!!!\n",
|
|
__FUNCTION__, __LINE__, player->video_audio_end_mask);
|
|
if (player->video_audio_end_mask == 0) {
|
|
player->event_handle(player->app_data, AIC_PLAYER_EVENT_PLAY_END, 0, 0);
|
|
player->state = AIC_PLAYER_STATE_PLAYBACK_COMPLETED;
|
|
logi("[%s:%d]play end!!!\n", __FUNCTION__, __LINE__);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
case MM_EVENT_PORT_FORMAT_DETECTED:
|
|
logi("[%s:%d]MM_EVENT_PORT_FORMAT_DETECTED\n", __FUNCTION__, __LINE__);
|
|
memcpy(&player->media_info, p_event_data, sizeof(struct aic_parser_av_media_info));
|
|
player->format_detected = AIC_PLAYER_PREPARE_FORMAT_DETECTED;
|
|
//player->event_handle(player->app_data,AIC_PLAYER_EVENT_DEMUXER_FORMAT_DETECTED,0,0);
|
|
break;
|
|
case MM_EVENT_ERROR:
|
|
if (data1 == MM_ERROR_FORMAT_NOT_DETECTED) {
|
|
player->format_detected = AIC_PLAYER_PREPARE_FORMAT_NOT_DETECTED;
|
|
// player->event_handle(player->app_data,AIC_PLAYER_EVENT_DEMUXER_FORMAT_NOT_DETECTED,0,0);
|
|
} else if (data1 == MM_ERROR_MB_ERRORS_IN_FRAME || data1 == MM_ERROR_INSUFFICIENT_RESOURCES) {
|
|
player->event_handle(player->app_data, AIC_PLAYER_EVENT_PLAY_END, 0, 0);
|
|
player->state = AIC_PLAYER_STATE_PLAYBACK_COMPLETED;
|
|
logi("[%s:%d]play end!!!\n", __FUNCTION__, __LINE__);
|
|
}
|
|
break;
|
|
case MM_EVENT_VIDEO_RENDER_PTS:
|
|
player->video_pts = data1;
|
|
player->video_pts = (player->video_pts << (sizeof(u32)*8));
|
|
player->video_pts |= data2;
|
|
//loge("video_pts:%lld\n",video_pts);
|
|
break;
|
|
case MM_EVENT_AUDIO_RENDER_PTS:
|
|
player->audio_pts = data1;
|
|
player->audio_pts = (player->audio_pts << (sizeof(u32)*8));
|
|
player->audio_pts |= data2;
|
|
player->event_handle(player->app_data,AIC_PLAYER_EVENT_PLAY_TIME,data1,data2);
|
|
break;
|
|
case MM_EVENT_VIDEO_RENDER_FIRST_FRAME:
|
|
case MM_EVENT_AUDIO_RENDER_FIRST_FRAME:
|
|
if (player->media_info.has_video) {
|
|
if (player->video_render_handle == h_component) {
|
|
logi("[%s:%d]first video frame come!!!\n",__FUNCTION__,__LINE__);
|
|
player->video_audio_seek_mask &= ~AIC_VIDEO;
|
|
if (player->video_audio_seek_mask == 0) {
|
|
player->seeking = 0;
|
|
}
|
|
}
|
|
}
|
|
if (player->media_info.has_audio) {
|
|
if (player->audio_render_handle == h_component) {
|
|
logi("[%s:%d]first audio frame come!!!\n",__FUNCTION__,__LINE__);
|
|
player->video_audio_seek_mask &= ~AIC_AUDIO;
|
|
if (player->video_audio_seek_mask == 0) {
|
|
player->seeking = 0;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
|
|
mm_callback component_event_callbacks = {
|
|
.event_handler = component_event_handler
|
|
};
|
|
|
|
struct aic_player* aic_player_create(char *uri)
|
|
{
|
|
s32 error;
|
|
struct aic_player * player = mpp_alloc(sizeof(struct aic_player));
|
|
|
|
if (player == NULL) {
|
|
loge("mpp_alloc aic_player error\n");
|
|
return NULL;
|
|
}
|
|
|
|
memset(player,0x00,sizeof(struct aic_player));
|
|
|
|
player->uri_param =
|
|
(mm_param_content_uri *)mpp_alloc(sizeof(mm_param_content_uri) + MM_MAX_STRINGNAME_SIZE);
|
|
|
|
if (player->uri_param == NULL) {
|
|
loge("mpp_alloc aic_player error\n");
|
|
goto _exit;
|
|
}
|
|
|
|
error = mm_init();
|
|
|
|
if (error != MM_ERROR_NONE) {
|
|
loge("mm_init error!!!\n");
|
|
goto _exit;
|
|
}
|
|
|
|
if (uri != NULL) {
|
|
if (aic_player_set_uri(player,uri)) {
|
|
loge("aic_player_set_uri error!!!\n");
|
|
goto _exit;
|
|
}
|
|
} else {
|
|
player->state = AIC_PLAYER_STATE_IDLE;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_get_handle(&player->demuxer_handle,
|
|
MM_COMPONENT_DEMUXER_NAME,
|
|
player, &component_event_callbacks)) {
|
|
loge("unable to get demuxer handle.\n");
|
|
goto _exit;
|
|
}
|
|
|
|
return player;
|
|
|
|
_exit:
|
|
if (player->uri_param) {
|
|
mpp_free(player->uri_param);
|
|
player->uri_param = NULL;
|
|
}
|
|
mpp_free(player);
|
|
return NULL;
|
|
}
|
|
|
|
s32 aic_player_set_uri(struct aic_player *player,char *uri)
|
|
{
|
|
int uri_len;
|
|
|
|
if (uri == NULL) {
|
|
loge("param error\n");
|
|
return -1;
|
|
}
|
|
if (player->uri_param == NULL) {
|
|
loge("player->uri_param=NULL\n");
|
|
return -1;
|
|
}
|
|
uri_len = strlen(uri);
|
|
if (uri_len > MM_MAX_STRINGNAME_SIZE-1) {
|
|
loge("path too long\n");
|
|
return -1;
|
|
}
|
|
memset(player->uri_param->content_uri,0x00,MM_MAX_STRINGNAME_SIZE);
|
|
player->uri_param->size = sizeof(mm_param_content_uri) + uri_len;
|
|
strcpy((char *)player->uri_param->content_uri,uri);
|
|
player->state = AIC_PLAYER_STATE_INITIALIZED;
|
|
return 0;
|
|
}
|
|
|
|
static void* player_index_param_content_uri_thread(void *pThreadData)
|
|
{
|
|
struct aic_player *player = (struct aic_player *)pThreadData;
|
|
player->format_detected = AIC_PLAYER_PREPARE_FORMAT_DETECTING;
|
|
player->state = AIC_PLAYER_STATE_PREPARING;
|
|
/*mm_set_parameter is blocking*/
|
|
player->thread_runing = 1;
|
|
mm_set_parameter(player->demuxer_handle, MM_INDEX_PARAM_CONTENT_URI, player->uri_param);
|
|
if (player->format_detected != AIC_PLAYER_PREPARE_FORMAT_DETECTED) {
|
|
loge("MM_ERROR_FORMAT_NOT_DETECTED !!!!");
|
|
player->event_handle(player->app_data, AIC_PLAYER_EVENT_DEMUXER_FORMAT_NOT_DETECTED, 0, 0);
|
|
return (void*)-1;
|
|
} else {
|
|
player->state = AIC_PLAYER_STATE_PREPARED;
|
|
player->event_handle(player->app_data, AIC_PLAYER_EVENT_DEMUXER_FORMAT_DETECTED, 0, 0);
|
|
}
|
|
player->thread_runing = 0;
|
|
return (void*)0;
|
|
}
|
|
|
|
s32 aic_player_prepare_async(struct aic_player *player)
|
|
{
|
|
int ret = 0;
|
|
if (player->state == AIC_PLAYER_STATE_PREPARING) {
|
|
logw("player->state hase been in AIC_PLAYER_STATE_PREPARING \n");
|
|
return 0;
|
|
}
|
|
if (NULL == player->demuxer_handle) {
|
|
loge("player->demuxer_handle has not been created \n");
|
|
return -1;
|
|
}
|
|
|
|
player->sync_flag = AIC_PLAYER_PREPARE_ASYNC;
|
|
|
|
ret = pthread_create(&player->threadId, NULL, player_index_param_content_uri_thread, player);
|
|
if (ret) {
|
|
loge("pthread_create fail!");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
s32 aic_player_prepare_sync(struct aic_player *player)
|
|
{
|
|
s32 error = MM_ERROR_NONE;
|
|
if (player->state != AIC_PLAYER_STATE_INITIALIZED) {
|
|
loge("player->state is not in AIC_PLAYER_STATE_INITIALIZED,plaese set uri!!!\n");
|
|
return -1;
|
|
}
|
|
|
|
if (NULL == player->demuxer_handle) {
|
|
loge("player->demuxer_handle has not been created \n");
|
|
return -1;
|
|
}
|
|
|
|
player->sync_flag = AIC_PLAYER_PREPARE_SYNC;
|
|
player->format_detected = AIC_PLAYER_PREPARE_FORMAT_DETECTING;
|
|
/*mm_set_parameter is blocking*/
|
|
error = mm_set_parameter(player->demuxer_handle,
|
|
MM_INDEX_PARAM_CONTENT_URI,
|
|
player->uri_param);
|
|
if ((error != MM_ERROR_NONE) ||
|
|
(player->format_detected != AIC_PLAYER_PREPARE_FORMAT_DETECTED)) {
|
|
loge("MM_ERROR_FORMAT_NOT_DETECTED!!!!");
|
|
return -1;
|
|
} else {
|
|
player->state = AIC_PLAYER_STATE_PREPARED;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_start_video(struct aic_player *player)
|
|
{
|
|
mm_video_param_port_format video_port_format;
|
|
|
|
if (player->media_info.has_video) {
|
|
video_port_format.port_index = DEMUX_PORT_VIDEO_INDEX;
|
|
video_port_format.index = 0;
|
|
if (MM_ERROR_NONE != mm_get_parameter(player->demuxer_handle,
|
|
MM_INDEX_PARAM_VIDEO_PORT_FORMAT,
|
|
&video_port_format)) {
|
|
loge("mm_get_parameter Error!!!!.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (player->vdecoder_handle) {
|
|
loge("please call aic_player_stop,free(vdecoder_handle)\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_get_handle(&player->vdecoder_handle,
|
|
MM_COMPONENT_VDEC_NAME, player,
|
|
&component_event_callbacks)) {
|
|
loge("unable to get vdecoder_handle handle.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
#ifdef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->vdec_allocator) {
|
|
if (MM_ERROR_NONE != mm_set_config(player->vdecoder_handle,
|
|
MM_INDEX_CONFIG_VIDEO_DECODER_EXT_FRAME_ALLOCATOR,
|
|
player->vdec_allocator)) {
|
|
loge("set allocator to vdec comp failed.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
if (player->init_vdec_crop) {
|
|
if (MM_ERROR_NONE != mm_set_config(player->vdecoder_handle,
|
|
MM_INDEX_CONFIG_VIDEO_DECODER_CROP_INFO,
|
|
(void *)&player->vdec_crop)) {
|
|
loge("set vdec comp crop info failed.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
video_port_format.color_format = MM_COLOR_FORMAT_YUV420P;
|
|
if (video_port_format.compression_format == MM_VIDEO_CODING_MJPEG) {
|
|
if (strcmp(PRJ_CHIP, "d12x") == 0) {
|
|
switch (AICFB_FORMAT) {
|
|
case 0x00:
|
|
video_port_format.color_format =
|
|
MM_COLOR_FORMAT_ARGB8888;
|
|
break;
|
|
case 0x08:
|
|
video_port_format.color_format = MM_COLOR_FORMAT_RGB888;
|
|
break;
|
|
case 0x0a:
|
|
video_port_format.color_format =
|
|
MM_COLOR_FORMAT_ARGB1555;
|
|
break;
|
|
case 0x0e:
|
|
video_port_format.color_format = MM_COLOR_FORMAT_RGB565;
|
|
break;
|
|
default:
|
|
loge("unsupport format:%d\n", AICFB_FORMAT);
|
|
return MM_ERROR_UNSUPPORT;
|
|
}
|
|
} else {
|
|
video_port_format.color_format = MM_COLOR_FORMAT_NV12;
|
|
}
|
|
}
|
|
|
|
video_port_format.port_index = VDEC_PORT_IN_INDEX;
|
|
|
|
if (MM_ERROR_NONE != mm_set_parameter(player->vdecoder_handle,
|
|
MM_INDEX_PARAM_VIDEO_PORT_FORMAT,
|
|
&video_port_format)) {
|
|
mm_param_skip_track skip_track;
|
|
loge("MM_INDEX_PARAM_VIDEO_PORT_FORMAT Error!!!!.\n");
|
|
skip_track.port_index = DEMUX_PORT_VIDEO_INDEX;
|
|
mm_set_parameter(player->demuxer_handle,
|
|
MM_INDEX_VENDOR_DEMUXER_SKIP_TRACK, &skip_track);
|
|
mm_free_handle(player->vdecoder_handle);
|
|
player->vdecoder_handle = NULL;
|
|
player->media_info.has_video = 0;
|
|
return MM_ERROR_BAD_PARAMETER;
|
|
}
|
|
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->video_render_handle) {
|
|
loge("please call aic_player_stop,free(vdecoder_handle)\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_get_handle(&player->video_render_handle,
|
|
MM_COMPONENT_VIDEO_RENDER_NAME,
|
|
player,
|
|
&component_event_callbacks)) {
|
|
loge("unable to get video_render_handle handle.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_set_config(player->video_render_handle,
|
|
MM_INDEX_VENDOR_VIDEO_RENDER_INIT,
|
|
NULL)) {
|
|
loge("mm_set_config Error!!!!.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (player->disp_rect.width != 0 && player->disp_rect.height != 0) {
|
|
aic_player_set_disp_rect(player, &player->disp_rect);
|
|
}
|
|
if (player->rotation_angle != MPP_ROTATION_0) {
|
|
aic_player_set_rotation(player, player->rotation_angle);
|
|
}
|
|
#endif
|
|
if (MM_ERROR_NONE !=
|
|
mm_set_bind(player->demuxer_handle, DEMUX_PORT_VIDEO_INDEX,
|
|
player->vdecoder_handle, VDEC_PORT_IN_INDEX)) {
|
|
loge("mm_set_bind error.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (MM_ERROR_NONE != mm_set_bind(player->vdecoder_handle,
|
|
VDEC_PORT_OUT_INDEX,
|
|
player->video_render_handle,
|
|
VIDEO_RENDER_PORT_IN_VIDEO_INDEX)) {
|
|
loge("mm_set_bind error.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
#endif
|
|
player->video_audio_end_mask |= AIC_VIDEO;
|
|
}
|
|
|
|
return MM_ERROR_NONE;
|
|
}
|
|
|
|
|
|
s32 aic_player_start_audio(struct aic_player *player)
|
|
{
|
|
mm_audio_param_port_format audio_port_format;
|
|
|
|
if (player->media_info.has_audio) {
|
|
audio_port_format.port_index = DEMUX_PORT_AUDIO_INDEX;
|
|
audio_port_format.index = 0;
|
|
|
|
if (MM_ERROR_NONE != mm_get_parameter(player->demuxer_handle,
|
|
MM_INDEX_PARAM_AUDIO_PORT_FORMAT,
|
|
&audio_port_format)) {
|
|
loge("mm_get_parameter Error!!!!.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (player->adecoder_handle) {
|
|
loge("please call aic_player_stop,free(adecoder_handle)\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_get_handle(&player->adecoder_handle,
|
|
MM_COMPONENT_ADEC_NAME, player,
|
|
&component_event_callbacks)) {
|
|
loge("unable to get adecoder_handle handle.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
audio_port_format.port_index = ADEC_PORT_IN_INDEX;
|
|
|
|
if (MM_ERROR_NONE != mm_set_parameter(player->adecoder_handle,
|
|
MM_INDEX_PARAM_AUDIO_PORT_FORMAT,
|
|
&audio_port_format)) {
|
|
mm_param_skip_track skip_track;
|
|
loge("MM_INDEX_PARAM_AUDIO_PORT_FORMAT Error!!!!.\n");
|
|
skip_track.port_index = DEMUX_PORT_AUDIO_INDEX;
|
|
mm_set_parameter(player->demuxer_handle,
|
|
MM_INDEX_VENDOR_DEMUXER_SKIP_TRACK, &skip_track);
|
|
mm_free_handle(player->adecoder_handle);
|
|
player->adecoder_handle = NULL;
|
|
player->media_info.has_audio = 0;
|
|
return MM_ERROR_BAD_PARAMETER;
|
|
}
|
|
|
|
if (player->audio_render_handle) {
|
|
loge("please call aic_player_stop,free(audio_render_handle)\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_get_handle(&player->audio_render_handle,
|
|
MM_COMPONENT_AUDIO_RENDER_NAME,
|
|
player,
|
|
&component_event_callbacks)) {
|
|
loge("unable to get audio_render_handle handle.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_set_config(player->audio_render_handle,
|
|
MM_INDEX_VENDOR_AUDIO_RENDER_INIT,
|
|
NULL)) {
|
|
logd("audio render init error!!!!.\n");
|
|
mm_free_handle(player->audio_render_handle);
|
|
player->audio_render_handle = NULL;
|
|
player->media_info.has_audio = 0;
|
|
return MM_ERROR_UNDEFINED;
|
|
}
|
|
|
|
if (player->volume != 0) {
|
|
aic_player_set_volum(player, player->volume);
|
|
}
|
|
|
|
if (MM_ERROR_NONE !=
|
|
mm_set_bind(player->demuxer_handle, DEMUX_PORT_AUDIO_INDEX,
|
|
player->adecoder_handle, ADEC_PORT_IN_INDEX)) {
|
|
loge("mm_set_bind error.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_set_bind(player->adecoder_handle,
|
|
ADEC_PORT_OUT_INDEX,
|
|
player->audio_render_handle,
|
|
AUDIO_RENDER_PORT_IN_AUDIO_INDEX)) {
|
|
loge("mm_set_bind error.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
player->video_audio_end_mask |= AIC_AUDIO;
|
|
}
|
|
|
|
return MM_ERROR_NONE;
|
|
}
|
|
|
|
|
|
s32 aic_player_start_clock(struct aic_player *player)
|
|
{
|
|
#ifdef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
return MM_ERROR_NONE;
|
|
#endif
|
|
|
|
#ifdef _CLOCK_COMPONENT_
|
|
if (player->media_info.has_video && player->media_info.has_audio) {
|
|
mm_time_config_clock_state clock_state;
|
|
|
|
if (player->clock_handle) {
|
|
loge("please call aic_player_stop,free(clock_handle)\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_get_handle(&player->clock_handle,
|
|
MM_COMPONENT_CLOCK_NAME, player,
|
|
&component_event_callbacks)) {
|
|
loge("unable to get clock_handle handle.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_set_bind(player->clock_handle,
|
|
CLOCK_PORT_OUT_VIDEO,
|
|
player->video_render_handle,
|
|
VIDEO_RENDER_PORT_IN_CLOCK_INDEX)) {
|
|
loge("unable to bind video_render component and clock component.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_set_bind(player->clock_handle,
|
|
CLOCK_PORT_OUT_AUDIO,
|
|
player->audio_render_handle,
|
|
AUDIO_RENDER_PORT_IN_CLOCK_INDEX)) {
|
|
loge("unable to bind audio_render component and clock component.\n");
|
|
return MM_ERROR_INSUFFICIENT_RESOURCES;
|
|
}
|
|
memset(&clock_state, 0x00, sizeof(mm_time_config_clock_state));
|
|
clock_state.state = MM_TIME_CLOCK_STATE_WAITING_FOR_START_TIME;
|
|
clock_state.wait_mask |= MM_CLOCK_PORT0;
|
|
clock_state.wait_mask |= MM_CLOCK_PORT1;
|
|
mm_set_config(player->clock_handle, MM_INDEX_CONFIG_TIME_CLOCK_STATE,
|
|
&clock_state);
|
|
}
|
|
#endif
|
|
|
|
return MM_ERROR_NONE;
|
|
}
|
|
|
|
s32 aic_player_start(struct aic_player *player)
|
|
{
|
|
s32 ret = MM_ERROR_NONE;
|
|
|
|
if (player->state == AIC_PLAYER_STATE_STARTED) {
|
|
loge("player->state has been in AIC_PLAYER_STATE_STARTED \n");
|
|
return 0;
|
|
}
|
|
|
|
if (player->state != AIC_PLAYER_STATE_PREPARED) {
|
|
loge("player->state is not in AIC_PLAYER_STATE_PREPARED ,it can not do this opt\n");
|
|
return -1;
|
|
}
|
|
|
|
if (player->sync_flag == AIC_PLAYER_PREPARE_ASYNC) {
|
|
if (player->threadId != 0) {
|
|
pthread_join(player->threadId, NULL);
|
|
player->threadId = 0;
|
|
}
|
|
}
|
|
|
|
ret = aic_player_start_video(player);
|
|
if ((MM_ERROR_INSUFFICIENT_RESOURCES == ret) || (MM_ERROR_UNSUPPORT == ret)) {
|
|
goto _EXIT;
|
|
}
|
|
|
|
ret = aic_player_start_audio(player);
|
|
if (MM_ERROR_INSUFFICIENT_RESOURCES == ret) {
|
|
goto _EXIT;
|
|
}
|
|
|
|
ret = aic_player_start_clock(player);
|
|
if (MM_ERROR_INSUFFICIENT_RESOURCES == ret) {
|
|
goto _EXIT;
|
|
}
|
|
|
|
if (!player->vdecoder_handle && !player->adecoder_handle) {
|
|
loge("video and audio all do not support !!!!.\n");
|
|
goto _EXIT;
|
|
}
|
|
#ifdef _CLOCK_COMPONENT_
|
|
if (player->clock_handle) {
|
|
mm_send_command(player->clock_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_IDLE, NULL);
|
|
}
|
|
#endif
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->media_info.has_video && player->video_render_handle) {
|
|
mm_send_command(player->video_render_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_IDLE, NULL);
|
|
}
|
|
#endif
|
|
if (player->media_info.has_video && player->vdecoder_handle) {
|
|
mm_send_command(player->vdecoder_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_IDLE, NULL);
|
|
}
|
|
if (player->media_info.has_audio && player->audio_render_handle &&
|
|
player->adecoder_handle) {
|
|
mm_send_command(player->audio_render_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_IDLE, NULL);
|
|
mm_send_command(player->adecoder_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_IDLE, NULL);
|
|
}
|
|
if (player->demuxer_handle) {
|
|
mm_send_command(player->demuxer_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_IDLE, NULL);
|
|
}
|
|
player->state = AIC_PLAYER_STATE_STARTED;
|
|
|
|
if (aic_player_play(player)) {
|
|
loge("aic_player_play fail !!!!.\n");
|
|
goto _EXIT;
|
|
}
|
|
|
|
return 0;
|
|
|
|
_EXIT:
|
|
|
|
#ifdef _CLOCK_COMPONENT_
|
|
if (player->clock_handle) {
|
|
mm_free_handle(player->clock_handle);
|
|
player->clock_handle = NULL;
|
|
}
|
|
#endif
|
|
|
|
if (player->audio_render_handle) {
|
|
mm_free_handle(player->audio_render_handle);
|
|
player->audio_render_handle = NULL;
|
|
}
|
|
|
|
if (player->adecoder_handle) {
|
|
mm_free_handle(player->adecoder_handle);
|
|
player->adecoder_handle = NULL;
|
|
}
|
|
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->video_render_handle) {
|
|
mm_free_handle(player->video_render_handle);
|
|
player->video_render_handle = NULL;
|
|
}
|
|
#endif
|
|
|
|
if (player->vdecoder_handle) {
|
|
mm_free_handle(player->vdecoder_handle);
|
|
player->vdecoder_handle = NULL;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
s32 aic_player_play(struct aic_player *player)
|
|
{
|
|
if (player->state == AIC_PLAYER_STATE_PLAYING) {
|
|
logi("it is already in AIC_PLAYER_STATE_PLAYING\n");
|
|
return 0;
|
|
}
|
|
if (player->state != AIC_PLAYER_STATE_STARTED &&
|
|
player->state != AIC_PLAYER_STATE_PAUSED) {
|
|
loge("player->state:[%d] in AIC_PLAYER_STATE_STARTED or "
|
|
"AIC_PLAYER_STATE_PAUSED ,it can not do this opt\n",
|
|
player->state);
|
|
return -1;
|
|
}
|
|
|
|
#ifdef _CLOCK_COMPONENT_
|
|
if (player->clock_handle) {
|
|
mm_send_command(player->clock_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_EXECUTING, NULL);
|
|
}
|
|
#endif
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->media_info.has_video && player->video_render_handle) {
|
|
mm_send_command(player->video_render_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_EXECUTING, NULL);
|
|
}
|
|
#endif
|
|
if (player->media_info.has_audio && player->audio_render_handle) {
|
|
mm_send_command(player->audio_render_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_EXECUTING, NULL);
|
|
}
|
|
if (player->media_info.has_video && player->vdecoder_handle) {
|
|
mm_send_command(player->vdecoder_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_EXECUTING, NULL);
|
|
}
|
|
if (player->media_info.has_audio && player->adecoder_handle) {
|
|
mm_send_command(player->adecoder_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_EXECUTING, NULL);
|
|
}
|
|
if (player->demuxer_handle) {
|
|
mm_send_command(player->demuxer_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_EXECUTING, NULL);
|
|
}
|
|
|
|
player->state = AIC_PLAYER_STATE_PLAYING;
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_pause(struct aic_player *player)
|
|
{
|
|
if (player->state == AIC_PLAYER_STATE_PAUSED) {
|
|
logi("it is already in AIC_PLAYER_STATE_PAUSED\n");
|
|
return aic_player_play(player);
|
|
} else if (player->state != AIC_PLAYER_STATE_PLAYING &&
|
|
player->state != AIC_PLAYER_STATE_PLAYBACK_COMPLETED) {
|
|
loge("player->state:[%d] in AIC_PLAYER_STATE_STARTED or "
|
|
"AIC_PLAYER_STATE_PAUSED ,it can not do this opt\n", player->state);
|
|
return -1;
|
|
}
|
|
if (player->media_info.has_audio && player->audio_render_handle
|
|
&& player->adecoder_handle) {
|
|
mm_send_command(player->audio_render_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_PAUSE, NULL);
|
|
wait_state(player->audio_render_handle, MM_STATE_PAUSE);
|
|
mm_send_command(player->adecoder_handle, MM_COMMAND_STATE_SET,
|
|
MM_STATE_PAUSE, NULL);
|
|
wait_state(player->adecoder_handle, MM_STATE_PAUSE);
|
|
}
|
|
if (player->media_info.has_video && player->vdecoder_handle) {
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->video_render_handle) {
|
|
mm_send_command(player->video_render_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_PAUSE, NULL);
|
|
wait_state(player->video_render_handle, MM_STATE_PAUSE);
|
|
}
|
|
#endif
|
|
mm_send_command(player->vdecoder_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_PAUSE, NULL);
|
|
wait_state(player->vdecoder_handle,MM_STATE_PAUSE);
|
|
}
|
|
if (player->demuxer_handle) {
|
|
mm_send_command(player->demuxer_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_PAUSE, NULL);
|
|
wait_state(player->demuxer_handle,MM_STATE_PAUSE);
|
|
}
|
|
#ifdef _CLOCK_COMPONENT_
|
|
if (player->clock_handle) {
|
|
mm_send_command(player->clock_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_PAUSE, NULL);
|
|
wait_state(player->clock_handle, MM_STATE_PAUSE);
|
|
}
|
|
#endif
|
|
player->state = AIC_PLAYER_STATE_PAUSED;
|
|
return 0;
|
|
}
|
|
|
|
static int do_seek(struct aic_player *player,u64 seek_time)
|
|
{
|
|
mm_time_config_timestamp time_stamp;
|
|
player->seeking = 1;
|
|
time_stamp.timestamp = seek_time;
|
|
if (MM_ERROR_NONE != mm_set_config(player->demuxer_handle,
|
|
MM_INDEX_CONFIG_TIME_POSITION,
|
|
&time_stamp)) {
|
|
goto _exit;
|
|
}
|
|
|
|
player->video_audio_seek_mask = 0;
|
|
|
|
if (player->media_info.has_video) {
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->video_render_handle) {
|
|
if (MM_ERROR_NONE != mm_set_config(player->video_render_handle,
|
|
MM_INDEX_CONFIG_TIME_POSITION,
|
|
&time_stamp)) {
|
|
goto _exit;
|
|
}
|
|
}
|
|
#endif
|
|
if (player->vdecoder_handle) {
|
|
if (MM_ERROR_NONE != mm_set_config(player->vdecoder_handle,
|
|
MM_INDEX_CONFIG_TIME_POSITION,
|
|
&time_stamp)) {
|
|
goto _exit;
|
|
}
|
|
}
|
|
|
|
player->video_audio_seek_mask |= AIC_VIDEO;
|
|
player->video_audio_end_mask |= AIC_VIDEO;
|
|
|
|
}
|
|
|
|
if (player->media_info.has_audio && player->audio_render_handle
|
|
&& player->adecoder_handle) {
|
|
if (MM_ERROR_NONE != mm_set_config(player->audio_render_handle,
|
|
MM_INDEX_CONFIG_TIME_POSITION,
|
|
&time_stamp)) {
|
|
goto _exit;
|
|
}
|
|
if (MM_ERROR_NONE != mm_set_config(player->adecoder_handle,
|
|
MM_INDEX_CONFIG_TIME_POSITION,
|
|
&time_stamp)) {
|
|
goto _exit;
|
|
}
|
|
player->video_audio_seek_mask |= AIC_AUDIO;
|
|
player->video_audio_end_mask |= AIC_AUDIO;
|
|
}
|
|
|
|
if (player->media_info.has_video && player->media_info.has_audio
|
|
&& player->clock_handle) {
|
|
if (MM_ERROR_NONE != mm_set_config(player->clock_handle,
|
|
MM_INDEX_CONFIG_TIME_POSITION,
|
|
&time_stamp)) {
|
|
goto _exit;
|
|
}
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_set_config(player->demuxer_handle,
|
|
MM_INDEX_VENDOR_CLEAR_BUFFER,
|
|
&time_stamp)) {
|
|
goto _exit;
|
|
}
|
|
return 0;
|
|
|
|
_exit:
|
|
loge("seek error!\n");
|
|
player->seeking = 0;
|
|
player->video_audio_seek_mask = 0;
|
|
return -1;
|
|
|
|
}
|
|
|
|
s32 aic_player_seek(struct aic_player *player,u64 seek_time)
|
|
{
|
|
int ret = 0;
|
|
mm_time_config_timestamp time_stamp;
|
|
if (player->seeking) {
|
|
loge("palyer in seeking\n");
|
|
return -1;
|
|
}
|
|
if ((player->state == AIC_PLAYER_STATE_PREPARED) ||
|
|
(player->state == AIC_PLAYER_STATE_STARTED)) {
|
|
time_stamp.timestamp = seek_time;
|
|
// logd("time_stamp.timestamp:"FMT_d64"\n",time_stamp.timestamp);
|
|
player->seeking = 1;
|
|
if (MM_ERROR_NONE != mm_set_config(player->demuxer_handle,
|
|
MM_INDEX_CONFIG_TIME_POSITION,
|
|
&time_stamp)) {
|
|
loge("seek error!\n");
|
|
player->seeking = 0;
|
|
ret = -1;
|
|
}
|
|
} else if ((player->state == AIC_PLAYER_STATE_PLAYING) ||
|
|
(player->state == AIC_PLAYER_STATE_PLAYBACK_COMPLETED)) {
|
|
aic_player_pause(player);
|
|
ret = do_seek(player, seek_time);
|
|
if (ret != 0) {
|
|
loge("seek error!\n");
|
|
ret = -1;
|
|
} else {
|
|
aic_player_play(player);
|
|
}
|
|
} else if (player->state == AIC_PLAYER_STATE_PAUSED) {
|
|
ret = do_seek(player, seek_time);
|
|
if (ret != 0) {
|
|
loge("seek error!\n");
|
|
ret = -1;
|
|
} else {
|
|
aic_player_play(player);
|
|
}
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void aic_player_stop_component(struct aic_player *player)
|
|
{
|
|
if (player->media_info.has_video) {
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->video_render_handle) {
|
|
mm_send_command(player->video_render_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_IDLE, NULL);
|
|
wait_state(player->video_render_handle, MM_STATE_IDLE);
|
|
mm_send_command(player->video_render_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_LOADED, NULL);
|
|
wait_state(player->video_render_handle, MM_STATE_LOADED);
|
|
}
|
|
#endif
|
|
if (player->vdecoder_handle) {
|
|
mm_send_command(player->vdecoder_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_IDLE, NULL);
|
|
wait_state(player->vdecoder_handle, MM_STATE_IDLE);
|
|
mm_send_command(player->vdecoder_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_LOADED, NULL);
|
|
wait_state(player->vdecoder_handle, MM_STATE_LOADED);
|
|
}
|
|
}
|
|
|
|
if (player->media_info.has_audio) {
|
|
if (player->audio_render_handle) {
|
|
mm_send_command(player->audio_render_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_IDLE, NULL);
|
|
wait_state(player->audio_render_handle, MM_STATE_IDLE);
|
|
mm_send_command(player->audio_render_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_LOADED, NULL);
|
|
wait_state(player->audio_render_handle, MM_STATE_LOADED);
|
|
}
|
|
if (player->adecoder_handle) {
|
|
mm_send_command(player->adecoder_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_IDLE, NULL);
|
|
wait_state(player->adecoder_handle, MM_STATE_IDLE);
|
|
mm_send_command(player->adecoder_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_LOADED, NULL);
|
|
wait_state(player->adecoder_handle, MM_STATE_LOADED);
|
|
}
|
|
}
|
|
|
|
if (player->demuxer_handle) {
|
|
mm_send_command(player->demuxer_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_IDLE, NULL);
|
|
wait_state(player->demuxer_handle, MM_STATE_IDLE);
|
|
mm_send_command(player->demuxer_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_LOADED, NULL);
|
|
wait_state(player->demuxer_handle, MM_STATE_LOADED);
|
|
}
|
|
|
|
#ifdef _CLOCK_COMPONENT_
|
|
if (player->media_info.has_video && player->media_info.has_audio) {
|
|
if (player->clock_handle) {
|
|
mm_send_command(player->clock_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_IDLE, NULL);
|
|
mm_send_command(player->clock_handle,
|
|
MM_COMMAND_STATE_SET, MM_STATE_LOADED, NULL);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (player->media_info.has_video) {
|
|
if (player->demuxer_handle && player->vdecoder_handle) {
|
|
mm_set_bind(player->demuxer_handle, DEMUX_PORT_VIDEO_INDEX, NULL, 0);
|
|
mm_set_bind(NULL, 0, player->vdecoder_handle, VDEC_PORT_IN_INDEX);
|
|
mm_set_bind(player->vdecoder_handle, VDEC_PORT_OUT_INDEX, NULL, 0);
|
|
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->video_render_handle) {
|
|
mm_set_bind(NULL, 0, player->video_render_handle,
|
|
VIDEO_RENDER_PORT_IN_VIDEO_INDEX);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (player->media_info.has_audio) {
|
|
if (player->demuxer_handle && player->adecoder_handle && player->audio_render_handle) {
|
|
mm_set_bind(player->demuxer_handle, DEMUX_PORT_AUDIO_INDEX, NULL, 0);
|
|
mm_set_bind(NULL, 0, player->adecoder_handle, ADEC_PORT_IN_INDEX);
|
|
mm_set_bind(player->adecoder_handle, ADEC_PORT_OUT_INDEX, NULL, 0);
|
|
mm_set_bind(NULL, 0, player->audio_render_handle, AUDIO_RENDER_PORT_IN_AUDIO_INDEX);
|
|
}
|
|
}
|
|
|
|
#ifdef _CLOCK_COMPONENT_
|
|
if (player->media_info.has_video && player->media_info.has_audio) {
|
|
if (player->clock_handle && player->audio_render_handle && player->video_render_handle) {
|
|
mm_set_bind(player->clock_handle, CLOCK_PORT_OUT_VIDEO, NULL, 0);
|
|
mm_set_bind(NULL, 0, player->audio_render_handle, AUDIO_RENDER_PORT_IN_CLOCK_INDEX);
|
|
mm_set_bind(player->clock_handle, CLOCK_PORT_OUT_AUDIO, NULL, 0);
|
|
mm_set_bind(NULL, 0, player->video_render_handle, VIDEO_RENDER_PORT_IN_CLOCK_INDEX);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
s32 aic_player_stop(struct aic_player *player)
|
|
{
|
|
if (player->state == AIC_PLAYER_STATE_STOPPED) {
|
|
return 0;
|
|
}
|
|
|
|
if (player->sync_flag == AIC_PLAYER_PREPARE_ASYNC) {
|
|
if (player->threadId != 0) {
|
|
if (player->thread_runing == 1) {
|
|
pthread_cancel(player->threadId);
|
|
}
|
|
pthread_join(player->threadId, NULL);
|
|
player->threadId = 0;
|
|
}
|
|
}
|
|
|
|
aic_player_stop_component(player);
|
|
|
|
player->video_audio_end_mask = 0;
|
|
|
|
if (player->media_info.has_video) {
|
|
#ifndef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
if (player->video_render_handle) {
|
|
mm_param_u32 params;
|
|
params.u32 = (u32)player->video_render_keep_last_frame;
|
|
if (MM_ERROR_NONE != mm_set_parameter(player->video_render_handle,
|
|
MM_INDEX_VENDOR_VIDEO_RENDER_KEEP_LAST_FRAME,
|
|
¶ms)) {
|
|
loge("set video render keep last frame failed.\n");
|
|
}
|
|
|
|
mm_free_handle(player->video_render_handle);
|
|
player->video_render_handle = NULL;
|
|
}
|
|
#endif
|
|
if (player->vdecoder_handle) {
|
|
mm_free_handle(player->vdecoder_handle);
|
|
player->vdecoder_handle = NULL;
|
|
}
|
|
}
|
|
|
|
if (player->media_info.has_audio) {
|
|
if (player->audio_render_handle) {
|
|
mm_free_handle(player->audio_render_handle);
|
|
player->audio_render_handle = NULL;
|
|
}
|
|
if (player->adecoder_handle) {
|
|
mm_free_handle(player->adecoder_handle);
|
|
player->adecoder_handle = NULL;
|
|
}
|
|
}
|
|
|
|
#ifdef _CLOCK_COMPONENT_
|
|
if (player->media_info.has_video && player->media_info.has_audio) {
|
|
if (player->clock_handle) {
|
|
mm_free_handle(player->clock_handle);
|
|
player->clock_handle = NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
memset(&player->media_info, 0x00, sizeof(struct aic_parser_av_media_info));
|
|
player->state = AIC_PLAYER_STATE_STOPPED;
|
|
player->seeking = 0;
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_destroy(struct aic_player *player)
|
|
{
|
|
if (player->state != AIC_PLAYER_STATE_STOPPED) {
|
|
aic_player_stop(player);
|
|
}
|
|
|
|
if (player->demuxer_handle) {
|
|
mm_free_handle(player->demuxer_handle);
|
|
player->demuxer_handle = NULL;
|
|
}
|
|
|
|
if (player->uri_param) {
|
|
mpp_free(player->uri_param);
|
|
player->uri_param = NULL;
|
|
}
|
|
|
|
mpp_free(player);
|
|
|
|
mm_deinit();
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_set_event_callback(struct aic_player *player,
|
|
void *app_data, event_handler event_handle)
|
|
{
|
|
player->event_handle = event_handle;
|
|
player->app_data = app_data;
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_get_media_info(struct aic_player *player,struct av_media_info *media_info)
|
|
{
|
|
if (media_info == NULL) {
|
|
return -1;
|
|
}
|
|
if ((!player->media_info.has_video) && (!player->media_info.has_audio)) {
|
|
return -1;
|
|
}
|
|
media_info->duration = player->media_info.duration;
|
|
media_info->file_size = player->media_info.file_size;
|
|
media_info->has_video = player->media_info.has_video;
|
|
media_info->has_audio = player->media_info.has_audio;
|
|
if (media_info->has_video) {
|
|
media_info->video_stream.width = player->media_info.video_stream.width;
|
|
media_info->video_stream.height = player->media_info.video_stream.height;
|
|
}
|
|
if (media_info->has_audio) {
|
|
media_info->audio_stream.bits_per_sample = player->media_info.audio_stream.bits_per_sample;
|
|
media_info->audio_stream.nb_channel = player->media_info.audio_stream.nb_channel;
|
|
media_info->audio_stream.sample_rate = player->media_info.audio_stream.sample_rate;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_get_screen_size(struct aic_player *player,struct mpp_size *screen_size)
|
|
{
|
|
mm_param_screen_size rect = {0};
|
|
|
|
if (!player->media_info.has_video || !player->video_render_handle) {
|
|
loge("no video!!!!\n");
|
|
return -1;
|
|
}
|
|
|
|
mm_get_parameter(player->video_render_handle, MM_INDEX_VENDOR_VIDEO_RENDER_SCREEN_SIZE, &rect);
|
|
screen_size->width = rect.width;
|
|
screen_size->height = rect.height;
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_set_disp_rect(struct aic_player *player,struct mpp_rect *disp_rect)
|
|
{
|
|
mm_config_rect rect = {0};
|
|
|
|
player->disp_rect = *disp_rect;
|
|
if (!player->media_info.has_video || !player->video_render_handle) {
|
|
return 0;
|
|
}
|
|
rect.left = disp_rect->x;
|
|
rect.top = disp_rect->y;
|
|
rect.width = disp_rect->width;
|
|
rect.height = disp_rect->height;
|
|
mm_set_parameter(player->video_render_handle, MM_INDEX_CONFIG_COMMON_OUTPUT_CROP, &rect);
|
|
return 0;
|
|
}
|
|
|
|
|
|
s32 aic_player_get_disp_rect(struct aic_player *player,struct mpp_rect *disp_rect)
|
|
{
|
|
mm_config_rect rect;
|
|
|
|
if (!player->media_info.has_video || !player->video_render_handle) {
|
|
loge("no video!!!!\n");
|
|
return -1;
|
|
}
|
|
mm_get_parameter(player->video_render_handle, MM_INDEX_CONFIG_COMMON_OUTPUT_CROP, &rect);
|
|
disp_rect->x = rect.left;
|
|
disp_rect->y = rect.top;
|
|
disp_rect->width = rect.width;
|
|
disp_rect->height = rect.height;
|
|
player->disp_rect = *disp_rect;
|
|
return 0;
|
|
}
|
|
|
|
|
|
s64 aic_player_get_play_time(struct aic_player *player)
|
|
{
|
|
//to do
|
|
if (player->media_info.has_audio) {
|
|
return player->audio_pts;
|
|
} else if (player->media_info.has_video) {
|
|
return player->video_pts;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
s32 aic_player_set_mute(struct aic_player *player)
|
|
{
|
|
mm_param_audio_volume volume;
|
|
if (!player->media_info.has_audio || !player->audio_render_handle) {
|
|
return -1;
|
|
}
|
|
if (player->mute) {
|
|
volume.volume = player->volume;
|
|
player->mute = 0;
|
|
} else {
|
|
player->mute = 1;
|
|
volume.volume = 0;
|
|
}
|
|
mm_set_parameter(player->audio_render_handle, MM_INDEX_VENDOR_AUDIO_RENDER_VOLUME, &volume);
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_set_volum(struct aic_player *player,s32 vol)
|
|
{
|
|
mm_param_audio_volume volume;
|
|
player->volume = vol;
|
|
if (!player->media_info.has_audio || !player->audio_render_handle) {
|
|
return 0;
|
|
}
|
|
volume.volume = vol;
|
|
mm_set_parameter(player->audio_render_handle, MM_INDEX_VENDOR_AUDIO_RENDER_VOLUME, &volume);
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_get_volum(struct aic_player *player,s32 *vol)
|
|
{
|
|
mm_param_audio_volume volume = {0};
|
|
if (!player->media_info.has_audio || !player->audio_render_handle || !vol) {
|
|
return -1;
|
|
}
|
|
|
|
mm_get_parameter(player->audio_render_handle, MM_INDEX_VENDOR_AUDIO_RENDER_VOLUME, &volume);
|
|
*vol = volume.volume;
|
|
player->volume = volume.volume;
|
|
return 0;
|
|
}
|
|
|
|
|
|
s32 aic_player_capture(struct aic_player *player, struct aic_capture_info *capture_info)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_set_rotation(struct aic_player *player, int rotation_angle)
|
|
{
|
|
mm_config_rotation rotation;
|
|
|
|
if (rotation_angle != MPP_ROTATION_0
|
|
&& rotation_angle != MPP_ROTATION_90
|
|
&& rotation_angle != MPP_ROTATION_180
|
|
&& rotation_angle != MPP_ROTATION_270) {
|
|
loge("param error!!!!\n");
|
|
return -1;
|
|
}
|
|
player->rotation_angle = rotation_angle;
|
|
if (!player->media_info.has_video) {
|
|
return 0;
|
|
}
|
|
|
|
rotation.rotation = rotation_angle;
|
|
if (0 == strcmp(PRJ_CHIP, "d13x")) {
|
|
if(!player->vdecoder_handle) {
|
|
loge("no vdecoder_handle!!!!\n");
|
|
return -1;
|
|
}
|
|
if (MM_ERROR_NONE != mm_set_config(player->vdecoder_handle,
|
|
MM_INDEX_CONFIG_COMMON_ROTATE,
|
|
&rotation)) {
|
|
loge("set vdecoder rotate failed!!!!\n");
|
|
return -1;
|
|
}
|
|
}
|
|
if(player->video_render_handle) {
|
|
if (MM_ERROR_NONE != mm_set_config(player->video_render_handle,
|
|
MM_INDEX_CONFIG_COMMON_ROTATE,
|
|
&rotation)) {
|
|
loge("set video render rotate failed!!!!\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 aic_player_get_rotation(struct aic_player *player)
|
|
{
|
|
mm_config_rotation rotation = {0};
|
|
if (!player->media_info.has_video || !player->video_render_handle) {
|
|
loge("no video!!!!\n");
|
|
return -1;
|
|
}
|
|
|
|
if (MM_ERROR_NONE != mm_get_config(player->video_render_handle,
|
|
MM_INDEX_CONFIG_COMMON_ROTATE, &rotation)) {
|
|
loge("no video!!!!\n");
|
|
return -1;
|
|
}
|
|
player->rotation_angle = rotation.rotation;
|
|
return rotation.rotation;
|
|
}
|
|
|
|
s32 aic_player_control(struct aic_player *player, enum aic_player_command cmd, void *data)
|
|
{
|
|
s32 ret = 0;
|
|
switch (cmd) {
|
|
case AIC_PLAYER_CMD_GET_VDEC_DECODER_FRAME: {
|
|
mm_buffer buffer = {0};
|
|
buffer.p_buffer = data;
|
|
buffer.data_type = MM_BUFFER_DATA_FRAME;
|
|
if (!player->vdecoder_handle) {
|
|
return -1;
|
|
}
|
|
ret = mm_get_buffer(player->vdecoder_handle, &buffer);
|
|
break;
|
|
}
|
|
|
|
case AIC_PLAYER_CMD_PUT_VDEC_DECODER_FRAME: {
|
|
mm_buffer buffer = {0};
|
|
buffer.p_buffer = data;
|
|
buffer.data_type = MM_BUFFER_DATA_FRAME;
|
|
if (!player->vdecoder_handle) {
|
|
return -1;
|
|
}
|
|
ret = mm_giveback_buffer(player->vdecoder_handle, &buffer);
|
|
break;
|
|
}
|
|
|
|
#ifdef AIC_MPP_PLAYER_VE_USE_FILL_FB
|
|
case AIC_PLAYER_CMD_SET_VDEC_EXT_FRAME_ALLOCATOR:
|
|
player->vdec_allocator = data;
|
|
break;
|
|
|
|
case AIC_PLAYER_CMD_SET_VDEC_SET_CROP_INFO:
|
|
if (!player->vdecoder_handle) {
|
|
memcpy(&player->vdec_crop, data, sizeof(struct mpp_dec_crop_info));
|
|
player->init_vdec_crop = 1;
|
|
return 0;
|
|
}
|
|
ret = mm_set_config(player->vdecoder_handle,
|
|
MM_INDEX_CONFIG_VIDEO_DECODER_CROP_INFO, data);
|
|
break;
|
|
#endif
|
|
case AIC_PLAYER_CMD_SET_VIDEO_RENDER_KEEP_LAST_FRAME: {
|
|
if (!data) {
|
|
loge("video render set last frame data is null\n");
|
|
return -1;
|
|
}
|
|
player->video_render_keep_last_frame = *(s8 *)data;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|