static s32 vdecoder_close(cedarv_decoder_t* p) { video_decoder_t* decoder; if(p == NULL) return CEDARV_RESULT_ERR_INVALID_PARAM; decoder = (video_decoder_t*)p; libve_reset(0, decoder->ve); if(decoder->stream_info.init_data != NULL) { mem_free(decoder->stream_info.init_data); decoder->stream_info.init_data = NULL; } if(decoder->ve != NULL) { libve_close(0, decoder->ve); decoder->ve = NULL; decoder->fbm = NULL; } if(decoder->vbv != NULL) { vbv_release(decoder->vbv); decoder->vbv = NULL; } return CEDARV_RESULT_OK; }
cedarx_result_e libcedarx_decoder_decode_stream(int force) { vresult_e res; cedarx_result_e result; cedarx_decoder_t* decoder = cedarx_decoder; if ((!decoder) || (!decoder->ve) || (!decoder->vbv)) return CEDARX_RESULT_NO_INIT; if (!force) { if (vbv_check_stream_frame(decoder->vbv) < 0) return CEDARX_RESULT_VBV_BUFFER_EMPTY; } res = libve_decode(0, 0, 0, decoder->ve); switch (res) { case VRESULT_OK: case VRESULT_FRAME_DECODED: case VRESULT_KEYFRAME_DECODED: result = CEDARX_RESULT_OK; break; case VRESULT_NO_FRAME_BUFFER: printf("Warning: There are not more framebuffer!\n"); result = CEDARX_RESULT_NO_FRAME_BUFFER; break; case VRESULT_NO_BITSTREAM: printf("Warning: There are not more bitstream!\n"); result = CEDARX_RESULT_VBV_BUFFER_EMPTY; break; default: printf("Error: Decode failed(%d), try to reset decoder!\n", res); libve_reset(0, decoder->ve); return CEDARX_RESULT_VE_FAILED; } return result; }
static s32 vdecoder_io_ctrl(cedarv_decoder_t* p, u32 cmd, u32 param) { video_decoder_t* decoder; if(p == NULL) return CEDARV_RESULT_ERR_INVALID_PARAM; decoder = (video_decoder_t*)p; if(p == NULL) return CEDARV_RESULT_ERR_INVALID_PARAM; switch(cmd) { case CEDARV_COMMAND_PLAY: { if(decoder->status != CEDARV_STATUS_PLAY && decoder->status != CEDARV_STATUS_STOP) decoder->mode_switched = 1; decoder->status = CEDARV_STATUS_PLAY; return CEDARV_RESULT_OK; } case CEDARV_COMMAND_FORWARD: { if(decoder->status != CEDARV_STATUS_PLAY) return CEDARV_RESULT_ERR_FAIL; decoder->status = CEDARV_STATUS_FORWARD; decoder->mode_switched = 1; return CEDARV_RESULT_OK; } case CEDARV_COMMAND_BACKWARD: { if(decoder->status != CEDARV_STATUS_PLAY) return CEDARV_RESULT_ERR_FAIL; decoder->status = CEDARV_STATUS_BACKWARD; decoder->mode_switched = 1; return CEDARV_RESULT_OK; } case CEDARV_COMMAND_STOP: { if(decoder->status != CEDARV_STATUS_PLAY && decoder->status != CEDARV_STATUS_FORWARD && decoder->status != CEDARV_STATUS_BACKWARD) return CEDARV_RESULT_ERR_FAIL; decoder->status = CEDARV_STATUS_STOP; decoder->mode_switched = 1; return CEDARV_RESULT_OK; } case CEDARV_COMMAND_ROTATE: { if(param > 5) return CEDARV_RESULT_ERR_FAIL; decoder->config_info.rotate_angle = param; if(param != 0) decoder->config_info.rotate_enable = 1; return CEDARV_RESULT_OK; } case CEDARV_COMMAND_JUMP: { libve_reset(0, decoder->ve); vbv_reset(decoder->vbv); if(p->free_vbs_buffer_sem != NULL) p->free_vbs_buffer_sem(p->cedarx_cookie); if(decoder->fbm != NULL) { if(decoder->display_already_begin) fbm_reset(decoder->last_frame_index, decoder->fbm); else fbm_reset(0xff, decoder->fbm); if(p->release_frame_buffer_sem != NULL) p->release_frame_buffer_sem(p->cedarx_cookie); } return CEDARV_RESULT_OK; } // case VDEC_QUERY_VBSBUFFER_USAGE_CMD: // { // s32 usage1, usage2; // // if(p->vbv != NULL && vbv_get_buffer_size(p->vbv) != 0) // { // usage1 = vbv_get_valid_data_size(p->vbv) * 100 / vbv_get_buffer_size(p->vbv); // usage2 = vbv_get_valid_frame_num(p->vbv) * 100 / vbv_get_max_stream_frame_num(p->vbv); // // return (usage1 > usage2) ? usage1 : usage2; // } // // return 0; // } case CEDARV_COMMAND_SET_TOTALMEMSIZE: { decoder->remainMemorySize = param; return CEDARV_RESULT_OK; } case CEDARV_COMMAND_PREVIEW_MODE: { decoder->status = CEDARV_STATUS_PREVIEW; return CEDARV_RESULT_OK; } default: return CEDARV_RESULT_ERR_FAIL; } }
static s32 vdecoder_decode(cedarv_decoder_t* p) { vresult_e vresult; #if (DECODE_FREE_RUN == 0) u64 video_time; #endif video_decoder_t* decoder; if(p == NULL) return CEDARV_RESULT_ERR_INVALID_PARAM; decoder = (video_decoder_t*)p; if(decoder->mode_switched) { libve_reset(0, decoder->ve); vbv_reset(decoder->vbv); if(p->free_vbs_buffer_sem != NULL) p->free_vbs_buffer_sem(p->cedarx_cookie); if(decoder->fbm != NULL) { fbm_flush(decoder->fbm); if(p->release_frame_buffer_sem != NULL) p->release_frame_buffer_sem(p->cedarx_cookie); } decoder->mode_switched = 0; return CEDARV_RESULT_NO_BITSTREAM; } if(decoder->status == CEDARV_STATUS_BACKWARD || decoder->status == CEDARV_STATUS_FORWARD) { vresult = libve_decode(1, 0, 0, decoder->ve); } else { if(decoder->stream_info.format == STREAM_FORMAT_H264 && decoder->display_already_begin == 0) { //* for H264, when decoding the first data unit containing PPS, we have to promise //* there is more than one bitstream frame for decoding. //* that is because the decoder uses the start code of the second bitstream frame //* to judge PPS end. if(vbv_get_stream_num(decoder->vbv) < 2) return CEDARV_RESULT_NO_BITSTREAM; } if(decoder->status == CEDARV_STATUS_PREVIEW) { vresult = libve_decode(1, 0, 0, decoder->ve); } else { #if (DECODE_FREE_RUN == 0) video_time = esMODS_MIoctrl(vdrv_com->avsync, DRV_AVS_CMD_GET_VID_TIME, DRV_AVS_TIME_TOTAL, 0); video_time *= 1000; vresult = libve_decode(0, 1, video_time, decoder->ve); #else vresult = libve_decode(0, 0, 0, decoder->ve); #endif } } if(vresult == VRESULT_OK) { return CEDARV_RESULT_OK; } else if(vresult == VRESULT_FRAME_DECODED) { return CEDARV_RESULT_FRAME_DECODED; } else if(vresult == VRESULT_KEYFRAME_DECODED) { if(decoder->status == CEDARV_STATUS_BACKWARD || decoder->status == CEDARV_STATUS_FORWARD || decoder->status == CEDARV_STATUS_PREVIEW) { libve_reset(1, decoder->ve); } return CEDARV_RESULT_KEYFRAME_DECODED; } else if(vresult == VRESULT_NO_FRAME_BUFFER) { return CEDARV_RESULT_NO_FRAME_BUFFER; } else if(vresult == VRESULT_NO_BITSTREAM) { return CEDARV_RESULT_NO_BITSTREAM; } else if(vresult == VRESULT_ERR_NO_MEMORY) { return CEDARV_RESULT_ERR_NO_MEMORY; } else if( vresult == VRESULT_ERR_UNSUPPORTED) { return CEDARV_RESULT_ERR_UNSUPPORTED; } else if(vresult == VRESULT_ERR_LIBRARY_NOT_OPEN) { return CEDARV_RESULT_ERR_FAIL; } else { return CEDARV_RESULT_OK; } }
cedarx_result_e libcedarx_decoder_open(cedarx_info_t* info) { cedarx_result_e result; vconfig_t config; vstream_info_t stream_info; cedarx_decoder_t* decoder; if (!info) return CEDARX_RESULT_INVALID_ARGS; if ((info->width > MAX_SUPPORTED_VIDEO_WIDTH) || \ (info->height > MAX_SUPPORTED_VIDEO_HEIGHT)) return CEDARX_RESULT_INVALID_ARGS; decoder = (cedarx_decoder_t*)mem_alloc(sizeof(cedarx_decoder_t)); if (!decoder) return CEDARX_RESULT_NO_ENOUGH_MEMORY; mem_set(decoder, 0, sizeof(cedarx_decoder_t)); cedarx_decoder = decoder; result = ve_init(); if (CEDARX_RESULT_OK != result) goto failed3; mem_set(&config, 0, sizeof(vconfig_t)); mem_set(&stream_info, 0, sizeof(vstream_info_t)); config.max_video_width = MAX_SUPPORTED_VIDEO_WIDTH; config.max_video_height = MAX_SUPPORTED_VIDEO_HEIGHT; config.max_output_width = MAX_SUPPORTED_OUTPUT_WIDTH; config.max_output_height = MAX_SUPPORTED_OUTPUT_HEIGHT; switch (info->stream) { case CEDARX_STREAM_FORMAT_MPEG1: stream_info.format = STREAM_FORMAT_MPEG2; stream_info.sub_format = MPEG2_SUB_FORMAT_MPEG1; break; case CEDARX_STREAM_FORMAT_MPEG2: stream_info.format = STREAM_FORMAT_MPEG2; stream_info.sub_format = MPEG2_SUB_FORMAT_MPEG2; break; case CEDARX_STREAM_FORMAT_XVID: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_XVID; break; case CEDARX_STREAM_FORMAT_DIVX1: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_DIVX1; break; case CEDARX_STREAM_FORMAT_DIVX2: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_DIVX2; break; case CEDARX_STREAM_FORMAT_DIVX3: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_DIVX3; break; case CEDARX_STREAM_FORMAT_DIVX4: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_DIVX4; break; case CEDARX_STREAM_FORMAT_DIVX5: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_DIVX5; break; case CEDARX_STREAM_FORMAT_H263: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_H263; break; case CEDARX_STREAM_FORMAT_SORENSSON_H263: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_SORENSSON_H263; break; case CEDARX_STREAM_FORMAT_WMV1: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_WMV1; break; case CEDARX_STREAM_FORMAT_WMV2: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_WMV2; break; case CEDARX_STREAM_FORMAT_VP6: stream_info.format = STREAM_FORMAT_MPEG4; stream_info.sub_format = MPEG4_SUB_FORMAT_VP6; break; case CEDARX_STREAM_FORMAT_REALVIDEO: stream_info.format = STREAM_FORMAT_REALVIDEO; stream_info.sub_format = STREAM_SUB_FORMAT_UNKNOW; break; case CEDARX_STREAM_FORMAT_H264: stream_info.format = STREAM_FORMAT_H264; stream_info.sub_format = STREAM_SUB_FORMAT_UNKNOW; stream_info.is_pts_correct = 1; decoder->greedy = 1; break; case CEDARX_STREAM_FORMAT_VC1: stream_info.format = STREAM_FORMAT_VC1; stream_info.sub_format = STREAM_SUB_FORMAT_UNKNOW; break; case CEDARX_STREAM_FORMAT_AVS: stream_info.format = STREAM_FORMAT_AVS; stream_info.sub_format = STREAM_SUB_FORMAT_UNKNOW; break; case CEDARX_STREAM_FORMAT_MJPEG: stream_info.format = STREAM_FORMAT_MJPEG; stream_info.sub_format = STREAM_SUB_FORMAT_UNKNOW; break; case CEDARX_STREAM_FORMAT_VP8: stream_info.format = STREAM_FORMAT_VP8; stream_info.sub_format = STREAM_SUB_FORMAT_UNKNOW; break; default: result = CEDARX_RESULT_INVALID_ARGS; goto failed2; } switch (info->container) { case CEDARX_CONTAINER_FORMAT_AVI: stream_info.container_format = CONTAINER_FORMAT_AVI; break; case CEDARX_CONTAINER_FORMAT_ASF: stream_info.container_format = CONTAINER_FORMAT_ASF; break; case CEDARX_CONTAINER_FORMAT_DAT: stream_info.container_format = CONTAINER_FORMAT_DAT; break; case CEDARX_CONTAINER_FORMAT_FLV: stream_info.container_format = CONTAINER_FORMAT_FLV; break; case CEDARX_CONTAINER_FORMAT_MKV: stream_info.container_format = CONTAINER_FORMAT_MKV; break; case CEDARX_CONTAINER_FORMAT_MOV: stream_info.container_format = CONTAINER_FORMAT_MOV; break; case CEDARX_CONTAINER_FORMAT_MPG: stream_info.container_format = CONTAINER_FORMAT_MPG; break; case CEDARX_CONTAINER_FORMAT_PMP: stream_info.container_format = CONTAINER_FORMAT_PMP; break; case CEDARX_CONTAINER_FORMAT_RM: stream_info.container_format = CONTAINER_FORMAT_RM; break; case CEDARX_CONTAINER_FORMAT_TS: stream_info.container_format = CONTAINER_FORMAT_TS; stream_info.is_pts_correct = 1; break; case CEDARX_CONTAINER_FORMAT_VOB: stream_info.container_format = CONTAINER_FORMAT_VOB; break; case CEDARX_CONTAINER_FORMAT_WEBM: stream_info.container_format = CONTAINER_FORMAT_WEBM; break; case CEDARX_CONTAINER_FORMAT_OGM: stream_info.container_format = CONTAINER_FORMAT_OGM; break; default: stream_info.container_format = CONTAINER_FORMAT_UNKNOW; break; } stream_info.video_width = info->width; stream_info.video_height = info->height; stream_info.frame_rate = info->frame_rate; stream_info.frame_duration = info->frame_duration; stream_info.aspec_ratio = 1000; if (info->data && (info->data_size > 0)) { decoder->init_data = mem_alloc(info->data_size); if (!decoder->init_data) { result = CEDARX_RESULT_NO_ENOUGH_MEMORY; goto failed2; } mem_cpy(decoder->init_data, info->data, info->data_size); stream_info.init_data = decoder->init_data; stream_info.init_data_len = info->data_size; } else { stream_info.init_data_len = 0; stream_info.init_data = NULL; } stream_info._3d_mode = _3D_MODE_NONE; mem_init(decoder->fd); ve_request(); if (info->request_buffer) decoder->request_buffer = info->request_buffer; if (info->update_buffer) decoder->update_buffer = info->update_buffer; if (info->release_buffer) decoder->release_buffer = info->release_buffer; if (info->lock_buffer) decoder->lock_buffer = info->lock_buffer; if (info->unlock_buffer) decoder->unlock_buffer = info->unlock_buffer; decoder->sys = info->sys; decoder->ve = libve_open(&config, &stream_info, decoder); if (!decoder->ve) { result = CEDARX_RESULT_VE_FAILED; goto failed1; } libve_reset(0, decoder->ve); decoder->vbv = vbv_init(); if (!decoder->vbv) { result = CEDARX_RESULT_NO_ENOUGH_MEMORY; goto failed0; } libve_set_vbv(decoder->vbv, decoder->ve); return CEDARX_RESULT_OK; failed0: libve_close(0, decoder->ve); failed1: ve_release(); mem_exit(); if (decoder->init_data) mem_free(decoder->init_data); failed2: ve_exit(); failed3: mem_free(decoder); cedarx_decoder = NULL; return result; }