You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
5.9 KiB
121 lines
5.9 KiB
#pragma once
|
|
#include "ihevc_typedefs.h"
|
|
#include "iv.h"
|
|
#include "ivd.h"
|
|
#include "ihevcd_cxa.h"
|
|
#define STRIDE 0
|
|
#define EXECUTE(ip, op, ...) \
|
|
if (IV_SUCCESS != (ret = ihevcd_cxa_api_function(codec_obj, ip, op))) \
|
|
printf(__VA_ARGS__);
|
|
void *ihevca_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
|
|
{
|
|
(void)pv_ctxt;
|
|
return malloc(i4_size);
|
|
}
|
|
|
|
void ihevca_aligned_free(void *pv_ctxt, void *pv_buf)
|
|
{
|
|
(void)pv_ctxt;
|
|
free(pv_buf);
|
|
return;
|
|
}
|
|
#define CALL_API(name, errorStr, ...) \
|
|
{ \
|
|
name##_ip_t ip = { \
|
|
sizeof(name##_ip_t), __VA_ARGS__}; \
|
|
name##_op_t op = {sizeof(name##_op_t)}; \
|
|
EXECUTE(&ip, &op, errorStr) \
|
|
}
|
|
#define VIDEO_CTL(name, subcmd, errorStr, ...) CALL_API(ihevcd_cxa_ctl_##name, errorStr, IVD_CMD_VIDEO_CTL, (IVD_CONTROL_API_COMMAND_TYPE_T)subcmd, __VA_ARGS__)
|
|
class Libhevc : public VideoDecoder
|
|
{
|
|
public:
|
|
iv_obj_t *codec_obj = NULL;
|
|
CHAR ac_error_str[1000];
|
|
// ivd_out_bufdesc_t ps_out_buf;
|
|
UWORD32 u4_num_bytes_dec = 0;
|
|
UWORD32 u4_ip_frm_ts = 0, u4_op_frm_ts = 0;
|
|
WORD32 ret;
|
|
UWORD32 u4_ip_buf_len;
|
|
UWORD32 frm_cnt = 0;
|
|
ivd_video_decode_ip_t s_video_decode_ip;
|
|
ivd_video_decode_op_t s_video_decode_op;
|
|
Libhevc()
|
|
{
|
|
ihevcd_cxa_create_ip_t s_create_ip;
|
|
ihevcd_cxa_create_op_t s_create_op;
|
|
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
|
|
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
|
|
s_create_ip.s_ivd_create_ip_t.e_output_format = IV_YUV_420P;
|
|
s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ihevca_aligned_malloc;
|
|
s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ihevca_aligned_free;
|
|
s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
|
|
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ihevcd_cxa_create_ip_t);
|
|
s_create_op.s_ivd_create_op_t.u4_size = sizeof(ihevcd_cxa_create_op_t);
|
|
EXECUTE(&s_create_ip, &s_create_op, "Error in Create %8x\n",
|
|
s_create_op.s_ivd_create_op_t.u4_error_code)
|
|
codec_obj = (iv_obj_t *)s_create_op.s_ivd_create_op_t.pv_handle;
|
|
codec_obj->pv_fxns = (void *)&ihevcd_cxa_api_function;
|
|
codec_obj->u4_size = sizeof(iv_obj_t);
|
|
VIDEO_CTL(set_num_cores, IHEVCD_CXA_CMD_CTL_SET_NUM_CORES, "\nError in setting number of cores", 1)
|
|
VIDEO_CTL(set_processor, IHEVCD_CXA_CMD_CTL_SET_PROCESSOR, "\nError in setting Processor type", ARCH_NA, SOC_NA)
|
|
|
|
emscripten_log(0, "libhevc init");
|
|
}
|
|
~Libhevc()
|
|
{
|
|
CALL_API(ivd_delete, "Error in Codec delete", IVD_CMD_DELETE)
|
|
free((void *)p_yuv[0]);
|
|
}
|
|
|
|
void decodeHeader(MemoryStream &data, int codec_id) override
|
|
{
|
|
CALL_API(ivd_ctl_set_config, "\nError in setting the codec in header decode mode", IVD_CMD_VIDEO_CTL, IVD_CMD_CTL_SETPARAMS, IVD_DECODE_HEADER, STRIDE, IVD_SKIP_NONE, IVD_DISPLAY_FRAME_OUT)
|
|
s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
|
|
s_video_decode_ip.u4_ts = u4_ip_frm_ts;
|
|
s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
|
|
s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
|
|
u8 lengthSizeMinusOne = data[27];
|
|
lengthSizeMinusOne &= 0x03;
|
|
NAL_unit_length = lengthSizeMinusOne;
|
|
data >>= 31;
|
|
int vps = 0, sps = 0, pps = 0;
|
|
data.read2B(vps);
|
|
s_video_decode_ip.pv_stream_buffer = (void *)data.point();
|
|
s_video_decode_ip.u4_num_Bytes = vps;
|
|
EXECUTE(&s_video_decode_ip, &s_video_decode_op, "\nError in header vps decode %x", s_video_decode_op.u4_error_code)
|
|
data >>= vps;
|
|
data >>= 3;
|
|
data.read2B(sps);
|
|
s_video_decode_ip.pv_stream_buffer = (void *)data.point();
|
|
s_video_decode_ip.u4_num_Bytes = sps;
|
|
EXECUTE(&s_video_decode_ip, &s_video_decode_op, "\nError in header sps decode %x", s_video_decode_op.u4_error_code)
|
|
data >>= sps;
|
|
data >>= 3;
|
|
data.read2B(pps);
|
|
s_video_decode_ip.pv_stream_buffer = (void *)data.point();
|
|
s_video_decode_ip.u4_num_Bytes = pps;
|
|
EXECUTE(&s_video_decode_ip, &s_video_decode_op, "\nError in header pps decode %x", s_video_decode_op.u4_error_code)
|
|
decodeVideoSize(s_video_decode_op.u4_pic_wd, s_video_decode_op.u4_pic_ht);
|
|
CALL_API(ivd_ctl_set_config, "\nError in setting the codec in frame decode mode", IVD_CMD_VIDEO_CTL, IVD_CMD_CTL_SETPARAMS, IVD_DECODE_FRAME, STRIDE, IVD_SKIP_NONE, IVD_DISPLAY_FRAME_OUT)
|
|
s_video_decode_ip.s_out_buffer.u4_num_bufs = 3;
|
|
s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = videoWidth * videoHeight;
|
|
s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] >> 2;
|
|
p_yuv[0] = (u32)(s_video_decode_ip.s_out_buffer.pu1_bufs[0] = (UWORD8 *)malloc(6 * s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1]));
|
|
p_yuv[1] = (u32)(s_video_decode_ip.s_out_buffer.pu1_bufs[1] = (UWORD8 *)p_yuv[0] + s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0]);
|
|
p_yuv[2] = (u32)(s_video_decode_ip.s_out_buffer.pu1_bufs[2] = (UWORD8 *)p_yuv[1] + s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1]);
|
|
}
|
|
void _decode(const char *data, int len) override
|
|
{
|
|
s_video_decode_ip.pv_stream_buffer = (void *)data;
|
|
s_video_decode_ip.u4_num_Bytes = len;
|
|
do
|
|
{
|
|
EXECUTE(&s_video_decode_ip, &s_video_decode_op, "Error in video Frame decode : ret %x Error %x\n", ret,
|
|
s_video_decode_op.u4_error_code);
|
|
s_video_decode_ip.u4_num_Bytes -= s_video_decode_op.u4_num_bytes_consumed;
|
|
s_video_decode_ip.pv_stream_buffer = (UWORD8 *)s_video_decode_ip.pv_stream_buffer + s_video_decode_op.u4_num_bytes_consumed;
|
|
decodeYUV420();
|
|
} while (s_video_decode_ip.u4_num_Bytes);
|
|
}
|
|
};
|