diff --git a/hardware/board/halley5/include/x2000_hal_conf.h b/hardware/board/halley5/include/x2000_hal_conf.h index a9f721f6f675e6cb5c75a996e0f6b5de5e3992f0..879954bc038e8a06d75c5c5095267b22455b09e2 100644 --- a/hardware/board/halley5/include/x2000_hal_conf.h +++ b/hardware/board/halley5/include/x2000_hal_conf.h @@ -74,6 +74,10 @@ #define HAL_MIPI_DSI_ENABLE #endif +#if CONFIG_FELIX_ENABLE +#define HAL_FELIX_ENABLE +#endif + /* 系统时钟配配置,通过工具生成,随开发板或者平台变化.*/ #include @@ -86,7 +90,7 @@ #include "x2000_hal_pdma.h" #ifdef HAL_NOR_FLASH_ENABLED -#include "x2000_hal_sfcnor.h" +#include "x2000_hal_sfc.h" #endif #ifdef HAL_MSC_ENABLED @@ -153,6 +157,10 @@ #include "x2000_ll_mipi_dsi.h" #endif +#ifdef HAL_FELIX_ENABLE +#include "x2000_hal_felix.h" +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/hardware/chip/x2000/example/vcodec/bs.h b/hardware/chip/x2000/example/vcodec/bs.h new file mode 100644 index 0000000000000000000000000000000000000000..45e46314349c7ac06a2638d07118ce40183bbf54 --- /dev/null +++ b/hardware/chip/x2000/example/vcodec/bs.h @@ -0,0 +1,402 @@ +#ifndef _H264_BS_H +#define _H264_BS_H 1 + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint8_t *start; + uint8_t *p; + uint8_t *end; + int bits_left; +} bs_t; + +#define _OPTIMIZE_BS_ 1 + +#if ( _OPTIMIZE_BS_ > 0 ) +#ifndef FAST_U8 +#define FAST_U8 +#endif +#endif + + +static bs_t *bs_new(uint8_t *buf, size_t size); +static void bs_free(bs_t *b); +static bs_t *bs_clone(bs_t *dest, const bs_t *src); +static bs_t *bs_init(bs_t *b, uint8_t *buf, size_t size); +static uint32_t bs_byte_aligned(bs_t *b); +static int bs_eof(bs_t *b); +static int bs_overrun(bs_t *b); +static int bs_pos(bs_t *b); + +static uint32_t bs_peek_u1(bs_t *b); +static uint32_t bs_read_u1(bs_t *b); +static uint32_t bs_read_u(bs_t *b, int n); +static uint32_t bs_read_f(bs_t *b, int n); +static uint32_t bs_read_u8(bs_t *b); +static uint32_t bs_read_ue(bs_t *b); +static int32_t bs_read_se(bs_t *b); + +static void bs_write_u1(bs_t *b, uint32_t v); +static void bs_write_u(bs_t *b, int n, uint32_t v); +static void bs_write_f(bs_t *b, int n, uint32_t v); +static void bs_write_u8(bs_t *b, uint32_t v); +static void bs_write_ue(bs_t *b, uint32_t v); +static void bs_write_se(bs_t *b, int32_t v); + +static int bs_read_bytes(bs_t *b, uint8_t *buf, int len); +static int bs_write_bytes(bs_t *b, uint8_t *buf, int len); +static int bs_skip_bytes(bs_t *b, int len); +static uint32_t bs_next_bits(bs_t *b, int nbits); +// IMPLEMENTATION + +static inline bs_t *bs_init(bs_t *b, uint8_t *buf, size_t size) +{ + b->start = buf; + b->p = buf; + b->end = buf + size; + b->bits_left = 8; + return b; +} + +static inline bs_t *bs_new(uint8_t *buf, size_t size) +{ + bs_t *b = (bs_t *)malloc(sizeof(bs_t)); + bs_init(b, buf, size); + return b; +} + +static inline void bs_free(bs_t *b) +{ + free(b); +} + +static inline bs_t *bs_clone(bs_t *dest, const bs_t *src) +{ + dest->start = src->p; + dest->p = src->p; + dest->end = src->end; + dest->bits_left = src->bits_left; + return dest; +} + +static inline uint32_t bs_byte_aligned(bs_t *b) +{ + return (b->bits_left == 8); +} + +static inline int bs_eof(bs_t *b) +{ + if (b->p >= b->end) { + return 1; + } else { + return 0; + } +} + +static inline int bs_overrun(bs_t *b) +{ + if (b->p > b->end) { + return 1; + } else { + return 0; + } +} + +static inline int bs_pos(bs_t *b) +{ + if (b->p > b->end) { + return (b->end - b->start); + } else { + return (b->p - b->start); + } +} + +static inline int bs_bytes_left(bs_t *b) +{ + return (b->end - b->p); +} + +static inline uint32_t bs_read_u1(bs_t *b) +{ + uint32_t r = 0; + + b->bits_left--; + + if (! bs_eof(b)) { + r = ((*(b->p)) >> b->bits_left) & 0x01; + } + + if (b->bits_left == 0) { + b->p ++; + b->bits_left = 8; + } + + return r; +} + +static inline void bs_skip_u1(bs_t *b) +{ + b->bits_left--; + if (b->bits_left == 0) { + b->p ++; + b->bits_left = 8; + } +} + +static inline uint32_t bs_peek_u1(bs_t *b) +{ + uint32_t r = 0; + + if (! bs_eof(b)) { + r = ((*(b->p)) >> (b->bits_left - 1)) & 0x01; + } + return r; +} + + +static inline uint32_t bs_read_u(bs_t *b, int n) +{ + uint32_t r = 0; + int i; + for (i = 0; i < n; i++) { + r |= (bs_read_u1(b) << (n - i - 1)); + } + return r; +} + +static inline void bs_skip_u(bs_t *b, int n) +{ + int i; + for (i = 0; i < n; i++) { + bs_skip_u1(b); + } +} + +static inline uint32_t bs_read_f(bs_t *b, int n) +{ + return bs_read_u(b, n); +} + +static inline uint32_t bs_read_u8(bs_t *b) +{ +#ifdef FAST_U8 + if (b->bits_left == 8 && ! bs_eof(b)) { // can do fast read + uint32_t r = b->p[0]; + b->p++; + return r; + } +#endif + return bs_read_u(b, 8); +} + +static inline uint32_t bs_read_ue(bs_t *b) +{ + int32_t r = 0; + int i = 0; + + while ((bs_read_u1(b) == 0) && (i < 32) && (!bs_eof(b))) { + i++; + } + r = bs_read_u(b, i); + r += (1 << i) - 1; + return r; +} + +static inline int32_t bs_read_se(bs_t *b) +{ + int32_t r = bs_read_ue(b); + if (r & 0x01) { + r = (r + 1) / 2; + } else { + r = -(r / 2); + } + return r; +} + + +static inline void bs_write_u1(bs_t *b, uint32_t v) +{ + b->bits_left--; + + if (! bs_eof(b)) { + // FIXME this is slow, but we must clear bit first + // is it better to memset(0) the whole buffer during bs_init() instead? + // if we don't do either, we introduce pretty nasty bugs + (*(b->p)) &= ~(0x01 << b->bits_left); + (*(b->p)) |= ((v & 0x01) << b->bits_left); + } + + if (b->bits_left == 0) { + b->p ++; + b->bits_left = 8; + } +} + +static inline void bs_write_u(bs_t *b, int n, uint32_t v) +{ + int i; + for (i = 0; i < n; i++) { + bs_write_u1(b, (v >> (n - i - 1)) & 0x01); + } +} + +static inline void bs_write_f(bs_t *b, int n, uint32_t v) +{ + bs_write_u(b, n, v); +} + +static inline void bs_write_u8(bs_t *b, uint32_t v) +{ +#ifdef FAST_U8 + if (b->bits_left == 8 && ! bs_eof(b)) { // can do fast write + b->p[0] = v; + b->p++; + return; + } +#endif + bs_write_u(b, 8, v); +} + +static inline void bs_write_ue(bs_t *b, uint32_t v) +{ + static const int len_table[256] = { + 1, + 1, + 2, 2, + 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + }; + + int len; + + if (v == 0) { + bs_write_u1(b, 1); + } else { + v++; + + if (v >= 0x01000000) { + len = 24 + len_table[ v >> 24 ]; + } else if (v >= 0x00010000) { + len = 16 + len_table[ v >> 16 ]; + } else if (v >= 0x00000100) { + len = 8 + len_table[ v >> 8 ]; + } else { + len = len_table[ v ]; + } + + bs_write_u(b, 2 * len - 1, v); + } +} + +static inline void bs_write_se(bs_t *b, int32_t v) +{ + if (v <= 0) { + bs_write_ue(b, -v * 2); + } else { + bs_write_ue(b, v * 2 - 1); + } +} + +static inline int bs_read_bytes(bs_t *b, uint8_t *buf, int len) +{ + int actual_len = len; + if (b->end - b->p < actual_len) { + actual_len = b->end - b->p; + } + if (actual_len < 0) { + actual_len = 0; + } + memcpy(buf, b->p, actual_len); + if (len < 0) { + len = 0; + } + b->p += len; + return actual_len; +} + +static inline int bs_write_bytes(bs_t *b, uint8_t *buf, int len) +{ + int actual_len = len; + if (b->end - b->p < actual_len) { + actual_len = b->end - b->p; + } + if (actual_len < 0) { + actual_len = 0; + } + memcpy(b->p, buf, actual_len); + if (len < 0) { + len = 0; + } + b->p += len; + return actual_len; +} + +static inline int bs_skip_bytes(bs_t *b, int len) +{ + int actual_len = len; + if (b->end - b->p < actual_len) { + actual_len = b->end - b->p; + } + if (actual_len < 0) { + actual_len = 0; + } + if (len < 0) { + len = 0; + } + b->p += len; + return actual_len; +} + +static inline uint32_t bs_next_bits(bs_t *bs, int nbits) +{ + bs_t b; + bs_clone(&b, bs); + return bs_read_u(&b, nbits); +} + +static inline uint64_t bs_next_bytes(bs_t *bs, int nbytes) +{ + int i = 0; + uint64_t val = 0; + + if ((nbytes > 8) || (nbytes < 1)) { + return 0; + } + if (bs->p + nbytes > bs->end) { + return 0; + } + + for (i = 0; i < nbytes; i++) { + val = (val << 8) | bs->p[i]; + } + return val; +} + +#define bs_print_state(b) fprintf( stderr, "%s:%d@%s: b->p=0x%02hhX, b->left = %d\n", __FILE__, __LINE__, __FUNCTION__, *b->p, b->bits_left ) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hardware/chip/x2000/example/vcodec/h264dec_test.c b/hardware/chip/x2000/example/vcodec/h264dec_test.c new file mode 100644 index 0000000000000000000000000000000000000000..5196126b217d9349f6ed874316e8d8c172773af7 --- /dev/null +++ b/hardware/chip/x2000/example/vcodec/h264dec_test.c @@ -0,0 +1,464 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../hal/vcodec/drv_codec.h" +#include "bs.h" + +#include "aos/vfs.h" +#if AOS_COMP_CLI +#include "aos/cli.h" +#endif + +#define PACKET_LEN 256 * 1024 +char packet[PACKET_LEN]; + + +struct configInfo { + int width; + int height; + char *srcfile; +}; + +static struct configInfo input_params; + +static struct option long_options[] = { + { "pixel_size", required_argument, NULL, 's'}, + { "src_file ", required_argument, NULL, 'i'}, + { "help ", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0}, +}; + +#define print_opt_help(opt_index, help_str) \ + do { \ + printf(" -%c or --%s %s", (char)long_options[opt_index].val, long_options[opt_index].name, help_str); \ + } while (0) + +static void usage() +{ + printf("\nh264dec-example usage:\n"); + print_opt_help(0, "Resolution size of H264 encoded code stream file. The format is WxH, for example: 1280x720.\n"); + print_opt_help(1, "File name and path of H264 encoded code stream file.\n"); + print_opt_help(2, "show help.\n"); +} + +//static int get_paramt(int argc, char *argv[]) +static int get_paramt(void) +{ + int ret = 0; + memset(&input_params, 0, sizeof(struct configInfo)); +#if 0 + char optstring[] = "s:i:h"; + while ((ret = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { + switch (ret) { + case 's': + if (2 != sscanf(optarg, "%dx%d", &input_params.width, &input_params.height)) { + printf("The resolution format of the resolution size is incorrect!\r\n"); + exit(-1); + } + break; + case 'i': + input_params.srcfile = optarg; + break; + case 'h': + usage(); + exit(0); + case '?': + default: + usage(); + exit(-1); + } + } +#else + input_params.width = 1280; + input_params.height = 720; + input_params.srcfile = "/data/video_50k.h264"; +#endif + + if (0 == input_params.width || 0 == input_params.height || NULL == input_params.srcfile) { + printf("Please input paramt!!!\r\n"); + usage(); + exit(-1); + } + + return 0; +} + + + +typedef struct { + unsigned char *stream; + unsigned char type; + unsigned int size; +} nal_unit_t; + +#define MAX_NALS_PER_TIME 9000 //25fps@60min + +typedef struct { + nal_unit_t nal[MAX_NALS_PER_TIME]; + int nal_count; +} nal_units_t; + +nal_units_t nal_units; + + +static int m_find_start_code(unsigned char *buf, unsigned int len, unsigned int *prefix_bytes) +{ + unsigned char *start = buf; + unsigned char *end = buf + len; + int index = 0; + + if (start >= end) { + return -1; + } + + while (start < end) { +#if 1 + /* next24bits */ + index = start - buf; + + if (start[0] == 0 && start[1] == 0 && start[2] == 1) { + *prefix_bytes = 3; + return index + 3; + } + + start++; + + + /* end of data buffer, no need to find. */ + if ((start + 3) == end) { + return -1; + } +#endif + } + + return -1; +} + +static unsigned int get_nal_size(char *buf, unsigned int len) +{ + char *start = buf; + char *end = buf + len; + unsigned int size = 0; + + if (start >= end) { + return -1; + } + + while (start < end) { + + if (start[0] == 0 && start[1] == 0 && start[2] == 1) { + break; + } + + start++; + } + + size = (unsigned int)(start - buf); + + return size; +} + +int extract_nal_units(nal_units_t *nals, unsigned char *buf, unsigned int len) +{ + int index = 0; + int next_nal = 0; + unsigned char *start = buf; + unsigned char *end = buf + len; + int size = 0; + unsigned int prefix_bytes; /*000001/00000001*/ + nal_unit_t *nal; + + unsigned int left = len; + int i = 0; + + int eos = 0; + nals->nal_count = 0; + + for (i = 0; i < MAX_NALS_PER_TIME; i++) { + + nal = &nals->nal[i]; + + index = m_find_start_code(start, left, &prefix_bytes); + if (index < 0) { + printf("no start code found!\n"); + return -1; + } + + nal->stream = start; + nal->type = nal->stream[index]; + + nal->size = get_nal_size(start + index, left - index) + index; + nals->nal_count++; + + start += nal->size; + left -= nal->size; + + if (left <= 0) { + /*EOS*/ + break; + } + + } + + if (left) { + printf("too many nals extraced!, %d bytes left\n", left); + } + + return len - left; +} + +/* 从NALS 中合并一个完整的Frame,将Frame中所有的slice 拼接到一起。*/ +static int get_slice_frame(nal_unit_t *nals, int start, int nal_counts, unsigned char **slice_frame_buffer, unsigned int *slice_frame_size, int *got_frame) +{ + nal_unit_t *nal = NULL; + int i = 0; + + int first_mb_in_slice = 0; + int slice_type = 0; + int new_frame = 0; + bs_t current_nal_bs; + + *got_frame = 0; + *slice_frame_size = 0; + + for (i = start; i < nal_counts; i++) { + + nal = &nal_units.nal[i]; + + bs_init(¤t_nal_bs, nal->stream + 4, nal->size - 4); + + + if ((nal->type & 0x1f) == 0x5 || (nal->type & 0x1f) == 0x1) { + first_mb_in_slice = bs_read_ue(¤t_nal_bs); + slice_type = bs_read_ue(¤t_nal_bs); + + + if (first_mb_in_slice == 0) { + + if (new_frame) { + *got_frame = 1; + break; + } + new_frame = 1; + } + + } + + if (*slice_frame_buffer == NULL) { + *slice_frame_buffer = nal->stream; + } + + *slice_frame_size += nal->size; + } + + return i; +} + +static void dump_dec_data(unsigned char *buf, unsigned int size, int index) +{ + if(index == 0){ + printf("y data: vddr = %x, size = %x\n", buf, size); + hexdump(buf, 128/*size*/); + }else{ + printf("uv data: vddr = %x, size = %x\n", buf, size); + hexdump(buf, 128/*size*/); + } +} + +//int do_h264_dec(int argc, char **argv) +int do_h264_dec(void) +{ + int ret = 0; + IHal_CodecHandle_t *codec_handle = NULL; + IHal_CodecParam h264dec_param; + int srcbuf_nums = 0; + int dstbuf_nums = 0; + int srcfd = -1; + unsigned long filesize = 0; + + printf("================== do_h264_dec start\n"); + //get_paramt(argc, argv); + get_paramt(); + + ret = IHal_CodecInit(); + assert(0 == ret); + + codec_handle = IHal_CodecCreate(H264_DEC); + assert(0 != codec_handle); + + memset(&h264dec_param, 0, sizeof(IHal_CodecParam)); + h264dec_param.codec_type = H264_DEC; + h264dec_param.codecparam.h264d_param.src_width = input_params.width; /* 源图像宽度 */ + h264dec_param.codecparam.h264d_param.src_height = input_params.height; /* 源图像高度 */ + h264dec_param.codecparam.h264d_param.dst_fmt = IMPP_PIX_FMT_NV12; /* 目标像素格式 */ + ret = IHal_Codec_SetParams(codec_handle, &h264dec_param); + assert(0 == ret); + + srcbuf_nums = IHal_Codec_CreateSrcBuffers(codec_handle, IMPP_INTERNAL_BUFFER, 3); + assert(1 <= srcbuf_nums); + + dstbuf_nums = IHal_Codec_CreateDstBuffer(codec_handle, IMPP_INTERNAL_BUFFER, 3); + assert(1 <= dstbuf_nums); + + ret = IHal_Codec_Start(codec_handle); + assert(0 == ret); + + srcfd = open(input_params.srcfile, O_RDONLY); + assert(-1 != srcfd); + + int dstfd = -1; + dstfd = open("/data/out_test.nv12", O_RDWR | O_CREAT | O_TRUNC, 0666); + assert(-1 != dstfd); + + filesize = lseek(srcfd, 0, SEEK_END); + lseek(srcfd, 0, SEEK_SET); + + int index = 0; + int packet_len = 0; + nal_unit_t *nal = NULL; + nal_unit_t *next_nal = NULL; + nal_unit_t *last_nal = NULL; + unsigned long current_offset = 0; + char *slice_frame_buffer = NULL; + unsigned long slice_frame_size = 0; + int eof = 0; + IMPP_BufferInfo_t codec_srcbuf; + IHAL_CodecStreamInfo_t codec_dststream; + int nal_count = 0; + int got_frame = 0; + int start = 0; + + while (1) { + memset(&codec_srcbuf, 0, sizeof(IMPP_BufferInfo_t)); + + packet_len = read(srcfd, packet, PACKET_LEN); + if (packet_len <= 0) { + // lseek(srcfd,0,SEEK_SET); + break; + } + + nal_units.nal_count = 0; + ret = extract_nal_units(&nal_units, packet, packet_len); + + if (ret < packet_len) { + printf("packet not extracted completely!\n"); + } + + nal_count = 0; + + last_nal = &nal_units.nal[nal_units.nal_count - 1]; + current_offset = lseek(srcfd, 0, SEEK_CUR); + + if (current_offset < filesize) { + nal_count = nal_units.nal_count - 1; + lseek(srcfd, -last_nal->size, SEEK_CUR); + } else { + /*EOF.*/ + nal_count = nal_units.nal_count; + eof = 1; + printf("----EOF----!\n"); + } + + got_frame = 0; + start = 0; + + do { + slice_frame_buffer = NULL; + ret = get_slice_frame(&nal_units, start, nal_count, &slice_frame_buffer, &slice_frame_size, &got_frame); + start = ret; + if (ret == nal_count) { + if (!got_frame && eof == 0) { + /* reseek to last nal decoded.*/ + lseek(srcfd, -slice_frame_size, SEEK_CUR); + } + break; + } + + /* decode nal units */ + ret = IHal_Codec_GetSrcBuffer(codec_handle, index, &codec_srcbuf); + assert(0 == ret); + + for (int i = 0; i < codec_srcbuf.mplane.numPlanes; i++) { + memcpy(codec_srcbuf.mplane.vaddr[i], slice_frame_buffer, slice_frame_size); + } + codec_srcbuf.byteused = slice_frame_size; + + ret = IHal_Codec_QueueSrcBuffer(codec_handle, &codec_srcbuf); + assert(0 == ret); + + ret = IHal_Codec_WaitDstAvailable(codec_handle, IMPP_WAIT_FOREVER); + assert(0 == ret); + + ret = IHal_Codec_DequeueDstBuffer(codec_handle, &codec_dststream); + assert(0 == ret); + + dump_dec_data(codec_dststream.mp.vaddr[0], codec_dststream.mp.len[0], 0); + dump_dec_data(codec_dststream.mp.vaddr[1], codec_dststream.mp.len[1], 1); + write(dstfd, codec_dststream.mp.vaddr[0], codec_dststream.mp.len[0]); + write(dstfd, codec_dststream.mp.vaddr[1], codec_dststream.mp.len[1]); + + + ret = IHal_Codec_QueueDstBuffer(codec_handle, &codec_dststream); + assert(0 == ret); + + ret = IHal_Codec_WaitSrcAvailable(codec_handle, IMPP_WAIT_FOREVER); + assert(0 == ret); + + ret = IHal_Codec_DequeueSrcBuffer(codec_handle, &codec_srcbuf); + assert(0 == ret); + } while (1); + } + +exit_loop: + + + close(dstfd); + + ret = close(srcfd); + assert(0 == ret); + + ret = IHal_Codec_Stop(codec_handle); + assert(0 == ret); + + ret = IHal_CodecDestroy(codec_handle); + assert(0 == ret); + + IHal_CodecDeInit(); + + return 0; +} + +static void __h264_dec(int32_t argc, char **argv) +{ + int ret = do_h264_dec(); + if(!ret) + printf("do_h264_dec done\n"); + else + printf("do_h264_dec err!\n"); + + return; +} + +#if AOS_COMP_CLI +#if 0 +struct cli_command vfs_h264dec_cmds[] = { + { "h264dec", "h264dec test", do_h264_dec, }, +}; + +int vfs_h264dec_test_cmd_init(void) +{ + return aos_cli_register_commands(&vfs_h264dec_cmds[0], sizeof(vfs_h264dec_cmds) / sizeof(vfs_h264dec_cmds[0])); +} + +POST_DRIVER_ENTRY(vfs_h264dec_test_cmd_init) +#else +ALIOS_CLI_CMD_REGISTER(__h264_dec, h264_dec, h264dec test) +#endif +#endif /* AOS_COMP_CLI */ + diff --git a/hardware/chip/x2000/hal/vcodec/drv_codec.c b/hardware/chip/x2000/hal/vcodec/drv_codec.c new file mode 100755 index 0000000000000000000000000000000000000000..2fdc503a12c46e9a51ab9c5d2289ce02c3c28fd3 --- /dev/null +++ b/hardware/chip/x2000/hal/vcodec/drv_codec.c @@ -0,0 +1,585 @@ +#include +#include +#include +#include +#include "drv_codec.h" +#include "x2000_hal_felix.h" + +#define TAG "x2000-codec" +/** + * @brief 编解码器模块的初始化,在创建编解码通道之前调用 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_CodecInit(void) +{ + ingenic_felix_init(); + return 0; +} + +/** + * @brief 编解码器模块的反初始化 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_CodecDeInit(void) +{ + ingenic_felix_deinit(); + + return 0; +} + +/** + * @brief 创建一个编码解码通道 + * @param [in] type : 要创建的编解码器类型 + * @retval IHal_CodecHandle_t 成功 + * @retval IHAL_RNULL 失败 + */ + +IHal_CodecHandle_t *IHal_CodecCreate(CODEC_TYPE type) +{ + void *ctx = NULL; + + IHal_CodecHandle_t *ret = NULL; + ret = malloc(sizeof(IHal_CodecHandle_t)); + if (!ret) { + printf("codec create failed"); + return IHAL_RNULL; + } + + switch (type) { + case H264_ENC: + break; + case H264_DEC: + ctx = ingenic_felix_ctx_init(); + if(!ctx) + printf("ingenic_felix_ctx_init error!\n"); + break; + case JPEG_ENC: + break; + case JPEG_DEC: + break; + default: + printf("not support codec type"); + return IHAL_RNULL; + } + + ret->codectype = type; + ret->ctx = ctx; + + return ret; +} + +/** + * @brief 销毁一个编码解码通道 + * @param [in] handle : Codec handle + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_CodecDestroy(IHal_CodecHandle_t *handle) +{ + CODEC_TYPE type = handle->codectype; + switch (type) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ingenic_felix_ctx_deinit(handle->ctx); + break; + default: + printf("not support codec type"); + return IHAL_RNULL; + + } + + free(handle); + + return IHAL_ROK; +} + +/** + * @brief 设置编解码器的参数,需要在编解码器启动之前调用一次 + * @param [in] handle : Codec handle + * @param [in] param : 要设置的编解码器参数 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_SetParams(IHal_CodecHandle_t *handle, IHal_CodecParam *param) +{ + + IHal_H264E_Param h264e_param = param->codecparam.h264e_param; + IHal_JpegEnc_Param jpegenc_param = param->codecparam.jpegenc_param; + IHal_JpegDec_Param jpegdec_param = param->codecparam.jpegdec_param; + IHal_H264D_Param h264d_param = param->codecparam.h264d_param; + int width = 0; + int height = 0; + unsigned int fourcc = 0; + + /*param set*/ + switch(handle->codectype) { + case H264_ENC: + break; + case H264_DEC: + width = h264d_param.src_width; + height = h264d_param.src_height; + switch(h264d_param.dst_fmt) { + case IMPP_PIX_FMT_NV12: + ingenic_vcodec_felix_set_param(handle->ctx, width, height, 2/*VPU_FORMAT_NV12*/); + break; + case IMPP_PIX_FMT_NV21: + ingenic_vcodec_felix_set_param(handle->ctx, width, height, 3/*VPU_FORMAT_NV21*/); + break; + default: + printf("dst_fmt type(%d) error ", h264d_param.dst_fmt); + return IHAL_RFAILED; + } + break; + case JPEG_ENC: + break; + case JPEG_DEC: + break; + default: + break; + } + + return IHAL_ROK; +} + +/** + * @brief 获取编解码器的参数 + * @param [in] handle : Codec handle + * @param [out] param : 被设置的编解码器参数 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_GetParams(IHal_CodecHandle_t *handle, IHal_CodecParam *param) +{ + IHal_H264E_Param h264e_param = {0}; + IHal_H264D_Param h264d_param = {0}; + + switch(handle->codectype) { + case H264_ENC: + break; + case H264_DEC: + ingenic_vcodec_felix_get_param(handle->ctx, FELIX_FORMAT,&h264d_param.dst_fmt); + ingenic_vcodec_felix_get_param(handle->ctx, FELIX_WIDTH,&h264d_param.src_width); + ingenic_vcodec_felix_get_param(handle->ctx, FELIX_HEIGHT,&h264d_param.src_height); + memcpy(¶m->codecparam.h264d_param, &h264d_param, sizeof(h264d_param)); + break; + case JPEG_ENC: + case JPEG_DEC: + default: + break; + } + + return IHAL_ROK; +} + +/** + * @brief 启动编解码器 + * @param [in] handle : Codec handle + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_Start(IHal_CodecHandle_t *handle) +{ + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ingenic_vcodec_felix_start(handle->ctx); + break; + default: + break; + } + + return IHAL_ROK; +} + +/** + * @brief 停止编解码器 + * @param [in] handle : Codec handle + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_Stop(IHal_CodecHandle_t *handle) +{ + unsigned int ret = 0; + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ret = ingenic_vcodec_felix_stop(handle->ctx); + default: + break; + } + + return ret; +} + +/** + * @brief 创建编解码源数据缓冲区 + * @param [in] handle : Codec handle + * @param [in] buftype : 缓冲区类型 + * @param [in] create_num : 需要创建的缓冲区个数 + * @retval 实际创建的缓冲区个数 成功 + * @retval 错误码 失败 + */ +IHAL_INT32 IHal_Codec_CreateSrcBuffers(IHal_CodecHandle_t *handle, IMPP_BUFFER_TYPE buftype, IHAL_INT32 create_num) +{ + IHAL_INT32 ret = 0; + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ret = ingenic_vcodec_felix_create_srcbuf(handle->ctx, create_num); + break; + default: + break; + } + + return ret; +} + +/** + * @brief 设置编解码源数据缓冲区,用于共享缓冲区,在编解码器启动之前进行调用 + * @param [in] handle : Codec handle + * @param [in] index : 缓冲区序号 + * @param [in] sharebuf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_SetSrcBuffer(IHal_CodecHandle_t *handle, int index, IMPP_BufferInfo_t *sharebuf) +{ + IHAL_INT32 ret = 0; + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ret = ingenic_vcodec_felix_set_srcbuf(handle->ctx, index, sharebuf->vaddr, sharebuf->paddr); + break; + default: + break; + } + + return ret; +} + +/** + * @brief 获取编解码源数据缓冲区,用于共享缓冲区 + * @param [in] handle : Codec handle + * @param [in] index : 缓冲区序号 + * @param [out] sharebuf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_GetSrcBuffer(IHal_CodecHandle_t *handle, int index, IMPP_BufferInfo_t *sharebuf) +{ + unsigned int vaddr = 0; + unsigned int size = 0; + unsigned int np = 0; + unsigned int i = 0; + + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + /*TODO num_planes*/ + break; + case H264_DEC: + ingenic_vcodec_felix_get_srcbuf(handle->ctx, index, &vaddr, &size); + sharebuf->mplane.vaddr[0] = vaddr; + sharebuf->mplane.len[0] = size; + sharebuf->index = index; + sharebuf->mplane.numPlanes = 1; + break; + default: + break; + } + + return IHAL_ROK; +} + +/** + * @brief 创建编解码器输出数据缓冲区 + * @param [in] handle : Codec handle + * @param [in] buftype : 缓冲区类型 + * @param [in] create_num : 需要创建的缓冲区个数 + * @retval 实际创建的缓冲区个数 成功 + * @retval 错误码 失败 + * @attention 仅用于解码器输出缓冲区类型,编码器默认为内部缓冲区( #IMPP_INTERNAL_BUFFER ) + */ +IHAL_INT32 IHal_Codec_CreateDstBuffer(IHal_CodecHandle_t *handle, IMPP_BUFFER_TYPE buftype, IHAL_INT32 create_num) +{ + IHAL_INT32 ret = 0; + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ret = ingenic_vcodec_felix_create_dstbuf(handle->ctx, create_num); + break; + default: + break; + } + + return ret; +} + +/** + * @brief 设置编解码器输出数据缓冲区,用于共享缓冲区,在编解码器启动之前调用 + * @param [in] handle : Codec handle + * @param [in] index : 缓冲区序号 + * @param [in] sharebuf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + * @attention 仅用于解码器缓冲区,编码器默认为内部缓冲区( #IMPP_INTERNAL_BUFFER ) + */ +IHAL_INT32 IHal_Codec_SetDstBuffer(IHal_CodecHandle_t *handle, int index, IMPP_BufferInfo_t *sharebuf) +{ + IHAL_INT32 ret = 0; + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ret = ingenic_vcodec_felix_set_dstbuf(handle->ctx, index, sharebuf->vaddr, sharebuf->paddr, sharebuf->size); + break; + default: + break; + } + + return ret; +} + +/** + * @brief 获取编解码器输出数据缓冲区,用于共享缓冲区 + * @param [in] handle : Codec handle + * @param [in] index : 缓冲区序号 + * @param [out] sharebuf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_GetDstBuffer(IHal_CodecHandle_t *handle, int index, IMPP_BufferInfo_t *sharebuf) +{ + unsigned int vaddr = 0; + unsigned int size = 0; + + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + /*TODO num_planes*/ + break; + case H264_DEC: + ingenic_vcodec_felix_get_dstbuf(handle->ctx, 0, index, &vaddr, &size); + sharebuf->mplane.vaddr[0] = vaddr; + sharebuf->mplane.len[0] = size; + ingenic_vcodec_felix_get_dstbuf(handle->ctx, 1, index, &vaddr, &size); + sharebuf->mplane.vaddr[1] = vaddr; + sharebuf->mplane.len[1] = size; + + break; + default: + break; + } + + return IHAL_ROK; +} + +/** + * @brief 等待编解码器源数据缓冲区可用 + * @param [in] handle : Codec handle + * @param [in] wait_type : 等待类型( #IMPP_NO_WAIT 或 #IMPP_WAIT_FOREVER ) + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_WaitSrcAvailable(IHal_CodecHandle_t *handle, IHAL_INT32 wait_type) +{ + unsigned int ret = 0; + + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + if(wait_type == IMPP_WAIT_FOREVER) + ret = ingenic_vcodec_felix_srcbuf_wait(handle->ctx, 1); + else + ret = ingenic_vcodec_felix_srcbuf_wait(handle->ctx, 0); + break; + default: + break; + } + + return ret; +} + +/** + * @brief 释放编解码器的源数据缓冲区 + * @param [in] handle : Codec handle + * @param [in] buf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_QueueSrcBuffer(IHal_CodecHandle_t *handle, IMPP_BufferInfo_t *buf) +{ + IHAL_INT32 ret = IHAL_ROK; + + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ret = ingenic_vcodec_felix_srcbuf_queue(handle->ctx, buf->index); + break; + default: + break; + } + + return ret; +} + +/** + * @brief 获取编解码器的源数据缓冲区 + * @param [in] handle : Codec handle + * @param [out] buf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_DequeueSrcBuffer(IHal_CodecHandle_t *handle, IMPP_BufferInfo_t *buf) +{ + int index = 0; + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ingenic_vcodec_felix_srcbuf_dequeue(handle->ctx, &index); + buf->index = index; + break; + default: + break; + } + + return IHAL_ROK; +} + +/** + * @brief 等待编解码器输出数据缓冲区可用 + * @param [in] handle : Codec handle + * @param [in] wait_type : 等待类型( #IMPP_NO_WAIT 或 #IMPP_WAIT_FOREVER ) + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_WaitDstAvailable(IHal_CodecHandle_t *handle, IHAL_INT32 wait_type) +{ + unsigned int ret = 0; + + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + if(wait_type == IMPP_WAIT_FOREVER) + ret = ingenic_vcodec_felix_dstbuf_wait(handle->ctx, 1); + else + ret = ingenic_vcodec_felix_dstbuf_wait(handle->ctx, 0); + break; + default: + break; + } + + return ret; +} + +/** + * @brief 归还编解码器的输出数据缓冲区 + * @param [in] handle : Codec handle + * @param [in] buf : 编解码器输出流信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_QueueDstBuffer(IHal_CodecHandle_t *handle, IHAL_CodecStreamInfo_t *buf) +{ + IHAL_INT32 ret = IHAL_ROK; + + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + ret = ingenic_vcodec_felix_dstbuf_queue(handle->ctx, buf->index); + break; + default: + break; + } + + return ret; +} + +/** + * @brief 获取编解码器的输出数据缓冲区 + * @param [in] handle : Codec handle + * @param [out] buf : 编解码器输出流信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_DequeueDstBuffer(IHal_CodecHandle_t *handle, IHAL_CodecStreamInfo_t *buf) +{ + int index = 0; + unsigned int vaddr[3] = {0}; + unsigned int size[3] = {0}; + unsigned int np = 0; + unsigned int i = 0; + + switch(handle->codectype) { + case H264_ENC: + case JPEG_ENC: + case JPEG_DEC: + break; + case H264_DEC: + np = 2; /* y_data and uv_data*/ + ingenic_vcodec_felix_dstbuf_dequeue(handle->ctx, np, &index, vaddr, size); + for(i = 0; i < np; i++) { + buf->mp.vaddr[i] = vaddr[i]; + buf->mp.len[i] = size[i]; + } + buf->index = index; + break; + default: + break; + } + + return IHAL_ROK; +} + +/** + * @brief 设置编解码器的控制参数 + * @param [in] handle : Codec handle + * @param [in] param : 编解码器控制参数 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_Control(IHal_CodecHandle_t *handle, IHal_CodecControlParam_t *param) +{ + + return IHAL_RFAILED; +} + diff --git a/hardware/chip/x2000/hal/vcodec/drv_codec.h b/hardware/chip/x2000/hal/vcodec/drv_codec.h new file mode 100755 index 0000000000000000000000000000000000000000..872cbe586dea66d62371068bacd48138b3a291c8 --- /dev/null +++ b/hardware/chip/x2000/hal/vcodec/drv_codec.h @@ -0,0 +1,469 @@ +/** + * @file codec.h + * @author ingenic-team + * @brief + * @version 0.1 + * @date 2021-12-06 + * + * @copyright Copyright (c) ingenic 2021 + * + */ +#ifndef __CODEC_H__ +#define __CODEC_H__ + +#include "impp.h" + +/** + * @defgroup group_Codec Codec模块 + * @{ + */ + +/** + * @addtogroup group_Codec_data_type 数据类型定义 + * @{ + */ + +/** + * @brief 码率控制模式 + */ +typedef enum __impp_rc_mode { + IMPP_ENC_RC_MODE_FIXQP, + IMPP_ENC_RC_MODE_CBR, + IMPP_ENC_RC_MODE_VBR, + IMPP_ENC_RC_MODE_CAPPED_VBR, + IMPP_ENC_RC_MODE_CAPPED_QUALITY, +} IMPP_RC_MODE; + +/** + * @brief 编解码器类型 + */ +typedef enum __codec_type { + H264_ENC = 0x01, /*!< h264编码 */ + H264_DEC = 0x02, /*!< h264解码 */ + H265_ENC = 0x03, /*!< h265编码 */ + H265_DEC = 0x04, /*!< h265解码 */ + JPEG_ENC = 0x05, /*!< jpeg编码 */ + JPEG_DEC = 0x06, /*!< jpeg解码 */ + AUDIO_G711A = 0x10, +} CODEC_TYPE; + +/** + * @brief JPEG编码参数 + */ +typedef struct __jpegenc_param { + IHAL_INT32 initialQp; /*!< 初始量化参数 */ + IHAL_INT32 quality; /*!< 质量参数 */ + IHAL_INT32 enc_width; /*!< 编码宽度 */ + IHAL_INT32 enc_height; /*!< 编码高度 */ + IHAL_INT32 src_width; /*!< 源图像宽度 */ + IHAL_INT32 src_height; /*!< 源图像高度 */ + IMPP_PIX_FMT src_fmt; /*!< 源图像像素格式 */ +} IHal_JpegEnc_Param; + +/** + * @brief JPEG解码参数 + */ +typedef struct __jpegdec_param { + IHAL_INT32 src_width; /*!< 源图像宽度 */ + IHAL_INT32 src_height; /*!< 源图像高度 */ + IHAL_INT32 quality; /*!< 质量参数 */ + IMPP_PIX_FMT dst_fmt; /*!< 目标像素格式 */ +} IHal_JpegDec_Param; + +/** + * @brief 控制命令 + */ +typedef enum { + ENCODER_IDR_REQUEST, +} IHal_ControlCmd_t; + +/** + * @brief 编解码器控制参数 + */ +typedef struct { + IHal_ControlCmd_t cmd; /*!< 控制命令 */ + IHAL_UINT32 priv[0]; +} IHal_CodecControlParam_t; + +/** + * @brief H264编码参数 + */ +typedef struct __h264e_param { + IMPP_RC_MODE rc_mode; /*!< 码率控制模式 */ + IHAL_INT32 target_bitrate; /*!< 目标码率 */ + IHAL_INT32 max_bitrate; /*!< 最大码率 */ + IHAL_INT32 gop_len; /*!< GOP长度 */ + IHAL_INT32 initial_Qp; /*!< 初始量化参数 */ + IHAL_INT32 IFrameQp; /*!< I帧量化参数 */ + IHAL_INT32 PFrameQp; /*!< P帧量化参数 */ + IHAL_INT32 mini_Qp; /*!< 最小量化参数 */ + IHAL_INT32 max_Qp; /*!< 最大量化参数 */ + IHAL_INT32 level; /*!< 编码的Level */ + IHAL_INT32 maxPSNR; + IHAL_INT32 freqIDR; /*!< I帧频率 */ + IHAL_INT32 maxPictureSize; + IHAL_INT32 frameRateNum; /*!< 帧率分母 */ + IHAL_INT32 frameRateDen; /*!< 帧率分子 */ + IHAL_INT32 enc_width; /*!< 编码宽度 */ + IHAL_INT32 enc_height; /*!< 编码高度 */ + IHAL_INT32 src_width; /*!< 源图像宽度 */ + IHAL_INT32 src_height; /*!< 源图像高度 */ + IMPP_PIX_FMT src_fmt; /*!< 源图像像素格式 */ +} IHal_H264E_Param; + +/** + * @brief H264解码参数 + */ +typedef struct __h264d_param { + IHAL_INT32 need_split; + IHAL_INT32 src_width; /*!< 源图像宽度 */ + IHAL_INT32 src_height; /*!< 源图像高度 */ + IMPP_PIX_FMT dst_fmt; /*!< 目标像素格式 */ +} IHal_H264D_Param; + +/** + * @brief H265编码参数 + */ +typedef struct __h265e_param { + IMPP_RC_MODE rc_mode; /*!< 码率控制模式 */ + IHAL_INT32 target_bitrate; /*!< 目标码率 */ + IHAL_INT32 max_bitrate; /*!< 最大码率 */ + IHAL_INT32 gop_len; /*!< GOP长度 */ + IHAL_INT32 initial_Qp; /*!< 初始量化参数 */ + IHAL_INT32 mini_Qp; /*!< 最小量化参数 */ + IHAL_INT32 max_Qp; /*!< 最大量化参数 */ + IHAL_INT32 level; /*!< 编码的Level */ + IHAL_INT32 freqIDR; /*!< I帧频率 */ + IHAL_INT32 maxPSNR; + IHAL_INT32 maxPictureSize; + IHAL_INT32 frameRateNum; /*!< 帧率分母 */ + IHAL_INT32 frameRateDen; /*!< 帧率分子 */ + IHAL_INT32 enc_width; /*!< 编码宽度 */ + IHAL_INT32 enc_height; /*!< 编码高度 */ + IHAL_INT32 src_width; /*!< 源图像宽度 */ + IHAL_INT32 src_height; /*!< 源图像高度 */ + IMPP_PIX_FMT src_fmt; /*!< 源图像像素格式 */ +} IHal_H265E_Param; + +/** + * @brief H265解码参数 + */ +typedef struct __h265d_param { + IHAL_INT32 need_split; + IHAL_INT32 src_width; /*!< 源图像宽度 */ + IHAL_INT32 src_height; /*!< 源图像高度 */ +} IHal_H265D_Param; + + +/** + * @brief 编解码器参数 + */ +typedef struct __codec_param { + CODEC_TYPE codec_type; /*!< 编解码器类型 */ + union { + IHal_JpegEnc_Param jpegenc_param; /*!< jpeg编码参数 */ + IHal_JpegDec_Param jpegdec_param; /*!< jpeg解码参数 */ + IHal_H264E_Param h264e_param; /*!< h264编码参数 */ + IHal_H264D_Param h264d_param; /*!< h264解码参数 */ + IHal_H265E_Param h265e_param; /*!< h265编码参数 */ + IHal_H265D_Param h265d_param; /*!< h265解码参数 */ + } codecparam; +} IHal_CodecParam; + +/** + * @brief H264编码NALU类型 + */ +typedef enum _H264E_NALU_TYPE_E { + H264E_NALU_BSLICE = 0, + H264E_NALU_PSLICE = 1, + H264E_NALU_ISLICE = 2, + H264E_NALU_IDRSLICE = 5, + H264E_NALU_SEI = 6, + H264E_NALU_SPS = 7, + H264E_NALU_PPS = 8, + H264E_NALU_BUTT +} H264E_NALU_TYPE_E; + + +/** + * @brief H265编码NALU类型 + */ +typedef enum _H265E_NALU_TYPE_E { + H265E_NALU_BSLICE = 0, + H265E_NALU_PSLICE = 1, + H265E_NALU_ISLICE = 2, + H265E_NALU_IDRSLICE = 19, + H265E_NALU_VPS = 32, + H265E_NALU_SPS = 33, + H265E_NALU_PPS = 34, + H265E_NALU_SEI = 39, + H265E_NALU_BUTT +} H265E_NALU_TYPE_E; + + +/** + * @brief 编码器NAL类型 + */ +typedef union nal_type { + H264E_NALU_TYPE_E h264e_nalu_type; + H265E_NALU_TYPE_E h265e_nalu_type; +} EncoderNalType; + +/** + * @brief 码流包信息 + */ +typedef struct _encoder_pack { + unsigned int offset; /*!< 偏移 */ + int length; /*!< 码流包长度 */ + int frameEnd; /*!< 结束帧 */ + int sliceType; /*!< Slice类型 */ + EncoderNalType nalType; /*!< 编码器NAL类型 */ +} EncoderPack; + + +/** + * @brief 码流信息 + */ +typedef struct _stream_info { + IHAL_UINT32 seq; /*!< 序列号 */ + IHAL_UINT32 packcnt; /*!< 码流包个数 */ + EncoderPack *pack; /*!< 码流包信息 */ +} IHAL_StreamPackInfo_t; + +/** + * @brief 编解码器输出流信息 + */ +typedef struct { + IHAL_UINT32 vaddr; /*!< 虚拟地址 */ + IHAL_UINT32 paddr; /*!< 物理地址 */ + IHAL_INT32 fd; /*!< 用于dma-buf */ + IHAL_UINT32 size; /*!< 码流大小 */ + IHAL_INT32 index; + /* buffer is mplane */ + struct { + IHAL_INT32 numPlanes; + IHAL_INT32 fd[3]; + IHAL_UINT32 vaddr[3]; + IHAL_UINT32 len[3]; + } mp; + IHAL_StreamPackInfo_t pack; /*!< 码流信息 */ +} IHAL_CodecStreamInfo_t; + + +/** + * @brief Codec handle + */ +struct IHal_CodecHandle { + CODEC_TYPE codectype; /*!< 编解码器类型 */ + void *ctx; +}; + +typedef struct IHal_CodecHandle IHal_CodecHandle_t; + +/** + * @} + */ + +/** + * @addtogroup group_Codec_API API定义 + * @{ + */ + +/** + * @brief 编解码器模块的初始化,在创建编解码通道之前调用 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_CodecInit(void); + +/** + * @brief 编解码器模块的反初始化 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_CodecDeInit(void); + +/** + * @brief 创建一个编码解码通道 + * @param [in] type : 要创建的编解码器类型 + * @retval IHal_CodecHandle_t 成功 + * @retval IHAL_RNULL 失败 + */ +IHal_CodecHandle_t *IHal_CodecCreate(CODEC_TYPE type); + +/** + * @brief 销毁一个编码解码通道 + * @param [in] handle : Codec handle + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_CodecDestroy(IHal_CodecHandle_t *handle); + +/** + * @brief 设置编解码器的参数,需要在编解码器启动之前调用一次 + * @param [in] handle : Codec handle + * @param [in] param : 要设置的编解码器参数 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_SetParams(IHal_CodecHandle_t *handle, IHal_CodecParam *param); + +/** + * @brief 获取编解码器的参数 + * @param [in] handle : Codec handle + * @param [out] param : 被设置的编解码器参数 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_GetParams(IHal_CodecHandle_t *handle, IHal_CodecParam *param); + +/** + * @brief 启动编解码器 + * @param [in] handle : Codec handle + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_Start(IHal_CodecHandle_t *handle); + +/** + * @brief 停止编解码器 + * @param [in] handle : Codec handle + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_Stop(IHal_CodecHandle_t *handle); + +/** + * @brief 创建编解码源数据缓冲区 + * @param [in] handle : Codec handle + * @param [in] buftype : 缓冲区类型 + * @param [in] create_num : 需要创建的缓冲区个数 + * @retval 实际创建的缓冲区个数 成功 + * @retval 错误码 失败 + */ +IHAL_INT32 IHal_Codec_CreateSrcBuffers(IHal_CodecHandle_t *handle, IMPP_BUFFER_TYPE buftype, IHAL_INT32 create_num); + +/** + * @brief 设置编解码源数据缓冲区,用于共享缓冲区,在编解码器启动之前进行调用 + * @param [in] handle : Codec handle + * @param [in] index : 缓冲区序号 + * @param [in] sharebuf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_SetSrcBuffer(IHal_CodecHandle_t *handle, int index, IMPP_BufferInfo_t *sharebuf); + +/** + * @brief 获取编解码源数据缓冲区,用于共享缓冲区 + * @param [in] handle : Codec handle + * @param [in] index : 缓冲区序号 + * @param [out] sharebuf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_GetSrcBuffer(IHal_CodecHandle_t *handle, int index, IMPP_BufferInfo_t *sharebuf); + +/** + * @brief 创建编解码器输出数据缓冲区 + * @param [in] handle : Codec handle + * @param [in] buftype : 缓冲区类型 + * @param [in] create_num : 需要创建的缓冲区个数 + * @retval 实际创建的缓冲区个数 成功 + * @retval 错误码 失败 + * @attention 仅用于解码器输出缓冲区类型,编码器默认为内部缓冲区( #IMPP_INTERNAL_BUFFER ) + */ +IHAL_INT32 IHal_Codec_CreateDstBuffer(IHal_CodecHandle_t *handle, IMPP_BUFFER_TYPE buftype, IHAL_INT32 create_num); + +/** + * @brief 设置编解码器输出数据缓冲区,用于共享缓冲区,在编解码器启动之前调用 + * @param [in] handle : Codec handle + * @param [in] index : 缓冲区序号 + * @param [in] sharebuf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + * @attention 仅用于解码器缓冲区,编码器默认为内部缓冲区( #IMPP_INTERNAL_BUFFER ) + */ +IHAL_INT32 IHal_Codec_SetDstBuffer(IHal_CodecHandle_t *handle, int index, IMPP_BufferInfo_t *sharebuf); + +/** + * @brief 获取编解码器输出数据缓冲区,用于共享缓冲区 + * @param [in] handle : Codec handle + * @param [in] index : 缓冲区序号 + * @param [out] sharebuf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_GetDstBuffer(IHal_CodecHandle_t *handle, int index, IMPP_BufferInfo_t *sharebuf); + +/** + * @brief 等待编解码器源数据缓冲区可用 + * @param [in] handle : Codec handle + * @param [in] wait_type : 等待类型( #IMPP_NO_WAIT 或 #IMPP_WAIT_FOREVER ) + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_WaitSrcAvailable(IHal_CodecHandle_t *handle, IHAL_INT32 wait_type); + +/** + * @brief 释放编解码器的源数据缓冲区 + * @param [in] handle : Codec handle + * @param [in] buf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_QueueSrcBuffer(IHal_CodecHandle_t *handle, IMPP_BufferInfo_t *buf); + +/** + * @brief 获取编解码器的源数据缓冲区 + * @param [in] handle : Codec handle + * @param [out] buf : 缓冲区信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_DequeueSrcBuffer(IHal_CodecHandle_t *handle, IMPP_BufferInfo_t *buf); + +/** + * @brief 等待编解码器输出数据缓冲区可用 + * @param [in] handle : Codec handle + * @param [in] wait_type : 等待类型( #IMPP_NO_WAIT 或 #IMPP_WAIT_FOREVER ) + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_WaitDstAvailable(IHal_CodecHandle_t *handle, IHAL_INT32 wait_type); + +/** + * @brief 归还编解码器的输出数据缓冲区 + * @param [in] handle : Codec handle + * @param [in] buf : 编解码器输出流信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_QueueDstBuffer(IHal_CodecHandle_t *handle, IHAL_CodecStreamInfo_t *buf); + +/** + * @brief 获取编解码器的输出数据缓冲区 + * @param [in] handle : Codec handle + * @param [out] buf : 编解码器输出流信息 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_DequeueDstBuffer(IHal_CodecHandle_t *handle, IHAL_CodecStreamInfo_t *buf); + +/** + * @brief 设置编解码器的控制参数 + * @param [in] handle : Codec handle + * @param [in] param : 编解码器控制参数 + * @retval 0 成功 + * @retval 非0 失败 + */ +IHAL_INT32 IHal_Codec_Control(IHal_CodecHandle_t *handle, IHal_CodecControlParam_t *param); + +/** + * @} + */ + +/** + * @} + */ + +#endif // __CODEC_H__ diff --git a/hardware/chip/x2000/hal/vcodec/felix/felix.c b/hardware/chip/x2000/hal/vcodec/felix/felix.c new file mode 100644 index 0000000000000000000000000000000000000000..2876ff01223fc2137e5d0fa80a4ac802e7af160b --- /dev/null +++ b/hardware/chip/x2000/hal/vcodec/felix/felix.c @@ -0,0 +1,114 @@ +//#include "x2000_hal.h" +#include "x2000_ll_felix.h" +#include "x2000_hal_felix.h" +#include "aos/kernel.h" +#include +#include + + +extern void ingenic_vcodec_felix_work_task(void *data); +#define VCODEC_TASK_PRIORITY 30 +#define VCODEC_TASK_STACK_SIZE 8192 + +int felix_task_create(void *data) +{ + int ret = 0; + struct ingenic_vdec_ctx *ctx = (struct ingenic_vdec_ctx *)data; + ctx->work_task = malloc(sizeof(aos_task_t)); + aos_task_t *h264dec_task = (aos_task_t *)ctx->work_task; + ret = aos_task_new_ext(h264dec_task, "h264_decode_worker", ingenic_vcodec_felix_work_task, ctx, 8192, VCODEC_TASK_PRIORITY); + if(ret){ + printf("aos_task_new_ext failed!\n"); + return -1; + } + return ret; +} + +int felix_task_delete(void *data) +{ + int ret; + struct ingenic_vdec_ctx *ctx = (struct ingenic_vdec_ctx *)data; + aos_task_t *h264dec_task = (aos_task_t *)ctx->work_task; + + ret = aos_task_delete(h264dec_task); + if(ret) + printf("task delete failed ret: %d \n",ret); + + free(ctx->work_task); + return ret; +} +void * felix_sem_init(void *priv) +{ + int ret; + priv = NULL; + priv = malloc(sizeof(sem_t)); + sem_t *fsem = (sem_t *)priv; + ret = sem_init(fsem, 0, 0); + return (void *)fsem; +} + +int felix_sem_destory(void *priv) +{ + int ret = 0; + sem_t * fsem; + if(priv) + fsem = (sem_t *)priv; + else{ + printf("priv is NULL\n"); + return ret; + } + ret = sem_destroy(fsem); + free(priv); + priv = NULL; + return ret; +} + +int felix_sem_wait(void *priv) +{ + int ret; + sem_t *fsem = (sem_t *)priv; + ret = sem_wait(fsem); + return ret; +} + +int felix_sem_trywait(void *priv) +{ + int ret; + sem_t *fsem = (sem_t *)priv; + ret = sem_trywait(fsem); + return ret; +} + +int felix_sem_timedwait(void *priv, unsigned int timeout_ms) +{ + int ret; + sem_t *fsem = (sem_t *)priv; + + struct timespec sem_timeout; + struct timeval tv; + gettimeofday(&tv, NULL); + + sem_timeout.tv_sec = tv.tv_sec + timeout_ms / 1000; + sem_timeout.tv_nsec = tv.tv_usec * 1000 + (timeout_ms % 1000) * 1000000; + ret = sem_timedwait(fsem, &sem_timeout); + + return ret; +} + +int felix_sem_post(void *priv) +{ + int ret; + sem_t *fsem = (sem_t *)priv; + ret = sem_post(fsem); + return ret; +} + + +struct sem_ops felix_sem_ops = { + .sem_init = felix_sem_init, + .sem_destroy = felix_sem_destory, + .sem_wait = felix_sem_wait, + .sem_trywait = felix_sem_trywait, + .sem_timedwait = felix_sem_timedwait, + .sem_post = felix_sem_post, +}; diff --git a/hardware/chip/x2000/hal/vcodec/impp.h b/hardware/chip/x2000/hal/vcodec/impp.h new file mode 100755 index 0000000000000000000000000000000000000000..a906f81b1a4984a2fd89b421c92a3c7a54ccd668 --- /dev/null +++ b/hardware/chip/x2000/hal/vcodec/impp.h @@ -0,0 +1,163 @@ +/** + * @file impp.h + * @author ingenic-team + * @brief + * @version 0.1 + * @date 2021-12-02 + * + * @copyright Copyright ingenic (c) 2021 + * + */ + +#ifndef __IMPP_H__ +#define __IMPP_H__ + +/** + * @defgroup group_IMPP 通用数据类型定义 + * @{ + */ + +#define IHAL_ROK 0 +#define IHAL_RERR 1 +#define IHAL_RFAILED 2 +#define IHAL_RNULL NULL + + +/* impp wait type */ +#define IMPP_NO_WAIT 0 /*!< 非阻塞等待 */ +#define IMPP_WAIT_FOREVER 0xFFFFFFFF /*!< 阻塞等待 */ + +typedef char IHAL_INT8; +typedef unsigned char IHAL_UINT8; +typedef short IHAL_INT16; +typedef unsigned short IHAL_UINT16; +typedef int IHAL_INT32; +typedef unsigned int IHAL_UINT32; +typedef long long IHAL_INT64; +typedef unsigned long long IHAL_UINT64; + + +/** + * @brief 像素格式 + */ +typedef enum { + IMPP_PIX_FMT_NV12, + IMPP_PIX_FMT_NV21, + IMPP_PIX_FMT_NV16, + IMPP_PIX_FMT_YUV422, + IMPP_PIX_FMT_YUV422P, + IMPP_PIX_FMT_I420, + IMPP_PIX_FMT_I422, + IMPP_PIX_FMT_YUV420p, + IMPP_PIX_FMT_RAW8, + IMPP_PIX_FMT_RAW10, + IMPP_PIX_FMT_RGBA_8888, + IMPP_PIX_FMT_RGBX_8888, + IMPP_PIX_FMT_BGRA_8888, + IMPP_PIX_FMT_BGRX_8888, + IMPP_PIX_FMT_ABGR_8888, + IMPP_PIX_FMT_ARGB_8888, + IMPP_PIX_FMT_RGB_888, + IMPP_PIX_FMT_BGR_888, + IMPP_PIX_FMT_RGB_565, + IMPP_PIX_FMT_RGB_555, + IMPP_PIX_FMT_RGBA_5551, + IMPP_PIX_FMT_BGRA_5551, + IMPP_PIX_FMT_ARGB_1555, + IMPP_PIX_FMT_HSV, + + /* Camera Raw8 */ + IMPP_PIX_FMT_SBGGR8, + IMPP_PIX_FMT_SGBRG8, + IMPP_PIX_FMT_SGRBG8, + IMPP_PIX_FMT_SRGGB8, + + /* Camera Raw10 */ + IMPP_PIX_FMT_SBGGR10, + IMPP_PIX_FMT_SGBRG10, + IMPP_PIX_FMT_SGRBG10, + IMPP_PIX_FMT_SRGGB10, + + /* Camera Raw12 */ + IMPP_PIX_FMT_SBGGR12, + IMPP_PIX_FMT_SGBRG12, + IMPP_PIX_FMT_SGRBG12, + IMPP_PIX_FMT_SRGGB12, + + /* Y only.*/ + IMPP_PIX_FMT_GREY, + IMPP_PIX_FMT_Y4, + IMPP_PIX_FMT_Y6, + IMPP_PIX_FMT_Y12, + IMPP_PIX_FMT_Y16, + + /* YUV422. */ + IMPP_PIX_FMT_YUYV, + IMPP_PIX_FMT_YYUV, + IMPP_PIX_FMT_YVYU, + IMPP_PIX_FMT_VYUY, + +} IMPP_PIX_FMT; + + +/** + * @brief 采样格式 + */ +typedef enum { + IMPP_SAMPLE_FMT_S8, /*!< 有符号8位采样 */ + IMPP_SAMPLE_FMT_U8, /*!< 无符号8位采样 */ + IMPP_SAMPLE_FMT_S16, /*!< 有符号16位采样 */ + IMPP_SAMPLE_FMT_U16, /*!< 无符号16位采样 */ + IMPP_SAMPLE_FMT_S24, /*!< 有符号24位采样 */ + IMPP_SAMPLE_FMT_U24, /*!< 无符号24位采样 */ + IMPP_SAMPLE_FMT_S32, /*!< 有符号32位采样 */ + IMPP_SAMPLE_FMT_U32, /*!< 无符号32位采样 */ +} IMPP_SAMPLE_FMT_t; + +/** + * @brief 缓冲区类型 + */ +typedef enum __impp_buffer_type { + IMPP_INTERNAL_BUFFER, /*!< 内部缓冲区 */ + IMPP_EXT_DMABUFFER, /*!< 外部dma-buf */ + IMPP_EXT_USERBUFFER, /*!< 外部用户空间缓冲区 */ +} IMPP_BUFFER_TYPE; + + +/** + * @brief 帧信息 + */ +typedef struct { + IHAL_INT32 fd; /*!< 用于dma-buf */ + IHAL_INT32 width; /*!< 宽度 */ + IHAL_INT32 height; /*!< 高度 */ + IHAL_UINT32 paddr; /*!< 物理地址 */ + IHAL_UINT32 vaddr; /*!< 虚拟地址 */ + IHAL_UINT32 size; /*!< 帧大小 */ + IMPP_PIX_FMT fmt; /*!< 像素格式 */ + IHAL_INT32 index; +} IMPP_FrameInfo_t; + +/** + * @brief 缓冲区信息 + */ +typedef struct { + IHAL_INT32 fd; /*!< 用于dma-buf */ + IHAL_UINT32 paddr; /*!< 物理地址 */ + IHAL_UINT32 vaddr; /*!< 虚拟地址 */ + IHAL_UINT32 size; /*!< 缓冲区大小 */ + IHAL_UINT32 byteused; + IHAL_INT32 index; + struct { + IHAL_INT32 numPlanes; + IHAL_INT32 fd[3]; + IHAL_UINT32 vaddr[3]; + IHAL_UINT32 len[3]; + } mplane; +} IMPP_BufferInfo_t; + +/** + * @} + */ + +#endif // __IMPP_H__ diff --git a/hardware/chip/x2000/package.yaml b/hardware/chip/x2000/package.yaml index 068e01306b0c16641a641ca4d2c1cb79cafbf03f..2500639ea5bdb5441f1f64724f033a4ec9f1b730 100644 --- a/hardware/chip/x2000/package.yaml +++ b/hardware/chip/x2000/package.yaml @@ -67,6 +67,8 @@ build_config: - libbare-cpu/cpu/core/include/ - libbare-cpu/cpu/soc-x2000/include/ ? - libbare-cpu/drivers/drivers-x2000/include/ + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/ + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/include #- newlib/mips-sde-elf/include/c++/7.2.0 #- newlib/mips-sde-elf/include/c++/7.2.0/mips-sde-elf #- newlib/mips-sde-elf/include/c++/7.2.0/backward @@ -134,6 +136,10 @@ source_file: - hal/lcd/drv_dpu.c ? - hal/lcd/display/fw050.c ? - hal/screentouch/ft6236.c ? +#h264dec + - hal/vcodec/drv_codec.c ? + - hal/vcodec/felix/felix.c ? + - libbare-cpu/cpu/core/traps.c - libbare-cpu/cpu/core/spinlock.c - libbare-cpu/cpu/core/porting_aos/genex.S @@ -160,15 +166,37 @@ source_file: - libbare-cpu/drivers/drivers-x2000/src/x2000_hal_adc.c ? - libbare-cpu/drivers/drivers-x2000/src/x2000_hal_pwm.c ? - libbare-cpu/drivers/drivers-x2000/src/x2000_hal_gmac.c ? - - libbare-cpu/drivers/drivers-x2000/src/x2000_ll_sfcnor.c ? - - libbare-cpu/drivers/drivers-x2000/src/x2000_hal_sfcnor.c ? + - libbare-cpu/drivers/drivers-x2000/src/x2000_ll_sfc.c ? + - libbare-cpu/drivers/drivers-x2000/src/x2000_hal_sfc.c ? - libbare-cpu/drivers/drivers-x2000/src/x2000_ll_mipi_dsi.c ? - libbare-cpu/drivers/drivers-x2000/src/x2000_hal_mipi_dsi.c ? - libbare-cpu/drivers/drivers-x2000/src/x2000_hal_lcd.c ? +#h264dec + - libbare-cpu/drivers/drivers-x2000/src/x2000_ll_felix.c ? + - libbare-cpu/drivers/drivers-x2000/src/x2000_hal_felix.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/api/jzm_h264_dec.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/buffer.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/golomb.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h2645_parse.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264_direct.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264_parse.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264_picture.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264_ps.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264_refs.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264_sei.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264_slice.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264data.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/h264dec.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/log.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/mathtables.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/mem.c ? + - libbare-cpu/drivers/drivers-x2000/src/felix/libh264/src/vpu_ops.c ? + - drivers/eth_lwip.c ? - example/rtc/rtc_example.c ? - example/touch/touch_example.c ? - example/gpio/hal_gpio_test.c ? + - example/vcodec/h264dec_test.c ? ## 第五部分:配置信息 # def_config: # 组件的可配置项 @@ -209,6 +237,8 @@ def_config: CONFIG_SPI_ENABLE: 0 # AUDIO CONFIG_AUDIO_ENABLE: 0 +#FELIX + CONFIG_FELIX_ENABLE: 1 # LCD CONFIG_LCD_KD050: 0 CONFIG_LCD_FW050: 0 @@ -220,7 +250,7 @@ def_config: CONFIG_TOUCH_ENABLE: 0 #依赖I2C组件 # FLASH CONFIG_U_FLASH_CORE: 1 - CONFIG_FLASH_ENABLE: 0 + CONFIG_FLASH_ENABLE: 1 # SDHC CONFIG_SDHC_ENABLE: 0 # ETH NETIF @@ -228,12 +258,12 @@ def_config: ################# components ################# # CLI - CLI_IOBOX_ENABLE: 0 #启用CLI命令,将自动配置依赖组件LFS + CLI_IOBOX_ENABLE: 1 #启用CLI命令,将自动配置依赖组件LFS CLI_CONFIG_STACK_SIZE : 8192 # Littlefs CONFIG_LFS_MOUNTPOINT: "/data" #LFS挂载目录 CONFIG_LITTLEFS_CNT: 1 #LFS占用的分区数量 - CONFIG_LFS_ENABLE: 0 #使用前需要设置CONFIG_FLASH_ENABLE + CONFIG_LFS_ENABLE: 1 #使用前需要设置CONFIG_FLASH_ENABLE # LWIP CONFIG_NO_LWIP: 1 CONFIG_LWIP_VERSION: "lwip2.0.0"