forked from langhuihui/jessibuca
/
libhevc.h
124 lines (121 loc) · 6.11 KB
/
libhevc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#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 decodeH265Header(IOBuffer &data) 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[22];
lengthSizeMinusOne &= 0x03;
NAL_unit_length = lengthSizeMinusOne;
data >>= 26;
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)
//emscripten_log(0, "vps %d", s_video_decode_op.u4_num_bytes_consumed);
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)
//emscripten_log(0, "sps %d", s_video_decode_op.u4_num_bytes_consumed);
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)
//emscripten_log(0, "pps %d", s_video_decode_op.u4_num_bytes_consumed);
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(IOBuffer data) override
{
s_video_decode_ip.pv_stream_buffer = (void *)data.point();
s_video_decode_ip.u4_num_Bytes = data.length;
do
{
ret = ihevcd_cxa_api_function(codec_obj, &s_video_decode_ip, &s_video_decode_op);
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;
if (ret == IV_SUCCESS)
decodeYUV420();
} while (s_video_decode_ip.u4_num_Bytes);
}
};