u-boot: weekly rls 2024.05.22

- bf9a0a

Change-Id: I0d8f19b2dfb78faf564af12d311557ac18b74c4d
This commit is contained in:
sophgo-forum-service
2024-05-27 17:20:20 +08:00
committed by carbon
parent 86e0edc820
commit 17580ae06a
27 changed files with 10816 additions and 0 deletions

View File

@ -0,0 +1,50 @@
#include <stdlib.h>
#include <common.h>
#include <command.h>
extern int jpeg_decoder(void *bs_addr, void *yuv_addr, int size);
extern int get_jpeg_size(int *width_addr, int *height_addr);
static int do_cvi_jpeg_dec(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
{
char *bs_addr = NULL;
char *yuv_addr = NULL;
int size = 0;
if (argc != 4) {
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
}
bs_addr = (char *)simple_strtol(argv[1], NULL, 16);
if (!bs_addr) {
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
}
yuv_addr = (char *)simple_strtol(argv[2], NULL, 16);
if (!yuv_addr) {
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
}
size = (int)simple_strtol(argv[3], NULL, 16);
if (!size) {
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
}
printf("\nstart jpeg dec task!, bs_addr %p, yuv_addr %p, size %d\n", bs_addr, yuv_addr, size);
jpeg_decoder(bs_addr, yuv_addr, size);
get_jpeg_size((int *)(bs_addr + size - 8), (int *)(bs_addr + size - 4));
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(cvi_jpeg_dec, 4, 0, do_cvi_jpeg_dec, "Jpeg decoder ", "\n"
);

View File

@ -0,0 +1 @@
obj-$(CONFIG_CMD_CVI_JPEG) += mm.o jdi.o jpuapifunc.o jpeg.o jpuhelper.o jdi_osal.o jpuapi.o jpurun.o mixer.o

View File

@ -0,0 +1,48 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__)
# define PLATFORM_WIN32
#elif defined(linux) || defined(__linux) || defined(ANDROID)
# define PLATFORM_LINUX
#else
# define PLATFORM_NON_OS
#endif
#if defined(_MSC_VER)
# include <windows.h>
# include <conio.h>
# define inline _inline
# define VPU_DELAY_MS(X) Sleep(X)
//should change to delay function which can be delay a microsecond unut.
# define VPU_DELAY_US(X) Sleep(X)
# define kbhit _kbhit
# define getch _getch
#elif defined(__GNUC__)
#ifdef _KERNEL_
# define VPU_DELAY_MS(X) udelay((X) * 1000)
# define VPU_DELAY_US(X) udelay(X)
#else
# define VPU_DELAY_MS(X) usleep((X) * 1000)
# define VPU_DELAY_US(X) usleep(X)
#endif
#elif defined(__ARMCC__)
#else
# error "Unknown compiler."
#endif
#define PROJECT_ROOT "..\\..\\..\\"
#if defined(JPU_FPGA_PLATFORM)
#if defined(ANDROID) || defined(linux)
#else
#define SUPPORT_CONF_TEST
#endif
#endif
#define API_VERSION 165
#define HAVE_STDIN_H 1
//#define MJPEG_ERROR_CONCEAL
#endif /* __CONFIG_H__ */

View File

@ -0,0 +1,54 @@
/*
* Copyright CviTek Inc.
*
* Created Time: Feb, 2020
*/
#ifndef __CVI_JPEG_CFG_H__
#define __CVI_JPEG_CFG_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define BM_DBG_MSG_ENABLE
#define BM_MASK_ERR 0x1
#define BM_MASK_FLOW 0x2
#define BM_MASK_MEM 0x4
#define BM_MASK_TRACE 0x10
#define BM_MASK_PERF 0x20
#define BM_MASK_ALL 0xFFFF
#ifdef BM_DBG_MSG_ENABLE
#define BM_DBG_ERR(msg, ...) if (jpu_level & BM_MASK_ERR)\
{ printf("[ERR] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); }
#define BM_DBG_FLOW(msg, ...) if (jpu_level & BM_MASK_FLOW)\
{ printf("[FLOW] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); }
#define BM_DBG_MEM(msg, ...) if (jpu_level & BM_MASK_MEM)\
{ printf("[MEM] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); }
#define BM_DBG_TRACE(msg, ...) if (jpu_level & BM_MASK_TRACE)\
{ printf("[TRACE] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); }
#define BM_DBG_PERF(msg, ...) if (jpu_level & BM_MASK_PERF)\
{ printf("[PERF] %s = %d, " msg, __func__, __LINE__, ## __VA_ARGS__); }
extern int jpu_level;
#else
#define BM_DBG_ERR(msg, ...)
#define BM_DBG_FLOW(msg, ...)
#define BM_DBG_MEM(msg, ...)
#define BM_DBG_TRACE(msg, ...)
#define BM_DBG_PERF(msg, ...)
#endif
//#define PROFILE_PERFORMANCE
#define JPEG_CODEC_INTR_NUM 75
//#define SUPPORT_INTERRUPT
#ifdef SUPPORT_INTERRUPT
int irq_handler_jpeg_codec(int irqn, void *priv);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -0,0 +1,537 @@
#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__)
#elif defined(linux) || defined(__linux) || defined(ANDROID)
#include <malloc.h>
#include "jdi.h"
#include "jpulog.h"
#include "jdi_osal.h"
#include "dm/device.h"
#include "timer.h"
#include "asm/cache.h"
#define JPU_BIT_REG_SIZE 0x1000
#define JPU_BIT_REG_BASE (0x0B000000)
/*
* DRAM Total Size = 256MB = 0x10000000
* DRAM_PHYSICAL_BASE = 0x100000000
| Offset | Size | Note
* System | 0x100000000 | 0x2000000 | 32MB
* System Mem | 0x102000000 | 0x4000000 | 64MB
* File Buf | 0x106000000 | 0x2000000 | 32MB
* Enc BS | 0x108000000 | 0x1000000 | 16MB
* ENC SRC | 0x10C000000 | 0x1000000 | 16MB
* LOAD SRC | 0x10D000000
*/
//#define SYSTEM_SIZE 0x2000000
#define JDI_DRAM_PHYSICAL_BASE (0x130000000)
#define JDI_DRAM_PHYSICAL_SIZE 0x00200000 //0x004000000
#define JDI_SYSTEM_ENDIAN JDI_LITTLE_ENDIAN
#define SPM_MEM_PHYSICAL_BASE 0x140000000
#define SPM_MEM_PHYSICAL_SIZE 0xC0000000
typedef struct jpu_buffer_t jpudrv_buffer_t;
typedef struct jpu_buffer_pool_t {
jpudrv_buffer_t jdb;
int inuse;
} jpu_buffer_pool_t;
static int s_jpu_fd;
static jpu_instance_pool_t *s_pjip;
static jpu_instance_pool_t s_jip;
static int s_task_num;
static int s_clock_state;
static jpudrv_buffer_t s_jdb_video_memory;
static jpudrv_buffer_t s_jdb_register;
static jpu_buffer_pool_t s_jpu_buffer_pool[MAX_JPU_BUFFER_POOL];
static int s_jpu_buffer_pool_count;
static int jpu_swap_endian(unsigned char *data, int len, int endian);
int jdi_probe(void)
{
int ret;
ret = jdi_init();
jdi_release();
return ret;
}
int jdi_init(void)
{
int ret;
void *buf = NULL;
if (s_jpu_fd != -1 && s_jpu_fd != 0x00) {
s_task_num++;
return 0;
}
s_jpu_fd = 1;
memset((void *)&s_jpu_buffer_pool, 0x00, sizeof(jpu_buffer_pool_t) * MAX_JPU_BUFFER_POOL);
s_jpu_buffer_pool_count = 0;
s_pjip = jdi_get_instance_pool();
if (!s_pjip) {
JLOG(ERR, "[jdi] fail to create instance pool for saving context\n");
goto ERR_JDI_INIT;
}
buf = malloc(JDI_DRAM_PHYSICAL_SIZE);
if (buf) {
s_jdb_video_memory.phys_addr = (unsigned long)buf;
s_jdb_video_memory.size = JDI_DRAM_PHYSICAL_SIZE;
JLOG(INFO, "alloc s_jdb_video_memory.phys_addr buf %p\n", buf);
} else {
JLOG(ERR, "alloc s_jdb_video_memory.phys_addr failed\n");
goto ERR_JDI_INIT;
}
if (!s_pjip->instance_pool_inited) {
memset(&s_pjip->vmem, 0x00, sizeof(jpeg_mm_t));
ret = jmem_init(&s_pjip->vmem, (unsigned long)s_jdb_video_memory.phys_addr, s_jdb_video_memory.size);
if (ret < 0) {
JLOG(ERR, "[JDI] fail to init jpu memory management logic\n");
goto ERR_JDI_INIT;
}
}
s_jdb_register.phys_addr = JPU_BIT_REG_BASE;
s_jdb_register.virt_addr = JPU_BIT_REG_BASE;
s_jdb_register.size = JPU_BIT_REG_SIZE;
jdi_set_clock_gate(1);
s_task_num++;
JLOG(INFO, "[jdi] success to init driver\n");
return s_jpu_fd;
ERR_JDI_INIT:
jdi_release();
return -1;
}
int jdi_release(void)
{
if (s_jpu_fd == -1 || s_jpu_fd == 0x00)
return 0;
if (jdi_lock() < 0) {
JLOG(ERR, "[jdi] fail to handle lock function\n");
return -1;
}
if (s_task_num > 1) {// means that the opened instance remains
s_task_num--;
jdi_unlock();
return 0;
}
if (s_jdb_video_memory.phys_addr) {
JLOG(INFO, "free s_jdb_video_memory.phys_addr buf %p\n", (void *)s_jdb_video_memory.phys_addr);
free((void *)s_jdb_video_memory.phys_addr);
}
s_task_num--;
jmem_exit(&s_pjip->vmem);
memset(&s_jdb_register, 0x00, sizeof(jpudrv_buffer_t));
if (s_jpu_fd != -1 && s_jpu_fd != 0x00)
s_jpu_fd = -1;
s_pjip = NULL;
jdi_unlock();
return 0;
}
jpu_instance_pool_t *jdi_get_instance_pool(void)
{
if (!s_pjip) {
s_pjip = &s_jip;
memset(s_pjip, 0x00, sizeof(jpu_instance_pool_t));
}
return (jpu_instance_pool_t *)s_pjip;
}
int jdi_open_instance(unsigned long instIdx)
{
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return -1;
s_pjip->jpu_instance_num++;
return 0;
}
int jdi_close_instance(unsigned long instIdx)
{
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return -1;
s_pjip->jpu_instance_num--;
return 0;
}
int jdi_get_instance_num(void)
{
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return -1;
return s_pjip->jpu_instance_num;
}
int jdi_hw_reset(void)
{
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return -1;
// to do any action for hw reset
return 0;
}
int jdi_lock(void)
{
return 0;
}
void jdi_unlock(void)
{
}
void jdi_write_register(unsigned int addr, unsigned int data)
{
unsigned long reg_addr;
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return;
reg_addr = addr + (unsigned long)s_jdb_register.virt_addr;
*(unsigned int *)reg_addr = data;
flush_dcache_range(reg_addr, reg_addr + sizeof(unsigned int));
// flush_dcache_all();
}
unsigned int jdi_read_register(unsigned int addr)
{
unsigned long reg_addr;
reg_addr = addr + (unsigned long)s_jdb_register.virt_addr;
// INV_DCACHE_RANGE((unsigned int)reg_addr, sizeof(unsigned int));
// invalidate_dcache_all();
invalidate_dcache_range(reg_addr, reg_addr + sizeof(unsigned int));
return *(unsigned int *)reg_addr;
}
int jdi_write_memory(unsigned long addr, unsigned char *data, int len, int endian)
{
jpudrv_buffer_t jdb = {0, };
unsigned long offset;
int i;
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return -1;
for (i = 0; i < MAX_JPU_BUFFER_POOL; i++) {
if (s_jpu_buffer_pool[i].inuse == 1) {
jdb = s_jpu_buffer_pool[i].jdb;
if (addr >= jdb.phys_addr && addr < (jdb.phys_addr + jdb.size))
break;
}
}
if (!jdb.size) {
JLOG(ERR, "address 0x%08lx is not mapped address!!!\n", addr);
return -1;
}
offset = addr - (unsigned long)jdb.phys_addr;
jpu_swap_endian(data, len, endian);
//by zhao for cache testing
OSAL_MEMCPY((void *)((unsigned long)jdb.virt_addr + offset), (void *)data, len);
//josal_memcpy_nocache((void *)((unsigned long)jdb.virt_addr+offset), (void *)data, len);
return len;
}
int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian)
{
jpudrv_buffer_t jdb = {0};
unsigned long offset;
int i;
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return -1;
for (i = 0; i < MAX_JPU_BUFFER_POOL; i++) {
if (s_jpu_buffer_pool[i].inuse == 1) {
jdb = s_jpu_buffer_pool[i].jdb;
if (addr >= jdb.phys_addr && addr < (jdb.phys_addr + jdb.size))
break;
}
}
if (!jdb.size)
return -1;
offset = addr - (unsigned long)jdb.phys_addr;
INV_DCACHE_RANGE(((unsigned long)jdb.virt_addr + offset), len);
OSAL_MEMCPY(data, (const void *)((unsigned long)jdb.virt_addr + offset), len);
jpu_swap_endian(data, len, endian);
return len;
}
int jdi_allocate_dma_memory(jpu_buffer_t *vb)
{
int i;
unsigned long offset;
jpudrv_buffer_t jdb = {0, };
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return -1;
jdb.size = vb->size;
jdb.phys_addr = (unsigned long)jmem_alloc(&s_pjip->vmem, jdb.size, 0);
if (jdb.phys_addr == (unsigned long)-1)
return -1; // not enough memory
offset = (unsigned long)(jdb.phys_addr - s_jdb_video_memory.phys_addr);
jdb.base = (unsigned long)s_jdb_video_memory.base + offset;
jdb.virt_addr = jdb.phys_addr;
vb->phys_addr = (unsigned long)jdb.phys_addr;
vb->base = (unsigned long)jdb.base;
vb->virt_addr = (unsigned long)vb->phys_addr;
for (i = 0; i < MAX_JPU_BUFFER_POOL; i++) {
if (s_jpu_buffer_pool[i].inuse == 0) {
s_jpu_buffer_pool[i].jdb = jdb;
s_jpu_buffer_pool_count++;
s_jpu_buffer_pool[i].inuse = 1;
break;
}
}
return 0;
}
void jdi_free_dma_memory(jpu_buffer_t *vb)
{
int i;
// int ret = 0;
jpudrv_buffer_t jdb = {0, };
if (!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
return;
if (vb->size == 0)
return;
for (i = 0; i < MAX_JPU_BUFFER_POOL; i++) {
if (s_jpu_buffer_pool[i].jdb.phys_addr == vb->phys_addr) {
s_jpu_buffer_pool[i].inuse = 0;
s_jpu_buffer_pool_count--;
jdb = s_jpu_buffer_pool[i].jdb;
break;
}
}
if (!jdb.size) {
JLOG(ERR, "[JDI] invalid buffer to free address = 0x%x\n", (int)jdb.virt_addr);
return;
}
jmem_free(&s_pjip->vmem, (unsigned long)jdb.phys_addr, 0);
memset(vb, 0, sizeof(jpu_buffer_t));
}
int jdi_set_clock_gate(int enable)
{
s_clock_state = enable;
return 0;
}
int jdi_get_clock_gate(void)
{
return s_clock_state;
}
static int intr_reason;
int irq_handler_jpeg_codec(int irqn, void *priv)
{
int curr_int = 0;
#ifdef PROFILE_PERFORMANCE
int ms;
ms = timer_meter_get_ms();
BM_DBG_PERF("time = %d ms\n", ms);
#endif
curr_int = jdi_read_register(MJPEG_PIC_STATUS_REG);
intr_reason |= curr_int;
BM_DBG_TRACE("curr_int = 0x%X, intr_reason = 0x%X\n", curr_int, intr_reason);
JpuWriteReg(MJPEG_PIC_STATUS_REG, curr_int);
return 0;
}
int jdi_wait_interrupt(int timeout)
{
#ifdef SUPPORT_INTERRUPT
int out_reason = 0;
while (1) {
BM_DBG_TRACE("intr_reason = 0x%X\n", intr_reason);
out_reason = intr_reason;
if (out_reason) {
int int_en = jdi_read_register(MJPEG_INTR_MASK_REG);
JpuWriteReg(MJPEG_INTR_MASK_REG, 0);
intr_reason &= (~out_reason);
BM_DBG_TRACE("out_reason = 0x%X\n", out_reason);
JpuWriteReg(MJPEG_INTR_MASK_REG, int_en);
break;
}
}
return out_reason;
#else
while (1) {
if (jdi_read_register(MJPEG_PIC_STATUS_REG))
break;
//Sleep(1); // 1ms sec
//if (count++ > timeout)
// return -1;
}
return 0;
#endif
}
void jdi_log(int cmd, int step)
{
int i;
switch (cmd) {
case JDI_LOG_CMD_PICRUN:
if (step == 1) {
JLOG(INFO, "\n**PIC_RUN start\n");
} else {
JLOG(INFO, "\n**PIC_RUN end\n");
}
break;
}
for (i = 0; i <= 0x238; i = i + 16) {
JLOG(INFO, "0x%04xh: 0x%08x 0x%08x 0x%08x 0x%08x\n", i,
jdi_read_register(i), jdi_read_register(i + 4),
jdi_read_register(i + 8), jdi_read_register(i + 0xc));
}
}
int jpu_swap_endian(unsigned char *data, int len, int endian)
{
unsigned long *p;
unsigned long v1, v2, v3;
int i;
int swap = 0;
p = (unsigned long *)data;
if (endian == JDI_SYSTEM_ENDIAN)
swap = 0;
else
swap = 1;
if (swap) {
if (endian == JDI_LITTLE_ENDIAN || endian == JDI_BIG_ENDIAN) {
for (i = 0; i < len / 4; i += 2) {
v1 = p[i];
v2 = (v1 >> 24) & 0xFF;
v2 |= ((v1 >> 16) & 0xFF) << 8;
v2 |= ((v1 >> 8) & 0xFF) << 16;
v2 |= ((v1 >> 0) & 0xFF) << 24;
v3 = v2;
v1 = p[i + 1];
v2 = (v1 >> 24) & 0xFF;
v2 |= ((v1 >> 16) & 0xFF) << 8;
v2 |= ((v1 >> 8) & 0xFF) << 16;
v2 |= ((v1 >> 0) & 0xFF) << 24;
p[i] = v2;
p[i + 1] = v3;
}
} else {
int sys_endian = JDI_SYSTEM_ENDIAN;
int swap4byte = 0;
swap = 0;
if (endian == JDI_32BIT_LITTLE_ENDIAN) {
if (sys_endian == JDI_BIG_ENDIAN) {
swap = 1;
}
} else {
if (sys_endian == JDI_BIG_ENDIAN) {
swap4byte = 1;
} else if (sys_endian == JDI_LITTLE_ENDIAN) {
swap4byte = 1;
swap = 1;
} else {
swap = 1;
}
}
if (swap) {
for (i = 0; i < len / 4; i++) {
v1 = p[i];
v2 = (v1 >> 24) & 0xFF;
v2 |= ((v1 >> 16) & 0xFF) << 8;
v2 |= ((v1 >> 8) & 0xFF) << 16;
v2 |= ((v1 >> 0) & 0xFF) << 24;
p[i] = v2;
}
}
if (swap4byte) {
for (i = 0; i < len / 4; i += 2) {
v1 = p[i];
v2 = p[i + 1];
p[i] = v2;
p[i + 1] = v1;
}
}
}
}
return swap;
}
#endif

View File

@ -0,0 +1,118 @@
#ifndef _JDI_HPI_H_
#define _JDI_HPI_H_
#include <stdlib.h>
//#include <string.h>
#include "jpuconfig.h"
#include "regdefine.h"
#include "mm.h"
#include "jdi_osal.h"
#define MAX_JPU_BUFFER_POOL 32
#define JpuWriteReg(ADDR, DATA) jdi_write_register(ADDR, DATA) // system register write
#define JpuReadReg(ADDR) jdi_read_register(ADDR) // system register write
#define JpuWriteMem(ADDR, DATA, LEN, ENDIAN) jdi_write_memory(ADDR, DATA, LEN, ENDIAN) // system memory write
#define JpuReadMem(ADDR, DATA, LEN, ENDIAN) jdi_read_memory(ADDR, DATA, LEN, ENDIAN) // system memory write
typedef struct jpu_buffer_t {
unsigned int size;
unsigned long phys_addr;
unsigned long base;
unsigned long virt_addr;
} jpu_buffer_t;
typedef struct jpu_instance_pool_t {
unsigned char jpgInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE];
void *jpu_mutex;
int jpu_instance_num;
int instance_pool_inited;
void *pendingInst;
jpeg_mm_t vmem;
} jpu_instance_pool_t;
#ifdef SUPPORT_128BIT_BUS
typedef enum {
JDI_128BIT_LITTLE_64BIT_LITTLE_ENDIAN = ((0 << 2) + (0 << 1) + (0 << 0)), //128 bit little, 64 bit little
JDI_128BIT_BIG_64BIT_LITTLE_ENDIAN = ((1 << 2) + (0 << 1) + (0 << 0)), //128 bit big , 64 bit little
JDI_128BIT_LITTLE_64BIT_BIG_ENDIAN = ((0 << 2) + (0 << 1) + (1 << 0)), //128 bit little, 64 bit big
JDI_128BIT_BIG_64BIT_BIG_ENDIAN = ((1 << 2) + (0 << 1) + (1 << 0)), //128 bit big, 64 bit big
JDI_128BIT_LITTLE_32BIT_LITTLE_ENDIAN = ((0 << 2) + (1 << 1) + (0 << 0)), //128 bit little, 32 bit little
JDI_128BIT_BIG_32BIT_LITTLE_ENDIAN = ((1 << 2) + (1 << 1) + (0 << 0)), //128 bit big , 32 bit little
JDI_128BIT_LITTLE_32BIT_BIG_ENDIAN = ((0 << 2) + (1 << 1) + (1 << 0)), //128 bit little, 32 bit big
JDI_128BIT_BIG_32BIT_BIG_ENDIAN = ((1 << 2) + (1 << 1) + (1 << 0)), //128 bit big, 32 bit big
} EndianMode;
#define JDI_LITTLE_ENDIAN JDI_128BIT_LITTLE_64BIT_LITTLE_ENDIAN
#define JDI_BIG_ENDIAN JDI_128BIT_BIG_64BIT_BIG_ENDIAN
#ifndef BIT(x)
#define BIT(x) (1 << (x))
#endif
#define JDI_128BIT_ENDIAN_MASK BIT(2)
#define JDI_64BIT_ENDIAN_MASK BIT(1)
#define JDI_ENDIAN_MASK BIT(0)
#define JDI_32BIT_LITTLE_ENDIAN JDI_128BIT_LITTLE_32BIT_LITTLE_ENDIAN
#define JDI_32BIT_BIG_ENDIAN JDI_128BIT_LITTLE_32BIT_BIG_ENDIAN
#else
typedef enum {
JDI_LITTLE_ENDIAN = 0,
JDI_BIG_ENDIAN,
JDI_32BIT_LITTLE_ENDIAN,
JDI_32BIT_BIG_ENDIAN,
} EndianMode;
#endif
typedef enum {
JDI_LOG_CMD_PICRUN = 0,
JDI_LOG_CMD_MAX
} jdi_log_cmd;
#if defined(__cplusplus)
extern "C" {
#endif
int jdi_probe(void);
int jdi_init(void);
int jdi_release(void); //this function may be called only at system off.
jpu_instance_pool_t *jdi_get_instance_pool(void);
int jdi_allocate_dma_memory(jpu_buffer_t *vb);
void jdi_free_dma_memory(jpu_buffer_t *vb);
int jdi_wait_interrupt(int timeout);
int jdi_hw_reset(void);
int jdi_set_clock_gate(int enable);
int jdi_get_clock_gate(void);
int jdi_open_instance(unsigned long instIdx);
int jdi_close_instance(unsigned long instIdx);
int jdi_get_instance_num(void);
void jdi_write_register(unsigned int addr, unsigned int data);
unsigned int jdi_read_register(unsigned int addr);
int jdi_write_memory(unsigned long addr, unsigned char *data, int len, int endian);
int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian);
int jdi_lock(void);
void jdi_unlock(void);
void jdi_log(int cmd, int step);
#ifdef JPU_FPGA_PLATFORM
#define HPI_SET_TIMING_MAX 1000
int jdi_set_timing_opt(void);
int jdi_set_clock_freg(int Device, int OutFreqMHz, int InFreqMHz);
#endif
int getch(void);
int kbhit(void);
#if defined(__cplusplus)
}
#endif
#endif //#ifndef _JDI_HPI_H_

View File

@ -0,0 +1,717 @@
//------------------------------------------------------------------------------
// File: vdi_osal.c
//
// Copyright (c) 2006, Chips & Media. All rights reserved.
//------------------------------------------------------------------------------
//#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__)
//#elif defined(linux) || defined(__linux) || defined(ANDROID)
//#else
#include <linux/string.h>
#include <stdarg.h>
#include <malloc.h>
#include "jdi.h"
#include "jdi_osal.h"
#include "asm/cache.h"
#include "jpulog.h"
#if defined(JPEG_FVP)
#define FILE_BUFFER_BASE 0xE0000000
#elif defined(JPEG_FPGA)
#define FILE_BUFFER_BASE 0x116000000
#endif
#define FILE_BUFFER_BASE 0x138000000
#define MAX_LIST_NUM 1
#define DEC_BS_FILE_BUFFER_BASE FILE_BUFFER_BASE
#define DEC_BS_FILE_BUFFER_SIZE (0x400000 * MAX_LIST_NUM)
#define DEC_YUV_FILE_BUFFER_BASE (DEC_BS_FILE_BUFFER_BASE + DEC_BS_FILE_BUFFER_SIZE)
#define DEC_YUV_FILE_BUFFER_SIZE (0x800000 * MAX_LIST_NUM)
#define ENC_YUV_FILE_BUFFER_BASE (DEC_YUV_FILE_BUFFER_BASE + DEC_YUV_FILE_BUFFER_SIZE)
#define ENC_YUV_FILE_BUFFER_SIZE (0x800000 * MAX_LIST_NUM)
#define ENC_BS_FILE_BUFFER_BASE (ENC_YUV_FILE_BUFFER_BASE + ENC_YUV_FILE_BUFFER_SIZE)
#define ENC_BS_FILE_BUFFER_SIZE (0x400000 * MAX_LIST_NUM)
#define ENC_HUFF_FILE_BUFFER_BASE (ENC_BS_FILE_BUFFER_BASE + ENC_BS_FILE_BUFFER_SIZE)
#define ENC_HUFF_FILE_BUFFER_SIZE (0x100000 * MAX_LIST_NUM)
#define ENC_QMAT_FILE_BUFFER_BASE (ENC_HUFF_FILE_BUFFER_BASE + ENC_HUFF_FILE_BUFFER_BASE)
#define ENC_QMAT_FILE_BUFFER_SIZE (0x100000 * MAX_LIST_NUM)
#define ENC_QP_FILE_BUFFER_BASE (ENC_QMAT_FILE_BUFFER_BASE + ENC_QMAT_FILE_BUFFER_SIZE)
#define ENC_QP_FILE_BUFFER_SIZE (0x100000 * MAX_LIST_NUM)
#define ENC_CFG_FILE_BUFFER_BASE (ENC_QP_FILE_BUFFER_BASE + ENC_QP_FILE_BUFFER_SIZE)
#define ENC_CFG_FILE_BUFFER_SIZE (0x10000 * MAX_LIST_NUM)
#define MULTI_FILE_BUFFER_BASE (ENC_CFG_FILE_BUFFER_BASE + ENC_CFG_FILE_BUFFER_SIZE)
#define MULTI_FILE_BUFFER_SIZE (0x10000)
#define MULTI_YUV_FILE_BUFFER_BASE (MULTI_FILE_BUFFER_BASE + MULTI_FILE_BUFFER_SIZE)
#define MULTI_YUV_FILE_BUFFER_SIZE (0x400000)
#if defined(JPEG_FVP)
#define LOG_MSG_BUF_BASE 0xD0000000
#elif defined(JPEG_FPGA)
#define LOG_MSG_BUF_BASE 0x120500000
#endif
#define LOG_MSG_BUF_BASE 0x120500000 // fixme fix me
#define LOG_MSG_BUF_SIZE 0x100000
static char *LOG_MSG_BUF = (char *)LOG_MSG_BUF_BASE;
#define MAX_MALLOC_BLOCK_SIZE 0x50000//0x200000
#define MAX_MALLOC_BLOCK_NUM 7
int jpu_level = BM_MASK_ERR;
//To
#define FILE_BUFFER_SIZE 0x1000000 * (MAX_FD_NUM - 1)
#define CMP_FILE_BUFFER_SIZE 0x1000000
unsigned char osal_malloc_heap[MAX_MALLOC_BLOCK_NUM][MAX_MALLOC_BLOCK_SIZE]; // allocate 64 4M-block for malloc
unsigned char osal_malloc_used[MAX_MALLOC_BLOCK_NUM] = {0};
typedef struct fileio_buf_t {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
} fileio_buf_t;
#define MAX_FD_NUM 5 // 0-bitstream file 1-yuv cmp file 2-
static fileio_buf_t s_file[MAX_FD_NUM] = {0};
static void myprintf(char *MsgBuf)
{
int size = strlen(MsgBuf);
if (size == 0)
return;
if (LOG_MSG_BUF + size >= (char *)(LOG_MSG_BUF_BASE + LOG_MSG_BUF_SIZE))
return;
josal_memcpy(LOG_MSG_BUF, MsgBuf, size);
LOG_MSG_BUF += size;
}
void *josal_memcpy(void *dst, const void *src, int count)
{
void *ret;
ret = memcpy(dst, src, count);
flush_dcache_range((unsigned long)dst, count);
return ret;
}
void *josal_memset(void *dst, int val, int count)
{
return memset(dst, val, count);
}
int josal_memcmp(const void *src, const void *dst, int size)
{
return memcmp(src, dst, size);
}
void *josal_malloc(int size)
{
int i;
if (size > MAX_MALLOC_BLOCK_SIZE || size == 0)
return NULL;
for (i = 0; i < MAX_MALLOC_BLOCK_NUM; i++)
if (osal_malloc_used[i] == 0)
break;
if (i < MAX_MALLOC_BLOCK_NUM) {
osal_malloc_used[i] = 1;
// JLOG(INFO, "malloc: %d, addr: 0x%p, size: %d\n", i, osal_malloc_heap[i], size);
return (void *)osal_malloc_heap[i];
}
return NULL;
}
void *josal_realloc(void *ptr, int size)
{
if (!ptr)
return josal_malloc(size);
if (size == 0 || size > MAX_MALLOC_BLOCK_SIZE) {
josal_free(ptr);
return NULL;
}
if (size <= MAX_MALLOC_BLOCK_SIZE)
return ptr;
return NULL;
}
void josal_free(void *p)
{
//free(p);
int i;
for (i = 0; i < MAX_MALLOC_BLOCK_NUM; i++)
if ((void *)osal_malloc_heap[i] == p)
break;
osal_malloc_used[i] = 0;
}
int josal_fflush(osal_file_t fp)
{
return 1;
}
int josal_feof(osal_file_t fp)
{
fileio_buf_t *p_fp = (fileio_buf_t *)fp;
if ((uint64_t)p_fp->_ptr >= p_fp->_bufsiz)
return 1;
else
return 0;
}
osal_file_t josal_fopen(const char *osal_file_tname, const char *mode)
{
int i;
for (i = 0; i < MAX_FD_NUM; i++)
if (s_file[i]._bufsiz == 0) // not used
break;
if (i == MAX_FD_NUM)
return NULL;
if (i != 1) // 1 - cmp file
s_file[i]._bufsiz = FILE_BUFFER_SIZE / (MAX_FD_NUM - 1);
else
s_file[i]._bufsiz = CMP_FILE_BUFFER_SIZE; // 256M for YUV compare file
if (i == 0)
s_file[i]._base = (char *)FILE_BUFFER_BASE;
else
s_file[i]._base = s_file[i - 1]._base + s_file[i - 1]._bufsiz;
s_file[i]._ptr = (char *)0;
for (i = 0; i < MAX_FD_NUM; i++) {
JLOG(INFO, "file = %d, base = 0x%lX, size = 0x%lX\n", i,
(unsigned long)s_file[i]._base,
(unsigned long)s_file[i]._bufsiz);
}
return &s_file[i];
}
size_t josal_fwrite(const void *p, int size, int count, osal_file_t fp)
{
long addr;
long real_size;
fileio_buf_t *p_fp = (fileio_buf_t *)fp;
if (!p_fp)
return 0;
if ((unsigned long)(size * count + p_fp->_ptr) > p_fp->_bufsiz)
real_size = p_fp->_bufsiz - (unsigned long)p_fp->_ptr;
else
real_size = size * count;
addr = (long)((long)p_fp->_base + (long)p_fp->_ptr);
josal_memcpy((void *)addr, (void *)p, real_size);
p_fp->_ptr += real_size;
JLOG(INFO, "fp: 0x%lx, size: %ld\n", addr, real_size);
return real_size;
}
size_t josal_fread(void *p, int size, int count, osal_file_t fp)
{
long addr;
long real_size;
fileio_buf_t *p_fp = (fileio_buf_t *)fp;
if (!p_fp)
return 0;
if ((unsigned long)(size * count + p_fp->_ptr) > p_fp->_bufsiz)
real_size = p_fp->_bufsiz - (unsigned long)p_fp->_ptr;
else
real_size = size * count;
addr = (long)((long)p_fp->_base + (long)p_fp->_ptr);
josal_memcpy((void *)p, (void *)addr, real_size);
p_fp->_ptr += real_size;
//printf("p_fp: _ptr = 0x%016llx _base = 0x%016llx _bufsiz = 0x%08x\n",
// (uint64_t)p_fp->_ptr, (uint64_t)p_fp->_base, p_fp->_bufsiz);
return real_size;
}
char *josal_fgets(void *p, int size, osal_file_t fp)
{
int s = josal_fread(p, 1, size, fp);
if (s == size)
return p;
else
return NULL;
}
char josal_fgetc(osal_file_t fp)
{
char *ptr;
fileio_buf_t *p_fp = (fileio_buf_t *)fp;
if (!p_fp)
return -1;
if ((unsigned long)p_fp->_ptr + sizeof(char) == p_fp->_bufsiz)
return -1;
ptr = p_fp->_base + (unsigned long)p_fp->_ptr;
p_fp->_ptr++;
return *ptr;
}
size_t josal_fputs(const char *s, osal_file_t fp)
{
return josal_fwrite(s, sizeof(char), strlen(s), fp);
}
long josal_ftell(osal_file_t fp)
{
fileio_buf_t *p_fp = (fileio_buf_t *)fp;
return p_fp->_bufsiz;
}
int josal_fseek(osal_file_t fp, long offset, int origin)
{
char *curr_p;
fileio_buf_t *p_fp = (fileio_buf_t *)fp;
if (!fp)
return -1;
switch (origin) {
case SEEK_CUR:
curr_p = (char *)p_fp->_ptr;
break;
case SEEK_END:
curr_p = (char *)(uint64_t)p_fp->_bufsiz;
break;
case SEEK_SET:
curr_p = (char *)0;
break;
default:
return -1;
}
p_fp->_ptr = curr_p + offset;
if (p_fp->_ptr > p_fp->_base + p_fp->_bufsiz)
p_fp->_ptr = p_fp->_base + p_fp->_bufsiz;
return 0;
}
int josal_fclose(osal_file_t fp)
{
fileio_buf_t *p_fp = (fileio_buf_t *)fp;
if (!p_fp)
return -1;
p_fp->_base = (char *)0;
p_fp->_bufsiz = 0;
p_fp->_ptr = (char *)0;
return 1;
}
int josal_fscanf(osal_file_t fp, const char *_Format, ...)
{
return 1;
}
int josal_fprintf(osal_file_t fp, const char *_Format, ...)
{
va_list ptr;
char logBuf[MAX_PRINT_LENGTH] = {0};
va_start(ptr, _Format);
vsnprintf(logBuf, MAX_PRINT_LENGTH, _Format, ptr);
va_end(ptr);
myprintf(logBuf);
return 1;
}
int josal_kbhit(void)
{
return 0;
}
int josal_getch(void)
{
return -1;
}
int josal_flush_ch(void)
{
return -1;
}
int josal_srand(int seed)
{
return 0;
}
/* to return a integer between 0~FEEDING_MAX_SIZE(4M) */
int josal_rand(void)
{
return 0x10000;
}
/* to conver c to upper case */
int josal_toupper(int c)
{
int ret = c;
char *ptr = (char *)&ret;
int i;
for (i = 0; i < sizeof(int); i++) {
if (ptr[i] > 96 && ptr[i] < 123)
ptr[i++] -= 32;
}
return ret;
}
void jinv_dcache_range(unsigned long start, unsigned long size)
{
invalidate_dcache_range(start, size);
}
#ifdef LIB_C_STUB
/*
* newlib_stubs.c
* the bellow code is just to build ref-code.
* customers will removed the bellow code bacuase they need a library which is related to the
* system library such as newlibc
*/
#include <errno.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/unistd.h>
#ifndef STDOUT_USART
#define STDOUT_USART 0
#endif
#ifndef STDERR_USART
#define STDERR_USART 0
#endif
#ifndef STDIN_USART
#define STDIN_USART 0
#endif
#undef errno
int errno;
extern int errno;
/*
* environ
* A pointer to a list of environment variables and their values.
* For a minimal environment, this empty list is adequate:
*/
char *__env[1] = { 0 };
char **environ = __env;
//int _write(int file, char *ptr, int len);
void _exit(int status)
{
_write(1, "exit", 4);
while (1) {
;
}
}
int _close(int file)
{
return -1;
}
/*
* execve
* Transfer control to a new process. Minimal implementation (for a system without processes):
*/
int _execve(char *name, char **argv, char **env)
{
errno = ENOMEM;
return -1;
}
/*
* fork
* Create a new process. Minimal implementation (for a system without processes):
*/
int _fork(void)
{
errno = EAGAIN;
return -1;
}
/*
* fstat
* Status of an open file. For consistency with other minimal implementations in these examples,
* all files are regarded as character special devices.
* The `sys/stat.h' header file required is distributed in the `include' subdirectory for this C library.
*/
int _fstat(int file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
/*
* getpid
* Process-ID; this is sometimes used to generate strings unlikely to conflict with other processes.
* Minimal implementation,
* for a system without processes:
*/
int _getpid(void)
{
return 1;
}
/*
* isatty
* Query whether output stream is a terminal. For consistency with the other minimal implementations,
*/
int _isatty(int file)
{
switch (file) {
case STDOUT_FILENO:
case STDERR_FILENO:
case STDIN_FILENO:
return 1;
default:
//errno = ENOTTY;
errno = EBADF;
return 0;
}
}
/*
* kill
* Send a signal. Minimal implementation:
*/
int _kill(int pid, int sig)
{
errno = EINVAL;
return (-1);
}
/*
* link
* Establish a new name for an existing file. Minimal implementation:
*/
int _link(char *old, char *new)
{
errno = EMLINK;
return -1;
}
/*
* lseek
* Set position in a file. Minimal implementation:
*/
int _lseek(int file, int ptr, int dir)
{
return 0;
}
/*
* sbrk
* Increase program data space.
* Malloc and related functions depend on this
*/
caddr_t _sbrk(int incr)
{
// extern char _ebss; // Defined by the linker
char _ebss;
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &_ebss;
}
prev_heap_end = heap_end;
heap_end += incr;
return (caddr_t)prev_heap_end;
}
/*
* read
* Read a character to a file. `libc' subroutines will use this system routine for input from all files,
* including stdin
* Returns -1 on error or blocks until the number of characters have been read.
*/
int _read(int file, char *ptr, int len)
{
int n;
int num = 0;
switch (file) {
case STDIN_FILENO:
for (n = 0; n < len; n++) {
char c = 0;
#if STDIN_USART == 1
while ((USART1->SR & USART_FLAG_RXNE) == (u16)RESET) {
}
c = (char)(USART1->DR & (u16)0x01FF);
#elif STDIN_USART == 2
while ((USART2->SR & USART_FLAG_RXNE) == (u16)RESET) {
}
c = (char)(USART2->DR & (u16)0x01FF);
#elif STDIN_USART == 3
while ((USART3->SR & USART_FLAG_RXNE) == (u16)RESET) {
}
c = (char)(USART3->DR & (u16)0x01FF);
#endif
*ptr++ = c;
num++;
}
break;
default:
errno = EBADF;
return -1;
}
return num;
}
/*
* stat
* Status of a file (by name). Minimal implementation:
* int _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
*/
int stat(const char *filepath, struct stat *st)
{
return _stat(filepath, st);
}
int _stat(const char *filepath, struct stat *st)
{
st->st_mode = S_IFCHR;
st->st_size = CMP_FILE_BUFFER_SIZE;
return 0;
}
/*
* times
* Timing information for current process. Minimal implementation:
*/
clock_t _times(struct tms *buf)
{
return -1;
}
/*
* unlink
* Remove a file's directory entry. Minimal implementation:
*/
int _unlink(char *name)
{
errno = ENOENT;
return -1;
}
/*
* wait
* Wait for a child process. Minimal implementation:
*/
int _wait(int *status)
{
errno = ECHILD;
return -1;
}
/*
* write
* Write a character to a file. `libc' subroutines will use this system routine for output to all files,
* including stdout
* Returns -1 on error or number of bytes sent
*/
int _write(int file, char *ptr, int len)
{
int n;
switch (file) {
case STDOUT_FILENO: /*stdout*/
for (n = 0; n < len; n++) {
#if STDOUT_USART == 1
while ((USART1->SR & USART_FLAG_TC) == (u16)RESET) {
}
USART1->DR = (*ptr++ & (u16)0x01FF);
#elif STDOUT_USART == 2
while ((USART2->SR & USART_FLAG_TC) == (u16)RESET) {
}
USART2->DR = (*ptr++ & (u16)0x01FF);
#elif STDOUT_USART == 3
while ((USART3->SR & USART_FLAG_TC) == (u16)RESET) {
}
USART3->DR = (*ptr++ & (u16)0x01FF);
#endif
}
break;
case STDERR_FILENO: /* stderr */
for (n = 0; n < len; n++) {
#if STDERR_USART == 1
while ((USART1->SR & USART_FLAG_TC) == (u16)RESET) {
}
USART1->DR = (*ptr++ & (u16)0x01FF);
#elif STDERR_USART == 2
while ((USART2->SR & USART_FLAG_TC) == (u16)RESET) {
}
USART2->DR = (*ptr++ & (u16)0x01FF);
#elif STDERR_USART == 3
while ((USART3->SR & USART_FLAG_TC) == (u16)RESET) {
}
USART3->DR = (*ptr++ & (u16)0x01FF);
#endif
}
break;
default:
errno = EBADF;
return -1;
}
return len;
}
#endif
//#endif

View File

@ -0,0 +1,97 @@
//------------------------------------------------------------------------------
// File: log.h
//
// Copyright (c) 2006, Chips & Media. All rights reserved.
//------------------------------------------------------------------------------
#ifndef _VDI_OSAL_H_
#define _VDI_OSAL_H_
//#include <stdio.h>
#include <stdlib.h>
//#include <ctype.h>
#include "cvi_jpeg_cfg.h"
#define MAX_PRINT_LENGTH 512
typedef void *osal_file_t;
# ifndef SEEK_SET
# define SEEK_SET 0
# endif
# ifndef SEEK_CUR
# define SEEK_CUR 1
# endif
# ifndef SEEK_END
# define SEEK_END 2
# endif
#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__)
#elif defined(linux) || defined(__linux) || defined(ANDROID)
//#ifndef stdout
//# define stdout (void * )1
//#endif
//#ifndef stderr
//# define stderr (void * )1
//#endif
#define OSAL_MEMCPY josal_memcpy
#define OSAL_MEMCMP josal_memcmp
#define OSAL_MALLOC josal_malloc
#define OSAL_FREE josal_free
#define OSAL_FOPEN josal_fopen
#define OSAL_FWRITE josal_fwrite
#define OSAL_FREAD josal_fread
#define OSAL_FSEEK josal_fseek
#define OSAL_FCLOSE josal_fclose
#define OSAL_FFLUSH josal_fflush
#define OSAL_FEOF josal_feof
#define OSAL_FGETS josal_fgets
#define INV_DCACHE_RANGE jinv_dcache_range
#endif
#if defined(__cplusplus)
extern "C" {
#endif
//memory
void *josal_memcpy(void *dst, const void *src, int count);
void *josal_memset(void *dst, int val, int count);
int josal_memcmp(const void *src, const void *dst, int size);
void *josal_malloc(int size);
void *josal_realloc(void *ptr, int size);
void josal_free(void *p);
osal_file_t josal_fopen(const char *osal_file_tname, const char *mode);
size_t josal_fwrite(const void *p, int size, int count, osal_file_t fp);
size_t josal_fread(void *p, int size, int count, osal_file_t fp);
long josal_ftell(osal_file_t fp);
int josal_fseek(osal_file_t fp, long offset, int origin);
int josal_fclose(osal_file_t fp);
int josal_fflush(osal_file_t fp);
int josal_fprintf(osal_file_t fp, const char *_Format, ...);
int josal_fscanf(osal_file_t fp, const char *_Format, ...);
int josal_kbhit(void);
int josal_getch(void);
int josal_flush_ch(void);
int josal_feof(osal_file_t fp);
void *josal_create_mutex(const char *name);
void josal_close_mutex(void *handle);
int josal_mutex_lock(void *handle);
int josal_mutex_unlock(void *handle);
char josal_fgetc(osal_file_t fp);
char *josal_fgets(void *p, int size, osal_file_t fp);
int josal_srand(int seed);
int josal_rand(void);
int josal_toupper(int c);
size_t josal_fputs(const char *s, osal_file_t fp);
void jinv_dcache_range(unsigned long start, unsigned long size);
#if defined(__cplusplus)
}
#endif
#endif //#ifndef _VDI_OSAL_H

View File

@ -0,0 +1,155 @@
#include "jpuconfig.h"
#include "regdefine.h"
#include "jpulog.h"
#include "jpurun.h"
#include "jpuhelper.h"
#include "jdi_osal.h"
#include <asm/io.h>
typedef struct v {
int mode; // 1 = dec, 2 = enc
int comparatorFlag;
int packedFormat;
int chroma_interleave;
int usePartialMode;
int partialBufNum;
int rot_angle;
int mirDir;
int outNum;
int roiEnable;
int roiWidth;
int roiHeight;
int mjpgChromaFormat;
int roiOffsetX;
int roiOffsetY;
int iHorScaleMode;
int iVerScaleMode;
int fileSize;
void *bs_addr;
void *yuv_addr;
} dec_cfg_t;
#define mmio_write_32(a, v) writel(v, a)
#define mmio_read_32(a) readl(a)
enum _mode_ {
MODE_DEC = 1,
MODE_ENC,
};
enum _packFormat_ {
PACK_PLANAR = 0,
PACK_YUYV,
PACK_UYVY,
PACK_YVYU,
PACK_VYUY,
PACK_YUV_444_PACKED,
} packFormat;
enum _partialMode_ {
PARTIAL_MODE_DISABLE = 0,
PARTIAL_MODE_ENABLE,
};
enum _rorateAngle_ {
ROTATE_0 = 0,
ROTATE_90 = 90,
ROTATE_180 = 180,
ROTATE_270 = 270,
};
enum _mirror_dir_ {
MIRROR_NO = 0,
MIRROR_VERTICAL,
MIRROR_HORIZONTAL,
MIRROR_BOTH,
};
int jpeg_dec(dec_cfg_t *cfg, void *bs_addr, void *yuv_addr, int size)
{
int ret = 0;
DecConfigParam decConfig;
memset(&decConfig, 0x00, sizeof(DecConfigParam));
decConfig.bitstreamFileName = NULL;
decConfig.StreamEndian = JPU_STREAM_ENDIAN;
decConfig.FrameEndian = JPU_FRAME_ENDIAN;
decConfig.yuvFileName = NULL;
decConfig.comparatorFlag = cfg->comparatorFlag;
decConfig.packedFormat = cfg->packedFormat;
decConfig.chroma_interleave = cfg->chroma_interleave;
decConfig.usePartialMode = cfg->usePartialMode;
decConfig.partialBufNum = cfg->partialBufNum;
decConfig.rot_angle = cfg->rot_angle;
decConfig.mirDir = cfg->mirDir;
decConfig.outNum = cfg->outNum;
decConfig.roiEnable = cfg->roiEnable;
decConfig.roiWidth = cfg->roiWidth;
decConfig.roiHeight = cfg->roiHeight;
decConfig.roiOffsetX = cfg->roiOffsetX;
decConfig.roiOffsetY = cfg->roiOffsetY;
decConfig.iHorScaleMode = cfg->iHorScaleMode;
decConfig.iVerScaleMode = cfg->iVerScaleMode;
decConfig.bs_addr = bs_addr;
decConfig.yuv_addr = yuv_addr;
decConfig.size = size;
if (!decConfig.usePartialMode) {
if (decConfig.rot_angle != 0 && decConfig.rot_angle != 90 &&
decConfig.rot_angle != 180 && decConfig.rot_angle != 270) {
JLOG(ERR, "Invalid rotation angle.\n");
return 1;
}
if (decConfig.mirDir != 0 && decConfig.mirDir != 1 &&
decConfig.mirDir != 2 && decConfig.mirDir != 3) {
JLOG(ERR, "Invalid mirror direction.\n");
return 1;
}
if (decConfig.rot_angle != 0 || decConfig.mirDir != 0)
decConfig.useRot = 1;
}
ret = jpeg_decode_helper(&decConfig);
return 1 - ret;
}
int jpeg_decoder(void *bs_addr, void *yuv_addr, int size)
{
dec_cfg_t allCfgs[] = {
// comp
// {MODE_ENC, 1, PACK_PLANAR, 0, PARTIAL_MODE_DISABLE, 2, ROTATE_0, MIRROR_NO, 1,
// 0, 3840, 2160, PACK_PLANAR, 0, 0, 0, 0, 40681 },
{MODE_DEC, 1, PACK_PLANAR, 0, PARTIAL_MODE_DISABLE, 4, ROTATE_0, MIRROR_NO, 1,
0, 300, 300, 0, 50, 50, 0, 0, 0x23431},
};
int idx, ret = 0, all = 0;
mmio_write_32((void *)TOP_DDR_ADDR_MODE_REG, (1 << DAMR_REG_VD_REMAP_ADDR_39_32_OFFSET));
mmio_write_32((void *)VC_REG_BASE, (mmio_read_32((void *)VC_REG_BASE) | (0x1f)));
#ifdef SUPPORT_INTERRUPT
request_irq(JPEG_CODEC_INTR_NUM, irq_handler_jpeg_codec, 0, "jpeg int", NULL);
BM_DBG_TRACE("irq num = %d\n", JPEG_INTRPT_REQ);
#endif
for (idx = 0; idx < sizeof(allCfgs) / sizeof(dec_cfg_t); idx++) {
if (allCfgs[idx].mode == MODE_DEC)
ret = jpeg_dec(&allCfgs[idx], bs_addr, yuv_addr, size);
// else
// ret = jpeg_enc_slt_test(&allCfgs[idx]);
if (ret) {
JLOG(NONE, "case %d, error\n", idx);
all = 1;
} else
JLOG(NONE, "case %d, success\n", idx);
}
JLOG(NONE, "jpeg decode %s\n", all ? "failed" : "passed");
return all;
}

View File

@ -0,0 +1,6 @@
#ifndef _JPEG_H_
#define _JPEG_H_
int jpeg_decoder(void *bs_addr, void *yuv_addr, int size);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,270 @@
#ifndef _JPU_API_H_
#define _JPU_API_H_
#include "jpuconfig.h"
#include "jdi.h"
#define CVI_JPG_DBG(msg, ...) \
do {\
if (1) {\
printf("[DBG] %s = %d, " msg, __func__, __LINE__, ##__VA_ARGS__);\
} \
} while (0)
#define ALIGN_X(IN, ALIGN) (((IN) + (ALIGN) - 1) / (ALIGN) * (ALIGN))
#define ALIGN_32
//------------------------------------------------------------------------------
// common struct and definition
//------------------------------------------------------------------------------
typedef enum {
ENABLE_JPG_ROTATION,
DISABLE_JPG_ROTATION,
ENABLE_JPG_MIRRORING,
DISABLE_JPG_MIRRORING,
SET_JPG_MIRROR_DIRECTION,
SET_JPG_ROTATION_ANGLE,
SET_JPG_ROTATOR_OUTPUT,
SET_JPG_ROTATOR_STRIDE,
SET_JPG_SCALE_HOR,
SET_JPG_SCALE_VER,
SET_JPG_USE_PARTIAL_MODE,
SET_JPG_PARTIAL_FRAME_NUM,
SET_JPG_PARTIAL_LINE_NUM,
SET_JPG_ENCODE_NEXT_LINE,
SET_JPG_USE_STUFFING_BYTE_FF,
ENC_JPG_GET_HEADER,
ENABLE_LOGGING,
DISABLE_LOGGING,
JPG_CMD_END
} JpgCommand;
typedef enum {
JPG_RET_SUCCESS,
JPG_RET_FAILURE,
JPG_RET_BIT_EMPTY,
JPG_RET_EOS,
JPG_RET_INVALID_HANDLE,
JPG_RET_INVALID_PARAM,
JPG_RET_INVALID_COMMAND,
JPG_RET_ROTATOR_OUTPUT_NOT_SET,
JPG_RET_ROTATOR_STRIDE_NOT_SET,
JPG_RET_FRAME_NOT_COMPLETE,
JPG_RET_INVALID_FRAME_BUFFER,
JPG_RET_INSUFFICIENT_FRAME_BUFFERS,
JPG_RET_INVALID_STRIDE,
JPG_RET_WRONG_CALL_SEQUENCE,
JPG_RET_CALLED_BEFORE,
JPG_RET_NOT_INITIALIZED
} JpgRet;
typedef enum {
MIRDIR_NONE,
MIRDIR_VER,
MIRDIR_HOR,
MIRDIR_HOR_VER
} JpgMirrorDirection;
typedef enum {
FORMAT_420 = 0,
FORMAT_422 = 1,
FORMAT_224 = 2,
FORMAT_444 = 3,
FORMAT_400 = 4
} FrameFormat;
typedef enum {
CBCR_ORDER_NORMAL,
CBCR_ORDER_REVERSED
} CbCrOrder;
typedef enum {
CBCR_SEPARATED = 0,
CBCR_INTERLEAVE
,
CRCB_INTERLEAVE
} CbCrInterLeave;
typedef enum {
PACKED_FORMAT_NONE,
PACKED_FORMAT_422_YUYV,
PACKED_FORMAT_422_UYVY,
PACKED_FORMAT_422_YVYU,
PACKED_FORMAT_422_VYUY,
PACKED_FORMAT_444
} PackedOutputFormat;
typedef enum {
INT_JPU_DONE = 0,
INT_JPU_ERROR = 1,
INT_JPU_BIT_BUF_EMPTY = 2,
INT_JPU_BIT_BUF_FULL = 2,
INT_JPU_PARIAL_OVERFLOW = 3,
INT_JPU_PARIAL_BUF0_EMPTY = 4,
INT_JPU_PARIAL_BUF1_EMPTY,
INT_JPU_PARIAL_BUF2_EMPTY,
INT_JPU_PARIAL_BUF3_EMPTY,
INT_JPU_BIT_BUF_STOP
} InterruptJpu;
typedef enum {
JPG_TBL_NORMAL,
JPG_TBL_MERGE
} JpgTableMode;
typedef enum {
ENC_HEADER_MODE_NORMAL,
ENC_HEADER_MODE_SOS_ONLY
} JpgEncHeaderMode;
typedef struct {
PhysicalAddress bufY;
PhysicalAddress bufCb;
PhysicalAddress bufCr;
int stride;
} FrameBuffer;
struct JpgInst;
//------------------------------------------------------------------------------
// decode struct and definition
//------------------------------------------------------------------------------
typedef struct JpgInst JpgDecInst;
typedef JpgDecInst * JpgDecHandle;
typedef struct {
PhysicalAddress bitstreamBuffer;
int bitstreamBufferSize;
BYTE *pBitStream;
int streamEndian;
int frameEndian;
CbCrInterLeave chroma_interleave;
int thumbNailEn;
PackedOutputFormat packedFormat;
int roiEnable;
int roiOffsetX;
int roiOffsetY;
int roiWidth;
int roiHeight;
} JpgDecOpenParam;
typedef struct {
int picWidth;
int picHeight;
int minFrameBufferCount;
int sourceFormat;
int ecsPtr;
int roiFrameWidth;
int roiFrameHeight;
int roiFrameOffsetX;
int roiFrameOffsetY;
int roiMCUSize;
int colorComponents;
} JpgDecInitialInfo;
typedef struct {
int scaleDownRatioWidth;
int scaleDownRatioHeight;
} JpgDecParam;
typedef struct {
int indexFrameDisplay;
int numOfErrMBs;
int decodingSuccess;
int decPicHeight;
int decPicWidth;
int consumedByte;
int bytePosFrameStart;
int ecsPtr;
} JpgDecOutputInfo;
//------------------------------------------------------------------------------
// encode struct and definition
//------------------------------------------------------------------------------
typedef struct JpgInst JpgEncInst;
typedef JpgEncInst * JpgEncHandle;
typedef struct {
PhysicalAddress bitstreamBuffer;
Uint32 bitstreamBufferSize;
int picWidth;
int picHeight;
int sourceFormat;
int restartInterval;
int streamEndian;
int frameEndian;
CbCrInterLeave chroma_interleave;
BYTE huffVal[4][162];
BYTE huffBits[4][256];
BYTE qMatTab[4][64];
PackedOutputFormat packedFormat;
} JpgEncOpenParam;
typedef struct {
int minFrameBufferCount;
int colorComponents;
} JpgEncInitialInfo;
typedef struct {
FrameBuffer *sourceFrame;
} JpgEncParam;
typedef struct {
PhysicalAddress bitstreamBuffer;
Uint32 bitstreamSize;
} JpgEncOutputInfo;
typedef struct {
PhysicalAddress paraSet;
BYTE *pParaSet;
int size;
int headerMode;
int quantMode;
int huffMode;
int disableAPPMarker;
} JpgEncParamSet;
#ifdef __cplusplus
extern "C" {
#endif
int JPU_IsBusy(void);
Uint32 JPU_GetStatus(void);
void JPU_ClrStatus(Uint32 val);
Uint32 JPU_IsInit(void);
Uint32 JPU_WaitInterrupt(int timeout);
JpgRet JPU_Init(void);
void JPU_DeInit(void);
int JPU_GetOpenInstanceNum(void);
JpgRet JPU_GetVersionInfo(Uint32 *versionInfo);
// function for decode
JpgRet JPU_DecOpen(JpgDecHandle *pHandle, JpgDecOpenParam *pop);
JpgRet JPU_DecClose(JpgDecHandle handle);
JpgRet JPU_DecGetInitialInfo(JpgDecHandle handle, JpgDecInitialInfo *info);
JpgRet JPU_DecSetRdPtr(JpgDecHandle handle, PhysicalAddress addr, int updateWrPtr);
JpgRet JPU_DecRegisterFrameBuffer(JpgDecHandle handle, FrameBuffer *bufArray, int num, int strideY, int strideC);
JpgRet JPU_DecGetBitstreamBuffer(JpgDecHandle handle, PhysicalAddress *prdPrt, PhysicalAddress *pwrPtr, int *size);
JpgRet JPU_DecUpdateBitstreamBuffer(JpgDecHandle handle, int size);
JpgRet JPU_HWReset(void);
JpgRet JPU_SWReset(void);
JpgRet JPU_DecStartOneFrame(JpgDecHandle handle, JpgDecParam *param);
JpgRet JPU_DecGetOutputInfo(JpgDecHandle handle, JpgDecOutputInfo *info);
JpgRet JPU_DecIssueStop(JpgDecHandle handle);
JpgRet JPU_DecCompleteStop(JpgDecHandle handle);
JpgRet JPU_DecGiveCommand(JpgDecHandle handle, JpgCommand cmd, void *parameter);
JpgRet JPU_EncGetBitstreamBuffer(JpgEncHandle handle, PhysicalAddress *prdPrt, PhysicalAddress *pwrPtr, int *size);
JpgRet JPU_EncUpdateBitstreamBuffer(JpgEncHandle handle, int size);
#ifdef __cplusplus
}
#endif
#endif //_JPU_API_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,280 @@
#ifndef _JPUAPI_UTIL_H_
#define _JPUAPI_UTIL_H_
#include "jpuapi.h"
#include "regdefine.h"
#define DC_TABLE_INDEX0 0
#define AC_TABLE_INDEX0 1
#define DC_TABLE_INDEX1 2
#define AC_TABLE_INDEX1 3
#define Q_COMPONENT0 0
#define Q_COMPONENT1 0x40
#define Q_COMPONENT2 0x80
typedef enum {
JPG_START_PIC = 0,
JPG_START_INIT,
JPG_START_STOP,
JPG_START_PARTIAL
} JpgStartCmd;
typedef struct{
UINT tag;
UINT type;
int count;
int offset;
} TAG;
enum {
JFIF = 0,
JFXX_JPG = 1,
JFXX_PAL = 2,
JFXX_RAW = 3,
EXIF_JPG = 4
};
typedef struct {
int PicX;
int PicY;
int BitPerSample[3];
int Compression; // 1 for uncompressed / 6 for compressed(jpeg)
int PixelComposition; // 2 for RGB / 6 for YCbCr
int SamplePerPixel;
int PlanrConfig; // 1 for chunky / 2 for planar
int YCbCrSubSample; // 00020002 for YCbCr 4:2:0 / 00020001 for YCbCr 4:2:2
UINT JpegOffset;
UINT JpegThumbSize;
} EXIF_INFO;
typedef struct {
BYTE *buffer;
int index;
int size;
} vpu_getbit_context_t;
#define init_get_bits(CTX, BUFFER, SIZE) JpuGbuInit(CTX, BUFFER, SIZE)
#define show_bits(CTX, NUM) JpuGguShowBit(CTX, NUM)
#define get_bits(CTX, NUM) JpuGbuGetBit(CTX, NUM)
#define get_bits_left(CTX) JpuGbuGetLeftBitCount(CTX)
#define get_bits_count(CTX) JpuGbuGetUsedBitCount(CTX)
typedef struct {
PhysicalAddress streamWrPtr;
PhysicalAddress streamRdPtr;
int streamEndflag;
PhysicalAddress streamBufStartAddr;
PhysicalAddress streamBufEndAddr;
int streamBufSize;
BYTE *pBitStream;
int frameOffset;
int consumeByte;
int nextOffset;
int currOffset;
FrameBuffer *frameBufPool;
int numFrameBuffers;
int stride;
int strideY;
int strideC;
int rotationEnable;
int mirrorEnable;
int mirrorDirection;
int rotationAngle;
FrameBuffer rotatorOutput;
int rotatorStride;
int rotatorOutputValid;
int initialInfoObtained;
int minFrameBufferNum;
int streamEndian;
int frameEndian;
int chroma_interleave;
int picWidth;
int picHeight;
int alignedWidth;
int alignedHeight;
int headerSize;
int ecsPtr;
int pagePtr;
int wordPtr;
int bitPtr;
int format;
int rstIntval;
int userHuffTab;
int huffDcIdx;
int huffAcIdx;
int Qidx;
BYTE huffVal[4][162];
BYTE huffBits[4][256];
BYTE cInfoTab[4][6];
BYTE qMatTab[4][64];
Uint32 huffMin[4][16];
Uint32 huffMax[4][16];
BYTE huffPtr[4][16];
// partial
int usePartial;
int lineNum;
int bufNum;
int busReqNum;
int compNum;
int mcuBlockNum;
int compInfo[3];
int frameIdx;
int bitEmpty;
int iHorScaleMode;
int iVerScaleMode;
int mcuWidth;
int mcuHeight;
vpu_getbit_context_t gbc;
#ifdef MJPEG_ERROR_CONCEAL
//error conceal
struct{
int bError;
int rstMarker;
int errPosX;
int errPosY;
} errInfo;
int curRstIdx;
int nextRstIdx;
int setPosX;
int setPosY;
int gbuStartPtr; // entry point in stream buffer before pic_run
int numRstMakerRounding;
#endif
//ROI
int roiEnable;
int roiOffsetX;
int roiOffsetY;
int roiWidth;
int roiHeight;
int roiMcuOffsetX;
int roiMcuOffsetY;
int roiMcuWidth;
int roiMcuHeight;
int packedFormat;
} JpgDecInfo;
typedef struct {
JpgEncOpenParam openParam;
JpgEncInitialInfo initialInfo;
PhysicalAddress streamRdPtr;
PhysicalAddress streamWrPtr;
PhysicalAddress streamBufStartAddr;
PhysicalAddress streamBufEndAddr;
int streamBufSize;
FrameBuffer *frameBufPool;
int numFrameBuffers;
int stride;
int rotationEnable;
int mirrorEnable;
int mirrorDirection;
int rotationAngle;
int initialInfoObtained;
int picWidth;
int picHeight;
int alignedWidth;
int alignedHeight;
int seqInited;
int frameIdx;
int format;
int streamEndian;
int frameEndian;
int chroma_interleave;
int rstIntval;
int busReqNum;
int mcuBlockNum;
int compNum;
int compInfo[3];
// give command
int disableAPPMarker;
int quantMode;
int stuffByteEnable;
Uint32 huffCode[4][256];
Uint32 huffSize[4][256];
BYTE *pHuffVal[4];
BYTE *pHuffBits[4];
BYTE *pCInfoTab[4];
BYTE *pQMatTab[4];
// partial
int usePartial;
int partiallineNum;
int partialBufNum;
int packedFormat;
JpgEncParamSet *paraSet;
} JpgEncInfo;
typedef struct JpgInst {
int inUse;
int instIndex;
int loggingEnable;
union {
JpgEncInfo encInfo;
JpgDecInfo decInfo;
} JpgInfo;
} JpgInst;
#ifdef __cplusplus
extern "C" {
#endif
JpgRet InitJpgInstancePool(void);
JpgRet GetJpgInstance(JpgInst **ppInst);
void FreeJpgInstance(JpgInst *pJpgInst);
JpgRet CheckJpgInstValidity(JpgInst *pci);
JpgRet CheckJpgDecOpenParam(JpgDecOpenParam *pop);
int JpuGbuInit(vpu_getbit_context_t *ctx, BYTE *buffer, int size);
int JpuGbuGetUsedBitCount(vpu_getbit_context_t *ctx);
int JpuGbuGetLeftBitCount(vpu_getbit_context_t *ctx);
unsigned int JpuGbuGetBit(vpu_getbit_context_t *ctx, int bit_num);
unsigned int JpuGguShowBit(vpu_getbit_context_t *ctx, int bit_num);
int JpegDecodeHeader(JpgDecInfo *jpg);
int JpgDecQMatTabSetUp(JpgDecInfo *jpg);
int JpgDecHuffTabSetUp(JpgDecInfo *jpg);
void JpgDecGramSetup(JpgDecInfo *jpg);
JpgRet CheckJpgEncOpenParam(JpgEncOpenParam *pop);
JpgRet CheckJpgEncParam(JpgEncHandle handle, JpgEncParam *param);
int JpgEncLoadHuffTab(JpgEncInfo *pJpgEncInfo);
int JpgEncLoadQMatTab(JpgEncInfo *pJpgEncInfo);
int JpgEncEncodeHeader(JpgEncHandle handle, JpgEncParamSet *para);
JpgRet JpgEnterLock(void);
JpgRet JpgLeaveLock(void);
JpgRet JpgSetClockGate(Uint32 on);
void SetJpgPendingInst(JpgInst *inst);
void ClearJpgPendingInst(void);
JpgInst *GetJpgPendingInst(void);
#ifdef MJPEG_ERROR_CONCEAL
int JpegDecodeConcealError(JpgDecInfo *jpg);
#endif
#ifdef __cplusplus
}
#endif
#endif //_JPUAPI_UTIL_H_

View File

@ -0,0 +1,36 @@
#ifndef _JPU_CONFIG_H_
#define _JPU_CONFIG_H_
#include "config.h"
#include "jputypes.h"
#define MAX_NUM_INSTANCE 8
#define MAX_INST_HANDLE_SIZE (12 * 1024)
#ifdef JPU_FPGA_PLATFORM
#define JPU_FRAME_ENDIAN JDI_BIG_ENDIAN
#define JPU_STREAM_ENDIAN JDI_BIG_ENDIAN
#else
#define JPU_FRAME_ENDIAN JDI_LITTLE_ENDIAN
#define JPU_STREAM_ENDIAN JDI_LITTLE_ENDIAN
#endif
// 0 (chroma separate mode), 1 (cbcr interleave mode), 2 (crcb interleave mode)
#define JPU_CHROMA_INTERLEAVE 1
#define JPU_INTERRUPT_TIMEOUT_MS 5000
#define JPU_STUFFING_BYTE_FF 0 // 0 : ON ("0xFF"), 1 : OFF ("0x00") for stuffing
#define JPU_PARTIAL_DECODE 1 // 0 : OFF, 1 : ON
#define MAX_MJPG_PIC_WIDTH 32768
#define MAX_MJPG_PIC_HEIGHT 32768
// For AVC decoder, 16(reference) + 2(current) + 1(rotator)
#define MAX_FRAME (19 * MAX_NUM_INSTANCE)
#define STREAM_FILL_SIZE 0x10000
#define STREAM_END_SIZE 0
#define JPU_GBU_SIZE 512
#define STREAM_BUF_SIZE 0x100000
#define JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL 0
#endif /* _JPU_CONFIG_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,165 @@
#ifndef _JPU_HELPER_H_
#define _JPU_HELPER_H_
#include "jpuapi.h"
#include "jpurun.h"
typedef struct {
char SrcFileName[256];
int NumFrame;
int PicX;
int PicY;
int FrameRate;
// MPEG4 ONLY
int VerId;
int DataPartEn;
int RevVlcEn;
int ShortVideoHeader;
int AnnexI;
int AnnexJ;
int AnnexK;
int AnnexT;
int IntraDcVlcThr;
int VopQuant;
// H.264 ONLY
int ConstIntraPredFlag;
int DisableDeblk;
int DeblkOffsetA;
int DeblkOffsetB;
int ChromaQpOffset;
int PicQpY;
// MJPEG ONLY
char HuffTabName[256];
char QMatTabName[256];
int VersionID;
int FrmFormat;
int SrcFormat;
int RstIntval;
int ThumbEnable;
int ThumbSizeX;
int ThumbSizeY;
// COMMON
int GopPicNum;
int SliceMode;
int SliceSizeMode;
int SliceSizeNum;
int IntraRefreshNum;
int ConstantIntraQPEnable;
int RCIntraQP;
int MaxQpSetEnable;
int MaxQp;
int GammaSetEnable;
int Gamma;
int HecEnable;
// RC
int RcEnable;
int RcBitRate;
int RcInitDelay;
int RcBufSize;
// NEW RC Scheme
int RcIntervalMode;
int RcMBInterval;
int IntraCostWeight;
int SearchRange;
int MeUseZeroPmv;
int MeBlkModeEnable;
} ENC_CFG;
typedef struct {
int sourceFormat;
int restartInterval;
BYTE huffVal[4][162];
BYTE huffBits[4][256];
BYTE qMatTab[4][64];
} EncMjpgParam;
#if defined(__cplusplus)
extern "C" {
#endif
int jpgGetHuffTable(char *huffFileName, EncMjpgParam *param);
int jpgGetQMatrix(char *qMatFileName, EncMjpgParam *param);
int getJpgEncOpenParamDefault(JpgEncOpenParam *pEncOP, EncConfigParam *pEncConfig);
int getJpgEncOpenParam(JpgEncOpenParam *pEncOP, EncConfigParam *pEncConfig, char *srcYuvFileName);
int parseJpgCfgFile(ENC_CFG *pEncCfg, char *FileName);
JpgRet WriteJpgBsBufHelper(JpgDecHandle handle, BufInfo *pBufInfo,
PhysicalAddress paBsBufStart,
PhysicalAddress paBsBufEnd, int defaultsize,
int checkeos, int *pstreameos, int endian);
int WriteBsBufFromBufHelper(JpgDecHandle handle, jpu_buffer_t *pJbStream,
BYTE *pChunk, int chunkSize, int endian);
JpgRet ReadJpgBsBufHelper(JpgEncHandle handle, osal_file_t *bsFp,
PhysicalAddress paBsBufStart,
PhysicalAddress paBsBufEnd, int encHeaderSize,
int endian);
int LoadYuvImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv,
PhysicalAddress addrY, PhysicalAddress addrCb,
PhysicalAddress addrCr, int picWidth,
int picHeight, int stride, int interleave,
int format, int endian, int packed);
int LoadYuvPartialImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, PhysicalAddress addrY,
PhysicalAddress addrCb, PhysicalAddress addrCr, int picWidth, int picHeight,
int picHeightPartial, int stride, int interleave, int format, int endian,
int partPosIdx, int frameIdx, int packed);
int SaveYuvImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv,
PhysicalAddress addrY, PhysicalAddress addrCb,
PhysicalAddress addrCr, int picWidth,
int picHeight, int stride, int interLeave,
int format, int endian, int packed);
int SaveYuvPartialImageHelperFormat(osal_file_t *yuvFp, Uint8 *pYuv, PhysicalAddress addrY,
PhysicalAddress addrCb, PhysicalAddress addrCr, int picWidth, int picHeight,
int picHeightPartial, int stride, int interLeave, int format, int endian,
int partPosIdx, int frameIdx, int packed);
unsigned int GetFrameBufSize(int framebufFormat, int picWidth, int picHeight);
void GetMcuUnitSize(int format, int *mcuWidth, int *mcuHeight);
typedef enum {
YUV444,
YUV422,
YUV420,
NV12,
NV21,
YUV400,
YUYV,
YVYU,
UYVY,
VYUY,
YYY,
RGB_PLANAR,
RGB32,
RGB24,
RGB16
} yuv2rgb_color_format;
void jpu_yuv2rgb(int width, int height, yuv2rgb_color_format format,
unsigned char *src, unsigned char *rgba, int chroma_reverse);
yuv2rgb_color_format
convert_jpuapi_format_to_yuv2rgb_color_format(int planar_format,
int pack_format, int interleave);
int comparateYuv(Uint8 *pYuv, Uint8 *pRefYuv, int picWidth, int picHeight,
int stride, int interleave, int format, int endian,
int packed);
#if defined(__cplusplus)
}
#endif
#endif //#ifndef _JPU_HELPER_H_

View File

@ -0,0 +1,79 @@
#ifndef _JPU_LOG_H_
#define _JPU_LOG_H_
#include <stdlib.h>
#include <command.h>
#include <stdio.h>
#include <config.h>
#include <vsprintf.h>
enum { NONE = 0, INFO, WARN, ERR, TRACE, MAX_LOG_LEVEL };
enum {
LOG_HAS_DAY_NAME = 1, /**< Include day name [default: no] */
LOG_HAS_YEAR = 2, /**< Include year digit [no] */
LOG_HAS_MONTH = 4, /**< Include month [no] */
LOG_HAS_DAY_OF_MON = 8, /**< Include day of month [no] */
LOG_HAS_TIME = 16, /**< Include time [yes] */
LOG_HAS_MICRO_SEC = 32, /**< Include microseconds [yes] ......*/
LOG_HAS_FILE = 64, /**< Include sender in the log [yes] */
LOG_HAS_NEWLINE = 128, /**< Terminate each call with newline [yes] .*/
LOG_HAS_CR = 256, /**< Include carriage return [no] */
LOG_HAS_SPACE = 512, /**< Include two spaces before log[yes] ..*/
LOG_HAS_COLOR = 1024, /**< Colorize logs [yes on win32] */
LOG_HAS_LEVEL_TEXT = 2048 /**< Include level text string [no] */
};
enum {
TERM_COLOR_R = 2, /**< Red */
TERM_COLOR_G = 4, /**< Green */
TERM_COLOR_B = 1, /**< Blue. */
TERM_COLOR_BRIGHT = 8 /**< Bright mask. */
};
#define MAX_PRINT_LENGTH 512
#ifdef ANDROID
#include <utils/Log.h>
#undef LOG_NDEBUG
#define LOG_NDEBUG 0
#undef LOG_TAG
#define LOG_TAG "JPUAPI"
#endif
#define JLOG LogMsg
#define LOG_ENABLE_FILE SetLogDecor(GetLogDecor() | LOG_HAS_FILE)
#if defined(__cplusplus)
extern "C" {
#endif
int InitLog(void);
void DeInitLog(void);
void SetMaxLogLevel(int level);
int GetMaxLogLevel(void);
void SetLogColor(int level, int color);
int GetLogColor(int level);
void SetLogDecor(int decor);
int GetLogDecor(void);
#define JLOG_LEVEL ERR
#define LogMsg(level, msg, ...) \
if (JLOG_LEVEL <= (level)) \
printf("%s = %d, " msg, __func__, __LINE__, ##__VA_ARGS__)
void timer_stop(void);
double timer_elapsed_us(void);
double timer_elapsed_ms(void);
int timer_is_valid(void);
double timer_frequency(void);
#if defined(__cplusplus)
}
#endif
#endif //#ifndef _JPU_LOG_H_

View File

@ -0,0 +1,704 @@
#include "jpuapi.h"
#include "jpuapifunc.h"
#include "jpuhelper.h"
#include "jpulog.h"
#include "jpurun.h"
#include "mixer.h"
#include "regdefine.h"
#include <stdlib.h>
#include "asm/cache.h"
#ifdef JPU_FPGA_PLATFORM
//#define ENC_SOURCE_FRAME_DISPLAY
#endif
#define NUM_FRAME_BUF MAX_FRAME
#define MAX_ROT_BUF_NUM 1
#define EXTRA_FRAME_BUFFER_NUM 0
#define ENC_SRC_BUF_NUM 1
//#define ROI_RANDOM_TEST
//#define TEST_JPEG_PERFORMANCE
#ifdef TEST_JPEG_PERFORMANCE
#undef __CONFIG_H__
#include "fw_config.h"
#include "system_common.h"
#include "dm/device.h"
#include "timer.h"
#endif
#define ALIGN_N_BIT(ADDR, BITS) ((((ADDR) + ((1 << (BITS)) - 1)) >> (BITS)) << (BITS))
int img_width, img_height;
int copy_to_dest_addr(Uint8 *pYuv, Uint8 *pRefYuv,
int picWidth, int picHeight, int strideY, int strideC,
int interleave, int format, int endian, int packed)
{
int size = 0;
int nY = 0;
Uint8 *pRef = NULL;
int lumaSize = 0, chromaSize = 0;
Uint8 *pOrg = NULL;
switch (format) {
case FORMAT_420:
nY = (picHeight + 1) / 2 * 2;
chromaSize = ((picWidth + 1) / 2) * ((picHeight + 1) / 2);
break;
case FORMAT_224:
nY = (picHeight + 1) / 2 * 2;
chromaSize = (picWidth) * ((picHeight + 1) / 2);
break;
case FORMAT_422:
nY = picHeight;
chromaSize = ((picWidth + 1) / 2) * picHeight;
break;
case FORMAT_444:
nY = picHeight;
chromaSize = picWidth * picHeight;
break;
case FORMAT_400:
nY = picHeight;
chromaSize = 0;
break;
}
pRef = pRefYuv;
pOrg = pYuv;
if (packed) {
if (packed == PACKED_FORMAT_444)
picWidth *= 3;
else
picWidth *= 2;
lumaSize = picWidth * nY;
chromaSize = 0;
} else {
if (format == FORMAT_420) {
lumaSize = strideY * nY;
chromaSize = strideC * ((picHeight + 1) / 2);
} else {
lumaSize = picWidth * nY;
}
}
CVI_JPG_DBG("nY = %d, picHeight = %d\n", nY, picHeight);
CVI_JPG_DBG("strideY = %d, lumaSize = 0x%X\n", strideY, lumaSize);
CVI_JPG_DBG("strideC = %d, chromaSize = 0x%X\n", strideC, chromaSize);
size = lumaSize + chromaSize * 2;
CVI_JPG_DBG("size = 0x%X, lumaSize = 0x%X, chromaSize = 0x%X\n", size, lumaSize, chromaSize);
CVI_JPG_DBG("y, pRef = %p, pOrg = %p\n", pRef, pOrg);
OSAL_MEMCPY(pRef, pOrg, lumaSize);
pOrg += lumaSize;
pRef += lumaSize;
pRef = (Uint8 *)ALIGN_N_BIT((unsigned long long)pRef, 12);
CVI_JPG_DBG("u, pRef = %p, pOrg = %p\n", pRef, pOrg);
OSAL_MEMCPY(pRef, pOrg, chromaSize);
pOrg += chromaSize;
pRef += chromaSize;
pRef = (Uint8 *)ALIGN_N_BIT((unsigned long long)pRef, 12);
CVI_JPG_DBG("v, pRef = %p, pOrg = %p\n", pRef, pOrg);
OSAL_MEMCPY(pRef, pOrg, chromaSize);
//flush_dcache_all();
flush_dcache_range((unsigned long)pRefYuv, (unsigned long)pRefYuv + lumaSize + chromaSize + chromaSize);
return 0;
}
int jpeg_decode_helper(DecConfigParam *param)
{
JpgDecHandle handle = {0};
JpgDecOpenParam decOP = {0};
JpgDecInitialInfo initialInfo = {0};
JpgDecOutputInfo outputInfo = {0};
JpgDecParam decParam = {0};
JpgRet ret = JPG_RET_SUCCESS;
FrameBuffer frameBuf[NUM_FRAME_BUF];
jpu_buffer_t vbStream = {0};
BufInfo bufInfo = {0};
FRAME_BUF * pFrame[NUM_FRAME_BUF];
Uint32 framebufWidth = 0, framebufHeight = 0;
Uint32 framebufStrideY = 0, framebufStrideC = 0;
Uint32 framebufFormat = FORMAT_420;
int dispWidth = 0, dispHeight = 0;
int i = 0, frameIdx = 0, ppIdx = 0, saveIdx = 0, totalNumofErrMbs = 0, streameos = 0, dispImage = 0;
int suc = 1;
Uint8 *pRefYuvBuf = NULL;
int needFrameBufCount = 0, regFrameBufCount = 0;
int rotEnable = 0;
int int_reason = 0;
int instIdx;
int partPosIdx = 0;
int partBufIdx = 0;
int partMaxIdx = 0;
int partialHeight = 0;
int jpeg_done = 0;
DecConfigParam decConfig;
memcpy(&decConfig, param, sizeof(DecConfigParam));
memset(&pFrame, 0x00, sizeof(FRAME_BUF *) * NUM_FRAME_BUF);
memset(&frameBuf, 0x00, sizeof(FrameBuffer) * NUM_FRAME_BUF);
instIdx = decConfig.instNum;
if (decConfig.usePartialMode && decConfig.roiEnable) {
JLOG(ERR, "Invalid operation mode : partial and ROI mode can not be worked\n");
goto ERR_DEC_INIT;
}
if (decConfig.packedFormat && decConfig.roiEnable) {
JLOG(ERR, "Invalid operation mode : packed mode and ROI mode can not be worked\n");
goto ERR_DEC_INIT;
}
if ((decConfig.iHorScaleMode || decConfig.iVerScaleMode) && decConfig.roiEnable) {
JLOG(ERR, "Invalid operation mode : Scaler mode and ROI mode can not be worked\n");
goto ERR_DEC_INIT;
}
if (decConfig.useRot && decConfig.roiEnable) {
JLOG(ERR, "Invalid operation mode : Rotator mode and ROI mode can not be worked\n");
goto ERR_DEC_INIT;
}
if (!decConfig.yuvFileName)
dispImage = 0;
else
dispImage = 1;
decConfig.comparatorFlag = param->comparatorFlag;
pRefYuvBuf = (Uint8 *)decConfig.yuv_addr;
bufInfo.buf = (Uint8 *)decConfig.bs_addr;
bufInfo.size = decConfig.size;
bufInfo.point = 0;
ret = JPU_Init();
if (ret != JPG_RET_SUCCESS && ret != JPG_RET_CALLED_BEFORE) {
suc = 0;
JLOG(ERR, "JPU_Init failed Error code is 0x%x\n", ret);
goto ERR_DEC_INIT;
}
// Open an instance and get initial information for decoding.
vbStream.size = STREAM_BUF_SIZE;
if (jdi_allocate_dma_memory(&vbStream) < 0) {
JLOG(ERR, "fail to allocate bitstream buffer\n");
goto ERR_DEC_INIT;
}
decOP.streamEndian = decConfig.StreamEndian;
decOP.frameEndian = decConfig.FrameEndian;
decOP.chroma_interleave = (CbCrInterLeave)decConfig.chroma_interleave;
decOP.bitstreamBuffer = vbStream.phys_addr;
decOP.bitstreamBufferSize = vbStream.size;
decOP.pBitStream = (BYTE *)vbStream.virt_addr; // set virtual address mapped of physical address
decOP.packedFormat = decConfig.packedFormat;
decOP.roiEnable = decConfig.roiEnable;
decOP.roiOffsetX = decConfig.roiOffsetX;
decOP.roiOffsetY = decConfig.roiOffsetY;
decOP.roiWidth = decConfig.roiWidth;
decOP.roiHeight = decConfig.roiHeight;
decParam.scaleDownRatioWidth = decConfig.iHorScaleMode;
decParam.scaleDownRatioHeight = decConfig.iVerScaleMode;
JLOG(INFO, "scale ratio:%d, %d\n", decParam.scaleDownRatioWidth, decParam.scaleDownRatioHeight);
ret = JPU_DecOpen(&handle, &decOP);
if (ret != JPG_RET_SUCCESS) {
JLOG(ERR, "JPU_DecOpen failed Error code is 0x%x\n", ret);
goto ERR_DEC_INIT;
}
// JPU_DecGiveCommand(handle, ENABLE_LOGGING, NULL);
if (decConfig.useRot)
rotEnable = 1;
else
rotEnable = 0;
ret = WriteJpgBsBufHelper(handle, &bufInfo, decOP.bitstreamBuffer,
decOP.bitstreamBuffer + decOP.bitstreamBufferSize,
0, 0, &streameos, decOP.streamEndian);
//flush_dcache_all();
flush_dcache_range(decOP.bitstreamBuffer, decOP.bitstreamBuffer + decOP.bitstreamBufferSize);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "WriteBsBufHelper failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
ret = JPU_DecGetInitialInfo(handle, &initialInfo);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "JPU_DecGetInitialInfo failed Error code is 0x%x, inst=%d\n", ret, instIdx);
goto ERR_DEC_OPEN;
}
if (decConfig.usePartialMode) {
// disable Rotator, Scaler
rotEnable = 0;
decConfig.iHorScaleMode = 0;
decConfig.iVerScaleMode = 0;
partialHeight = (initialInfo.sourceFormat == FORMAT_420 || initialInfo.sourceFormat == FORMAT_224) ?
16 : 8;
partMaxIdx = ((initialInfo.picHeight + 15) & ~15) / partialHeight;
if (partMaxIdx < decConfig.partialBufNum)
decConfig.partialBufNum = partMaxIdx;
}
img_width = initialInfo.picWidth;
img_height = initialInfo.picHeight;
JLOG(INFO, "init info width: %d, height = %d\n", initialInfo.picWidth, initialInfo.picHeight);
if (initialInfo.sourceFormat == FORMAT_420 || initialInfo.sourceFormat == FORMAT_422)
framebufWidth = ((initialInfo.picWidth + 15) / 16) * 16;
else
framebufWidth = ((initialInfo.picWidth + 7) / 8) * 8;
if (initialInfo.sourceFormat == FORMAT_420 || initialInfo.sourceFormat == FORMAT_224)
framebufHeight = ((initialInfo.picHeight + 15) / 16) * 16;
else
framebufHeight = ((initialInfo.picHeight + 7) / 8) * 8;
if (decConfig.roiEnable) {
framebufWidth = initialInfo.roiFrameWidth;
framebufHeight = initialInfo.roiFrameHeight;
}
// scaler constraint when conformance test is disable
if (framebufWidth < 128 || framebufHeight < 128) {
if (decConfig.iHorScaleMode || decConfig.iVerScaleMode)
JLOG(WARN,
"Invalid operation mode : Not supported resolution with Scaler, width=%d, height=%d\n",
framebufWidth, framebufHeight);
decConfig.iHorScaleMode = 0;
decConfig.iVerScaleMode = 0;
}
JLOG(INFO, "* Dec InitialInfo =>\n instance #%d,\n minframeBuffercount: %u\n",
instIdx, initialInfo.minFrameBufferCount);
JLOG(INFO, "picWidth: %u\n picHeight: %u\n roiWidth: %u\n rouHeight: %u\n",
initialInfo.picWidth, initialInfo.picHeight, initialInfo.roiFrameWidth, initialInfo.roiFrameHeight);
if (decConfig.usePartialMode) {
JLOG(INFO, "Partial Mode Enable\n ");
JLOG(INFO, "Num of Buffer for Partial : %d\n ", decConfig.partialBufNum);
JLOG(INFO, "Num of Line for Partial : %d\n ", partialHeight);
}
framebufFormat = initialInfo.sourceFormat;
framebufWidth >>= decConfig.iHorScaleMode;
framebufHeight >>= decConfig.iVerScaleMode;
if (decConfig.iHorScaleMode || decConfig.iVerScaleMode) {
framebufHeight = ((framebufHeight + 1) / 2) * 2;
framebufWidth = ((framebufWidth + 1) / 2) * 2;
}
dispWidth = (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) ? framebufHeight : framebufWidth;
dispHeight = (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) ? framebufWidth : framebufHeight;
if (decConfig.rot_angle == 90 || decConfig.rot_angle == 270) {
framebufStrideY = framebufHeight;
framebufHeight = framebufWidth;
framebufFormat = (framebufFormat == FORMAT_422) ? FORMAT_224 :
(framebufFormat == FORMAT_224) ? FORMAT_422 : framebufFormat;
} else {
framebufStrideY = framebufWidth;
}
framebufStrideC = framebufStrideY / 2;
printf("framebufStrideY = %d, framebufStrideC = %d\n", framebufStrideY, framebufStrideC);
if (decConfig.iHorScaleMode || decConfig.iVerScaleMode)
framebufStrideY = ((framebufStrideY + 15) / 16) * 16;
if (decOP.packedFormat >= PACKED_FORMAT_422_YUYV && decOP.packedFormat <= PACKED_FORMAT_422_VYUY) {
framebufStrideY = framebufStrideY * 2;
framebufFormat = FORMAT_422;
if (decConfig.rot_angle == 90 || decConfig.rot_angle == 270)
framebufFormat = FORMAT_224;
} else if (decOP.packedFormat == PACKED_FORMAT_444) {
framebufStrideY = framebufStrideY * 3;
framebufFormat = FORMAT_444;
} else if (decOP.packedFormat == PACKED_FORMAT_NONE) {
#ifdef ALIGN_32
if (framebufFormat == FORMAT_420) {
framebufStrideY = ALIGN_X(framebufStrideY, 32);
framebufStrideC = ALIGN_X(framebufStrideY / 2, 32);
}
#endif
}
JLOG(INFO, "framebufStrideY = %d, framebufHeight = %d\n", framebufStrideY, framebufHeight);
JLOG(INFO, "framebufFormat = %d, packedFormat = %d\n", framebufFormat, decOP.packedFormat);
JLOG(INFO, "display width: %d, height = %d\n", dispWidth, dispHeight);
// Allocate frame buffer
regFrameBufCount = initialInfo.minFrameBufferCount + EXTRA_FRAME_BUFFER_NUM;
if (decConfig.usePartialMode) {
if (decConfig.partialBufNum > 4)
decConfig.partialBufNum = 4;
regFrameBufCount *= decConfig.partialBufNum;
}
needFrameBufCount = regFrameBufCount;
AllocateFrameBuffer(instIdx, framebufFormat, framebufStrideY,
framebufHeight, needFrameBufCount, 0, framebufStrideC);
JpgEnterLock();
for (i = 0; i < needFrameBufCount; ++i) {
pFrame[i] = GetFrameBuffer(instIdx, i);
frameBuf[i].bufY = pFrame[i]->vb_y.phys_addr;
JLOG(INFO, "frame buffer Y addr: 0x%lx\n", frameBuf[i].bufY);
frameBuf[i].bufCb = pFrame[i]->vb_cb.phys_addr;
JLOG(INFO, "frame buffer Cb addr: 0x%lx\n", frameBuf[i].bufCb);
if (decOP.chroma_interleave == CBCR_SEPARATED) {
frameBuf[i].bufCr = pFrame[i]->vb_cr.phys_addr;
JLOG(INFO, "frame buffer Cr addr: 0x%lx\n", frameBuf[i].bufCr);
}
if (dispImage) {
clear_frame_buffer(instIdx, i);
JLOG(INFO, ".");
}
}
JpgLeaveLock();
ret = JPU_DecGiveCommand(handle, SET_JPG_USE_PARTIAL_MODE, &decConfig.usePartialMode);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "JPU_DecGiveCommand[SET_JPG_USE_PARTIAL_MODE] failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
ret = JPU_DecGiveCommand(handle, SET_JPG_PARTIAL_FRAME_NUM, &decConfig.partialBufNum);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "JPU_DecGiveCommand[SET_JPG_PARTIAL_FRAME_NUM] failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
ret = JPU_DecGiveCommand(handle, SET_JPG_PARTIAL_LINE_NUM, &partialHeight);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "JPU_DecGiveCommand[SET_JPG_PARTIAL_LINE_NUM] failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
// Register frame buffers requested by the decoder.
ret = JPU_DecRegisterFrameBuffer(handle, frameBuf, regFrameBufCount, framebufStrideY, framebufStrideC);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "JPU_DecRegisterFrameBuffer failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
ppIdx = 0;
while (1) {
#ifdef TEST_JPEG_PERFORMANCE
u64 now = timer_get_tick(); // get_timer(0);
u64 time_consume = 0;
#endif
if (rotEnable) {
JPU_DecGiveCommand(handle, SET_JPG_ROTATION_ANGLE, &decConfig.rot_angle);
JPU_DecGiveCommand(handle, SET_JPG_MIRROR_DIRECTION, &decConfig.mirDir);
JPU_DecGiveCommand(handle, SET_JPG_ROTATOR_OUTPUT, &frameBuf[ppIdx]);
JPU_DecGiveCommand(handle, SET_JPG_ROTATOR_STRIDE, &framebufStrideY);
JPU_DecGiveCommand(handle, ENABLE_JPG_ROTATION, 0);
JPU_DecGiveCommand(handle, ENABLE_JPG_MIRRORING, 0);
}
JPU_DecGiveCommand(handle, SET_JPG_SCALE_HOR, &decConfig.iHorScaleMode);
JPU_DecGiveCommand(handle, SET_JPG_SCALE_VER, &decConfig.iVerScaleMode);
if (decConfig.usePartialMode) {
partPosIdx = 0;
partBufIdx = 0;
outputInfo.decodingSuccess = 0;
JPU_SWReset();
}
// Start decoding a frame.
ret = JPU_DecStartOneFrame(handle, &decParam);
if (ret != JPG_RET_SUCCESS && ret != JPG_RET_EOS) {
if (ret == JPG_RET_BIT_EMPTY) {
ret = WriteJpgBsBufHelper(handle, &bufInfo, decOP.bitstreamBuffer,
decOP.bitstreamBuffer + decOP.bitstreamBufferSize,
STREAM_FILL_SIZE, 0, &streameos, decOP.streamEndian);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "WriteBsBufHelper failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
continue;
}
suc = 0;
JLOG(ERR, "JPU_DecStartOneFrame failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
if (ret == JPG_RET_EOS)
goto JPU_END_OF_STREAM;
while (1) {
int_reason = JPU_WaitInterrupt(JPU_INTERRUPT_TIMEOUT_MS);
if (int_reason == -1) {
JLOG(ERR, "Error : timeout happened\n");
JPU_SWReset();
break;
}
if (decConfig.usePartialMode && (int_reason & 0xf0)) {
partBufIdx = ((partPosIdx) % decConfig.partialBufNum);
if ((1 << partBufIdx) & ((int_reason & 0xf0) >> 4)) {
printf("DECODED : PARTIAL BUFFER IDX %d / POS %d / MAX POS %d / INT_REASON=0x%x\n",
partBufIdx, partPosIdx + 1, partMaxIdx, int_reason);
if (dispImage) {
// p_disp_frame = FindFrameBuffer(instIdx,
// frameBuf[partBufIdx].bufY);
#ifdef JPU_FPGA_PLATFORM
set_mixer_dec_out_frame(p_disp_frame, framebufStrideY, partialHeight);
#endif
}
partPosIdx++;
JPU_ClrStatus((1 << (INT_JPU_PARIAL_BUF0_EMPTY + partBufIdx)));
continue;
} else {
suc = 0;
JLOG(ERR,
"Invalid partial interrupt : expected reason =0x%x, actual reason=0x%x\n",
(1 << partBufIdx), ((int_reason & 0xF0) >> 4));
goto ERR_DEC_OPEN;
}
}
if (int_reason & (1 << INT_JPU_DONE)) {
// Must catch PIC_DONE interrupt before catching EMPTY interrupt
// Do no clear INT_JPU_DONE and INT_JPU_ERROR interrupt.
// these will be cleared in JPU_DecGetOutputInfo.
JLOG(INFO, "jpeg done\n");
jpeg_done = 1;
break;
}
if (int_reason & (1 << INT_JPU_ERROR)) {
// Must catch PIC_DONE interrupt before catching EMPTY interrupt
// Do no clear INT_JPU_DONE and INT_JPU_ERROR interrupt.
// these will be cleared in JPU_DecGetOutputInfo.
break;
}
if (int_reason & (1 << INT_JPU_BIT_BUF_EMPTY)) {
ret = WriteJpgBsBufHelper(handle, &bufInfo, decOP.bitstreamBuffer,
decOP.bitstreamBuffer + decOP.bitstreamBufferSize,
STREAM_FILL_SIZE, 0, &streameos, decOP.streamEndian);
printf("write buffer in empty intterupt!\n\n");
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR,
"WriteBsBufHelper failed Error code is 0x%x\n",
ret);
goto ERR_DEC_OPEN;
}
JPU_ClrStatus((1 << INT_JPU_BIT_BUF_EMPTY));
}
if (int_reason & (1 << INT_JPU_BIT_BUF_STOP)) {
ret = JPU_DecCompleteStop(handle);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "JPU_DecCompleteStop failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
JPU_ClrStatus((1 << INT_JPU_BIT_BUF_STOP));
break;
}
if (int_reason & (1 << INT_JPU_PARIAL_OVERFLOW))
JPU_ClrStatus((1 << INT_JPU_PARIAL_OVERFLOW));
}
JPU_END_OF_STREAM:
ret = JPU_DecGetOutputInfo(handle, &outputInfo);
if (ret != JPG_RET_SUCCESS) {
suc = 0;
JLOG(ERR, "JPU_DecGetOutputInfo failed Error code is 0x%x\n", ret);
goto ERR_DEC_OPEN;
}
#ifdef TEST_JPEG_PERFORMANCE
time_consume = timer_get_tick();
JLOG(INFO, "time_consume: %ld\n", (time_consume - now) / TIMER_CNT_US);
#endif
#ifdef MJPEG_ERROR_CONCEAL
if (outputInfo.numOfErrMBs) {
int err_rst_idx, errPosX, errPosY;
err_rst_idx = (outputInfo.numOfErrMBs & 0x0F000000) >> 24;
errPosX = (outputInfo.numOfErrMBs & 0x00FFF000) >> 12;
errPosY = (outputInfo.numOfErrMBs & 0x00000FFF);
JLOG(ERR,
"Error restart Idx : %d, MCU x:%d, y:%d, in Frame : %d\n",
err_rst_idx, errPosX, errPosY, frameIdx);
continue;
}
#endif
if (outputInfo.decodingSuccess == 0)
JLOG(ERR, "JPU_DecGetOutputInfo decode fail framdIdx %d\n", frameIdx);
JLOG(INFO,
"#%d:%d, indexFrameDisplay %d || consumedByte %d || ppIdx %d || frameStart=0x%x || ecsStart=0x%x\n",
instIdx, frameIdx, outputInfo.indexFrameDisplay, outputInfo.consumedByte,
ppIdx, outputInfo.bytePosFrameStart, outputInfo.bytePosFrameStart + outputInfo.ecsPtr);
JLOG(INFO, "rdPtr=0x%x || wrPtr=0x%x || pos=%d\n",
JpuReadReg(MJPEG_BBC_RD_PTR_REG),
JpuReadReg(MJPEG_BBC_WR_PTR_REG),
JpuReadReg(MJPEG_BBC_CUR_POS_REG));
if (outputInfo.indexFrameDisplay == -1)
break;
// YUV Dump Done when partial buffer is all displayed.
int_reason = JPU_GetStatus();
if (decConfig.usePartialMode && !(int_reason & 0xF0))
goto SKIP_BUF_DUMP;
// indexFrameDisplay points to the frame buffer, among ones
// registered, which holds the output of the decoder.
if (dispImage) {
#ifdef JPU_FPGA_PLATFORM
if (frameIdx)
wait_mixer_int();
#endif
if (!rotEnable) {
#ifdef JPU_FPGA_PLATFORM
set_mixer_dec_out_frame(p_disp_frame, outputInfo.decPicWidth, outputInfo.decPicHeight);
#endif
} else {
#ifdef JPU_FPGA_PLATFORM
set_mixer_dec_out_frame(p_disp_frame,
(decConfig.rot_angle == 90 || decConfig.rot_angle == 270)
? outputInfo.decPicHeight : outputInfo.decPicWidth,
(decConfig.rot_angle == 90 || decConfig.rot_angle == 270)
? outputInfo.decPicWidth : outputInfo.decPicHeight);
#endif
ppIdx = (ppIdx - regFrameBufCount + 1) % MAX_ROT_BUF_NUM;
}
} else if (decConfig.comparatorFlag != 0) {
JLOG(INFO, "compare yuv, frameBuf[%d].bufY = 0x%lx\n", saveIdx, frameBuf[saveIdx].bufY);
JLOG(INFO, "width:%d, height:%d\n", dispWidth, dispHeight);
saveIdx = ppIdx;
if (comparateYuv((Uint8 *)frameBuf[saveIdx].bufY, pRefYuvBuf,
dispWidth, dispHeight, framebufStrideY, (int)decOP.chroma_interleave,
framebufFormat, 0, decOP.packedFormat) != 0) {
suc = 0;
}
JLOG(INFO, "compare result: %d\n", 1 - suc);
if (suc)
JLOG(ERR, "compare pass\n");
ppIdx = (ppIdx - regFrameBufCount + 1) % MAX_ROT_BUF_NUM;
}
copy_to_dest_addr((Uint8 *)frameBuf[saveIdx].bufY, pRefYuvBuf,
dispWidth, dispHeight, framebufStrideY, framebufStrideC,
(int)decOP.chroma_interleave, framebufFormat, 0, decOP.packedFormat);
SKIP_BUF_DUMP:
if (outputInfo.numOfErrMBs) {
int err_rst_idx, errPosX, errPosY;
err_rst_idx = (outputInfo.numOfErrMBs & 0x0F000000) >> 24;
errPosX = (outputInfo.numOfErrMBs & 0x00FFF000) >> 12;
errPosY = (outputInfo.numOfErrMBs & 0x00000FFF);
JLOG(ERR,
"Error restart Idx : %d, MCU x:%d, y:%d, in Frame : %d\n",
err_rst_idx, errPosX, errPosY, frameIdx);
}
frameIdx++;
if (decConfig.outNum && frameIdx == decConfig.outNum)
break;
}
if (totalNumofErrMbs) {
suc = 0;
JLOG(ERR, "Total Num of Error MBs : %d\n", totalNumofErrMbs);
}
ERR_DEC_OPEN:
// Now that we are done with decoding, close the open instance.
ret = JPU_DecClose(handle);
JLOG(INFO, "Dec End. Tot Frame %d\n", frameIdx);
ERR_DEC_INIT:
free_frame_buffer(instIdx);
jdi_free_dma_memory(&vbStream);
JPU_DeInit();
if (jpeg_done == 1) {
JLOG(INFO, "decode test done\n");
}
return suc;
}
int get_jpeg_size(int *width_addr, int *height_addr)
{
*width_addr = img_width;
*height_addr = img_height;
return 0;
}

View File

@ -0,0 +1,114 @@
#ifndef _JPU_RUN_H_
#define _JPU_RUN_H_
#include "jpuconfig.h"
#define MAX_FILE_PATH 256
typedef struct {
unsigned char *buf;
int size;
int point;
int count;
int fillendbs;
} BufInfo;
typedef struct {
char *yuvFileName;
char *bitstreamFileName;
char *huffFileName;
char *qMatFileName;
char *qpFileName;
char *cfgFileName;
int picWidth;
int picHeight;
int rot_angle;
int mirDir;
int useRot;
int mjpgChromaFormat;
int outNum;
int instNum;
int roiEnable;
int StreamEndian;
int FrameEndian;
int chroma_interleave;
int bEnStuffByte;
// altek requirement
int encHeaderMode;
char *strStmDir;
char *strCfgDir;
int usePartialMode;
int partialBufNum;
int partialHeight;
int packedFormat;
int RandRotMode;
int compareJpg;
} EncConfigParam;
typedef struct {
char *yuvFileName;
char *bitstreamFileName;
int comparatorFlag;
int rot_angle;
int mirDir;
int useRot;
int outNum;
int checkeos;
int instNum;
int StreamEndian;
int FrameEndian;
int chroma_interleave;
int iHorScaleMode;
int iVerScaleMode;
// ROI
int roiEnable;
int roiWidth;
int roiHeight;
int roiOffsetX;
int roiOffsetY;
int roiWidthInMcu;
int roiHeightInMcu;
int roiOffsetXInMcu;
int roiOffsetYInMcu;
// packed
int packedFormat;
int usePartialMode;
int partialBufNum;
int partialHeight;
int filePlay;
int size;
void *bs_addr;
void *yuv_addr;
} DecConfigParam;
enum { STD_JPG_ENC };
typedef struct {
int codecMode;
int numMulti;
int saveYuv;
int multiMode[MAX_NUM_INSTANCE];
char *multiFileName[MAX_NUM_INSTANCE];
char *multiYuvFileName[MAX_NUM_INSTANCE];
EncConfigParam encConfig[MAX_NUM_INSTANCE];
DecConfigParam decConfig[MAX_NUM_INSTANCE];
} MultiConfigParam;
#if defined(__cplusplus)
extern "C" {
#endif
int jpeg_decode_helper(DecConfigParam *param);
int EncodeTest(EncConfigParam *param);
int MultiInstanceTest(MultiConfigParam *param);
int get_jpeg_size(int *width_addr, int *height_addr);
#if defined(__cplusplus)
}
#endif
#endif /* _JPU_RUN_H_ */

View File

@ -0,0 +1,125 @@
#ifndef _JPU_TABLE_H_
#define _JPU_TABLE_H_
static unsigned char lumaDcBits[16] = {
0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static unsigned char lumaDcValue[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00,
};
static unsigned char lumaAcBits[16] = {
0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D,
};
static unsigned char lumaAcValue[168] = {
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72,
0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45,
0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75,
0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3,
0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4,
0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static unsigned char chromaDcBits[16] = {
0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static unsigned char chromaDcValue[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00,
};
static unsigned char chromaAcBits[16] = {
0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
};
static unsigned char chromaAcValue[168] = {
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1,
0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74,
0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4,
0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
#ifdef NOT_USED
static unsigned char lumaQ[64] = {
0x0C, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0C, 0x09, 0x09, 0x0C, 0x11,
0x0B, 0x0A, 0x0B, 0x11, 0x15, 0x0F, 0x0C, 0x0C, 0x0F, 0x15, 0x18,
0x13, 0x13, 0x15, 0x13, 0x13, 0x18, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
};
static unsigned char chromaBQ[64] = {
0x0D, 0x0B, 0x0B, 0x0D, 0x0E, 0x0D, 0x10, 0x0E, 0x0E, 0x10, 0x14,
0x0E, 0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
};
static unsigned char chromaRQ[64] = {
0x0D, 0x0B, 0x0B, 0x0D, 0x0E, 0x0D, 0x10, 0x0E, 0x0E, 0x10, 0x14,
0x0E, 0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
};
#endif
static unsigned char lumaQ2[64] = {
0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05, 0x05, 0x06, 0x09,
0x06, 0x05, 0x06, 0x09, 0x0B, 0x08, 0x06, 0x06, 0x08, 0x0B, 0x0C,
0x0A, 0x0A, 0x0B, 0x0A, 0x0A, 0x0C, 0x10, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x10, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
};
static unsigned char chromaBQ2[64] = {
0x07, 0x07, 0x07, 0x0D, 0x0C, 0x0D, 0x18, 0x10, 0x10, 0x18, 0x14,
0x0E, 0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
};
#ifdef NOT_USED
static unsigned char chromaRQ2[64] = {
0x07, 0x07, 0x07, 0x0D, 0x0C, 0x0D, 0x18, 0x10, 0x10, 0x18, 0x14,
0x0E, 0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
};
#endif
#endif //_JPU_TABLE_H_

View File

@ -0,0 +1,62 @@
#ifndef _JPU_TYPES_H_
#define _JPU_TYPES_H_
typedef unsigned int UINT;
typedef unsigned char Uint8;
typedef unsigned int Uint32;
typedef unsigned short Uint16;
typedef char Int8;
typedef int Int32;
typedef short Int16;
#if defined(_MSC_VER)
typedef unsigned _int64 Uint64;
typedef _int64 Int64;
#else
typedef unsigned long Uint64;
typedef long Int64;
#endif
typedef Uint64 PhysicalAddress;
typedef unsigned char BYTE;
typedef int BOOL;
#ifndef HAVE_STDIN_H
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
#if defined(_MSC_VER)
typedef unsigned _int64 uint64_t;
typedef _int64 int64_t;
#else
#endif
#ifndef __int8_t_defined
typedef signed char int8_t;
#endif
typedef int int32_t;
typedef short int16_t;
#ifndef BYTE
typedef unsigned char BYTE;
#endif
#ifndef BOOL
typedef int BOOL;
#endif
#endif
#ifndef NULL
#define NULL 0
#endif
#if defined(linux) || defined(__linux) || defined(ANDROID)
#define TRUE 1
#define FALSE 0
#endif
#endif /* _JPU_TYPES_H_ */

View File

@ -0,0 +1,373 @@
//#include <stdio.h>
#include "jpuapi.h"
#include "jpuhelper.h"
#include "jpulog.h"
#include "mixer.h"
#include "regdefine.h"
#include <linux/string.h>
#include <stdlib.h>
typedef struct {
FRAME_BUF frameBuf[MAX_FRAME];
jpu_buffer_t vb_base;
int instIndex;
int last_num;
unsigned long last_addr;
} fb_context;
static fb_context s_fb[MAX_NUM_INSTANCE];
int AllocateFrameBuffer(int instIdx, int format, int strideY, int height,
int frameBufNum, int pack, int strideC)
{
unsigned int divX, divY;
int i;
unsigned int lum_size, chr_size;
fb_context *fb;
fb = &s_fb[instIdx];
divX = format == FORMAT_420 || format == FORMAT_422 ? 2 : 1;
divY = format == FORMAT_420 || format == FORMAT_224 ? 2 : 1;
switch (format) {
case FORMAT_420:
height = (height + 1) / 2 * 2;
strideY = (strideY + 1) / 2 * 2;
break;
case FORMAT_224:
height = (height + 1) / 2 * 2;
break;
case FORMAT_422:
strideY = (strideY + 1) / 2 * 2;
break;
case FORMAT_444:
height = (height + 1) / 2 * 2;
strideY = (strideY + 1) / 2 * 2;
break;
case FORMAT_400:
height = (height + 1) / 2 * 2;
strideY = (strideY + 1) / 2 * 2;
break;
}
lum_size = (unsigned int)strideY * (unsigned int)height;
if (pack)
chr_size = 0;
else {
if (format == FORMAT_420)
chr_size = strideC * height / divY;
else
chr_size = lum_size / divX / divY;
}
fb->vb_base.size = lum_size + chr_size * 2;
fb->vb_base.size *= frameBufNum;
if (jdi_allocate_dma_memory(&fb->vb_base) < 0) {
JLOG(ERR, "Fail to allocate frame buffer size=%d\n", fb->vb_base.size);
return 0;
}
fb->last_addr = fb->vb_base.phys_addr;
for (i = fb->last_num; i < fb->last_num + frameBufNum; i++) {
fb->frameBuf[i].Format = format;
fb->frameBuf[i].Index = i;
fb->frameBuf[i].vb_y.phys_addr = fb->last_addr;
fb->frameBuf[i].vb_y.size = lum_size;
fb->last_addr += fb->frameBuf[i].vb_y.size;
fb->last_addr = ((fb->last_addr + 7) & ~7);
if (chr_size) {
fb->frameBuf[i].vb_cb.phys_addr = fb->last_addr;
fb->frameBuf[i].vb_cb.size = chr_size;
fb->last_addr += fb->frameBuf[i].vb_cb.size;
fb->last_addr = ((fb->last_addr + 7) & ~7);
fb->frameBuf[i].vb_cr.phys_addr = fb->last_addr;
fb->frameBuf[i].vb_cr.size = chr_size;
fb->last_addr += fb->frameBuf[i].vb_cr.size;
fb->last_addr = ((fb->last_addr + 7) & ~7);
}
fb->frameBuf[i].strideY = strideY;
if (format == FORMAT_420)
fb->frameBuf[i].strideC = strideC;
else
fb->frameBuf[i].strideC = strideY / divX;
}
fb->last_num += frameBufNum;
return 1;
}
int GetFrameBufBase(int instIdx)
{
fb_context *fb;
fb = &s_fb[instIdx];
return fb->vb_base.phys_addr;
}
int GetFrameBufAllocSize(int instIdx)
{
fb_context *fb;
fb = &s_fb[instIdx];
return (fb->last_addr - fb->vb_base.phys_addr);
}
FRAME_BUF *GetFrameBuffer(int instIdx, int index)
{
fb_context *fb;
fb = &s_fb[instIdx];
return &fb->frameBuf[index];
}
FRAME_BUF *find_frame_buffer(int instIdx, PhysicalAddress addrY)
{
int i;
fb_context *fb;
fb = &s_fb[instIdx];
for (i = 0; i < MAX_FRAME; i++) {
if (fb->frameBuf[i].vb_y.phys_addr == addrY) {
return &fb->frameBuf[i];
}
}
return NULL;
}
void clear_frame_buffer(int instIdx, int index)
{
}
void free_frame_buffer(int instIdx)
{
fb_context *fb;
fb = &s_fb[instIdx];
fb->last_num = 0;
fb->last_addr = -1;
jdi_free_dma_memory(&fb->vb_base);
fb->vb_base.base = 0;
fb->vb_base.size = 0;
}
#ifdef JPU_FPGA_PLATFORM
//------------------------------------------------------------------------------
// MIXER REGISTER ADDRESS
//------------------------------------------------------------------------------
#define MIX_BASE 0x1000000
#define DISP_MIX 0x2000000
#define MIX_INT (MIX_BASE + 0x044)
#define MIX_STRIDE_Y (MIX_BASE + 0x144)
#define MIX_STRIDE_CB (MIX_BASE + 0x148)
#define MIX_STRIDE_CR (MIX_BASE + 0x14c)
#define MIX_ADDR_Y (MIX_BASE + 0x138)
#define MIX_ADDR_CB (MIX_BASE + 0x13C)
#define MIX_ADDR_CR (MIX_BASE + 0x140)
#define MIX_RUN (MIX_BASE + 0x120)
#define DISP_TOTAL_SAMPLE (DISP_MIX + 0x00C)
#define DISP_ACTIVE_SAMPLE (DISP_MIX + 0x010)
#define DISP_HSYNC_START_END (DISP_MIX + 0x014)
#define DISP_VSYNC_TOP_START (DISP_MIX + 0x018)
#define DISP_VSYNC_TOP_END (DISP_MIX + 0x01C)
#define DISP_VSYNC_BOT_START (DISP_MIX + 0x020)
#define DISP_VSYNC_BOT_END (DISP_MIX + 0x024)
#define DISP_ACTIVE_REGION_TOP (DISP_MIX + 0x02C)
#define DISP_ACTIVE_REGION_BOT (DISP_MIX + 0x030)
#define MIX_MIX_INTRPT (MIX_BASE + 0x0000)
#define MIX_SYNC_STATE (MIX_BASE + 0x0004)
#define MIX_SYNC_CTRL (MIX_BASE + 0x0008)
#define MIX_TOTAL_SAMPLE (MIX_BASE + 0x000c)
#define MIX_ACTIVE_SAMPLE (MIX_BASE + 0x0010)
#define MIX_HSYNC_START_END (MIX_BASE + 0x0014)
#define MIX_VSYNC_TOP_START (MIX_BASE + 0x0018)
#define MIX_VSYNC_TOP_END (MIX_BASE + 0x001c)
#define MIX_VSYNC_BOT_START (MIX_BASE + 0x0020)
#define MIX_VSYNC_BOT_END (MIX_BASE + 0x0024)
#define MIX_ACT_REGION_SAMPLE (MIX_BASE + 0x0028)
#define MIX_ACT_REGION_TOP (MIX_BASE + 0x002c)
#define MIX_ACT_REGION_BOT (MIX_BASE + 0x0030)
#define MIX_TOP_START (MIX_BASE + 0x0034)
#define MIX_BOT_START (MIX_BASE + 0x0038)
#define MIX_LINE_INC (MIX_BASE + 0x003c)
#define MIX_LATCH_PARAM_CTRL (MIX_BASE + 0x0040)
#define MIX_INTERRUPT (MIX_BASE + 0x0044)
#define MIX_LAYER_CTRL (MIX_BASE + 0x0100)
#define MIX_LAYER_ORDER (MIX_BASE + 0x0104)
#define MIX_BIG_ENDIAN (MIX_BASE + 0x0108)
#define MIX_L0_BG_COLOR (MIX_BASE + 0x0110)
#define MIX_L1_CTRL (MIX_BASE + 0x0120)
#define MIX_L1_LSIZE (MIX_BASE + 0x0124)
#define MIX_L1_SSIZE (MIX_BASE + 0x0128)
#define MIX_L1_LPOS (MIX_BASE + 0x012c)
#define MIX_L1_SPOS (MIX_BASE + 0x0130)
#define MIX_L1_BG_COLOR (MIX_BASE + 0x0134)
#define MIX_L1_Y_SADDR (MIX_BASE + 0x0138)
#define MIX_L1_CB_SADDR (MIX_BASE + 0x013c)
#define MIX_L1_CR_SADDR (MIX_BASE + 0x0140)
#define MIX_L1_Y_STRIDE (MIX_BASE + 0x0144)
#define MIX_L1_CB_STRIDE (MIX_BASE + 0x0148)
#define MIX_L1_CR_STRIDE (MIX_BASE + 0x014c)
int SetMixerDecOutFrame(FRAME_BUF *pFrame, int width, int height)
{
int staX, staY;
int div;
staX = (MAX_DISPLAY_WIDTH - width) / 2;
if (height > MAX_DISPLAY_HEIGHT)
staY = 0;
else
staY = (MAX_DISPLAY_HEIGHT - height) / 2;
if (staX % 16)
staX = (staX + 15) / 16 * 16;
JpuWriteReg(MIX_L0_BG_COLOR, (0 << 16) | (0x80 << 8) | 0x80);
JpuWriteReg(MIX_L1_LSIZE, (height << 12) | width);
JpuWriteReg(MIX_L1_SSIZE, (height << 12) | width);
JpuWriteReg(MIX_L1_LPOS, (staY << 12) | staX);
div = (pFrame->Format == FORMAT_420 || pFrame->Format == FORMAT_422 ||
pFrame->Format == FORMAT_400)
? 2
: 1;
JpuWriteReg(MIX_STRIDE_Y, width);
JpuWriteReg(MIX_STRIDE_CB, width / div);
JpuWriteReg(MIX_STRIDE_CR, width / div);
JpuWriteReg(MIX_ADDR_Y, pFrame->vb_y.phys_addr);
JpuWriteReg(MIX_ADDR_CB, pFrame->vb_cb.phys_addr);
JpuWriteReg(MIX_ADDR_CR, pFrame->vb_cr.phys_addr);
JpuWriteReg(DISP_HSYNC_START_END,
((0x7d7 - 40) << 12) | (0x82f - 40)); // horizontal center
JpuWriteReg(DISP_ACTIVE_REGION_TOP, ((0x014 - 2) << 12) | (0x230 - 2));
JpuWriteReg(DISP_ACTIVE_REGION_BOT, ((0x247 - 2) << 12) | (0x463 - 2));
JpuWriteReg(MIX_LAYER_CTRL, 0x3); // backgroup on
JpuWriteReg(MIX_RUN, 0x92); // on, vdec, from sdram
return 1;
}
int SetMixerDecOutLayer(int instIdx, int index, int width, int height)
{
FRAME_BUF *pFrame;
int staX, staY;
int div;
pFrame = GetFrameBuffer(instIdx, index);
staX = (MAX_DISPLAY_WIDTH - width) / 2;
if (height > MAX_DISPLAY_HEIGHT)
staY = 0;
else
staY = (MAX_DISPLAY_HEIGHT - height) / 2;
if (staX % 16)
staX = (staX + 15) / 16 * 16;
JpuWriteReg(MIX_L0_BG_COLOR, (0 << 16) | (0x80 << 8) | 0x80);
JpuWriteReg(MIX_L1_LSIZE, (height << 12) | width);
JpuWriteReg(MIX_L1_SSIZE, (height << 12) | width);
JpuWriteReg(MIX_L1_LPOS, (staY << 12) | staX);
div = (pFrame->Format == FORMAT_420 || pFrame->Format == FORMAT_422 ||
pFrame->Format == FORMAT_400)
? 2
: 1;
JpuWriteReg(MIX_STRIDE_Y, width);
JpuWriteReg(MIX_STRIDE_CB, width / div);
JpuWriteReg(MIX_STRIDE_CR, width / div);
JpuWriteReg(MIX_ADDR_Y, pFrame->vb_y.phys_addr);
JpuWriteReg(MIX_ADDR_CB, pFrame->vb_cb.phys_addr);
JpuWriteReg(MIX_ADDR_CR, pFrame->vb_cr.phys_addr);
JpuWriteReg(DISP_HSYNC_START_END, ((0x7d7 - 40) << 12) | (0x82f - 40)); // horizontal center
JpuWriteReg(DISP_ACTIVE_REGION_TOP, ((0x014 - 2) << 12) | (0x230 - 2));
JpuWriteReg(DISP_ACTIVE_REGION_BOT, ((0x247 - 2) << 12) | (0x463 - 2));
JpuWriteReg(MIX_LAYER_CTRL, 0x3); // backgroup on
JpuWriteReg(MIX_RUN, 0x92); // on, vdec, from sdram
return 1;
}
void wait_mixer_int(void)
{
int data;
return;
if (JpuReadReg(MIX_INT) == 1)
JpuWriteReg(MIX_INT, 0);
while (1) {
data = JpuReadReg(MIX_INT);
if (data & 1)
break;
}
JpuWriteReg(MIX_INT, 0);
}
#endif
#ifdef PLATFORM_LINUX
#include <linux/fb.h>
#define FBDEV_FILENAME "/dev/fb0"
typedef struct {
int s_fd;
unsigned char *s_scr_ptr;
unsigned char *s_rgb_ptr;
unsigned long s_product;
int s_fb_stride;
int s_fb_height;
int s_fb_width;
int s_fb_bpp;
} sw_mixer_context_t;
#endif // PLATFORM_LINUX
int sw_mixer_open(int instIdx, int width, int height)
{
return 0;
}
int sw_mixer_draw(int instIdx, int x, int y, int width, int height,
int planar_format, int pack_format, int interleave,
unsigned char *pbImage)
{
return 0;
}
void sw_mixer_close(int instIdx)
{
}

View File

@ -0,0 +1,47 @@
#ifndef _MIXER_H_
#define _MIXER_H_
#include "jpuconfig.h"
typedef struct {
int Format;
int Index;
jpu_buffer_t vb_y;
jpu_buffer_t vb_cb;
jpu_buffer_t vb_cr;
int strideY;
int strideC;
} FRAME_BUF;
#define MAX_DISPLAY_WIDTH 1920
#define MAX_DISPLAY_HEIGHT 1088
#if defined(__cplusplus)
extern "C" {
#endif
int AllocateFrameBuffer(int instIdx, int format, int strideY, int height,
int frameBufNum, int pack, int strideC);
void free_frame_buffer(int instIdx);
FRAME_BUF *GetFrameBuffer(int instIdx, int index);
int GetFrameBufBase(int instIdx);
int GetFrameBufAllocSize(int instIdx);
void clear_frame_buffer(int instIdx, int index);
FRAME_BUF *find_frame_buffer(int instIdx, PhysicalAddress addrY);
#ifdef JPU_FPGA_PLATFORM
int SetMixerDecOutLayer(int instIdx, int index, int picX, int picY);
int SetMixerDecOutFrame(FRAME_BUF *pFrame, int width, int height);
void wait_mixer_int(void);
#endif
int sw_mixer_open(int instIdx, int width, int height);
int sw_mixer_draw(int instIdx, int x, int y, int width, int height,
int planar_format, int pack_format, int inteleave,
unsigned char *pbImage);
void sw_mixer_close(int instIdx);
#if defined(__cplusplus)
}
#endif
#endif //#ifndef _MIXER_H_

View File

@ -0,0 +1,582 @@
#include <stdlib.h>
#include "mm.h"
#include "jdi_osal.h"
#include <common.h>
#include "jpulog.h"
#define P_ALLOC(_x) OSAL_MALLOC(_x)
#define P_FREE(_x) OSAL_FREE(_x)
//#define assert(_exp) // if (!(_exp)) { osal_printf("assert at %s:%d\n", __FILE__, __LINE__); while(1); }
#define HEIGHT(_tree) (!(_tree) ? -1 : _tree->height)
/*
* doubly linked list
*/
#define MAX(_a, _b) ((_a) >= (_b) ? (_a) : (_b))
enum {
LEFT,
RIGHT
} rotation_dir_t;
struct avl_node_data {
int key;
page_t *page;
} avl_node_data_t;
static avl_node_t *make_avl_node(vmem_key_t key, page_t *page)
{
avl_node_t *node = (avl_node_t *)
josal_malloc(sizeof(avl_node_t));
node->key = key;
node->page = page;
node->height = 0;
node->left = NULL;
node->right = NULL;
return node;
}
static int get_balance_factor(avl_node_t *tree)
{
int factor = 0;
if (tree) {
factor = HEIGHT(tree->right) - HEIGHT(tree->left);
}
return factor;
}
/*
* Left Rotation
*
* A B
* \ / \
* B => A C
* / \ \
* D C D
*
*/
static avl_node_t *rotation_left(avl_node_t *tree)
{
avl_node_t *rchild;
avl_node_t *lchild;
if (!tree)
return NULL;
rchild = tree->right;
if (!rchild) {
return tree;
}
lchild = rchild->left;
rchild->left = tree;
tree->right = lchild;
tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
rchild->height = MAX(HEIGHT(rchild->left), HEIGHT(rchild->right)) + 1;
return rchild;
}
/*
* Reft Rotation
*
* A B
* \ / \
* B => D A
* / \ /
* D C C
*
*/
static avl_node_t *rotation_right(avl_node_t *tree)
{
avl_node_t *rchild;
avl_node_t *lchild;
if (!tree)
return NULL;
lchild = tree->left;
if (!lchild)
return NULL;
rchild = lchild->right;
lchild->right = tree;
tree->left = rchild;
tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
lchild->height = MAX(HEIGHT(lchild->left), HEIGHT(lchild->right)) + 1;
return lchild;
}
static avl_node_t *do_balance(avl_node_t *tree)
{
int bfactor = 0, child_bfactor; /* balancing factor */
bfactor = get_balance_factor(tree);
if (bfactor >= 2) {
child_bfactor = get_balance_factor(tree->right);
if (child_bfactor == 1 || child_bfactor == 0) {
tree = rotation_left(tree);
} else if (child_bfactor == -1) {
tree->right = rotation_right(tree->right);
tree = rotation_left(tree);
} else {
//fprintf(stderr, "invalid balancing factor: %d\n", child_bfactor);
assert(0);
return NULL;
}
} else if (bfactor <= -2) {
child_bfactor = get_balance_factor(tree->left);
if (child_bfactor == -1 || child_bfactor == 0) {
tree = rotation_right(tree);
} else if (child_bfactor == 1) {
tree->left = rotation_left(tree->left);
tree = rotation_right(tree);
} else {
//fprintf(stderr, "invalid balancing factor: %d\n", child_bfactor);
assert(0);
return NULL;
}
}
return tree;
}
static avl_node_t *unlink_end_node(avl_node_t *tree, int dir, avl_node_t **found_node)
{
// avl_node_t* node;
*found_node = NULL;
if (!tree)
return NULL;
if (dir == LEFT) {
if (!tree->left) {
*found_node = tree;
return NULL;
}
} else {
if (!tree->right) {
*found_node = tree;
return NULL;
}
}
if (dir == LEFT) {
// node = tree->left;
tree->left = unlink_end_node(tree->left, LEFT, found_node);
if (!tree->left) {
tree->left = (*found_node)->right;
(*found_node)->left = NULL;
(*found_node)->right = NULL;
}
} else {
// node = tree->right;
tree->right = unlink_end_node(tree->right, RIGHT, found_node);
if (!tree->right) {
tree->right = (*found_node)->left;
(*found_node)->left = NULL;
(*found_node)->right = NULL;
}
}
tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
return do_balance(tree);
}
static avl_node_t *avltree_insert(avl_node_t *tree, vmem_key_t key, page_t *page)
{
if (!tree) {
tree = make_avl_node(key, page);
} else {
if (key >= tree->key) {
tree->right = avltree_insert(tree->right, key, page);
} else {
tree->left = avltree_insert(tree->left, key, page);
}
}
tree = do_balance(tree);
tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
return tree;
}
static avl_node_t *do_unlink(avl_node_t *tree)
{
avl_node_t *node;
avl_node_t *end_node;
node = unlink_end_node(tree->right, LEFT, &end_node);
if (node) {
tree->right = node;
} else {
node = unlink_end_node(tree->left, RIGHT, &end_node);
if (node)
tree->left = node;
}
if (!node) {
node = tree->right ? tree->right : tree->left;
end_node = node;
}
if (end_node) {
end_node->left = (tree->left != end_node) ? tree->left : end_node->left;
end_node->right = (tree->right != end_node) ? tree->right : end_node->right;
end_node->height = MAX(HEIGHT(end_node->left), HEIGHT(end_node->right)) + 1;
}
tree = end_node;
return tree;
}
static avl_node_t *avltree_remove(avl_node_t *tree, avl_node_t **found_node, vmem_key_t key)
{
*found_node = NULL;
if (!tree) {
// DPRINT("failed to find key %d\n", key);
return NULL;
}
if (key == tree->key) {
*found_node = tree;
tree = do_unlink(tree);
} else if (key > tree->key) {
tree->right = avltree_remove(tree->right, found_node, key);
} else {
tree->left = avltree_remove(tree->left, found_node, key);
}
if (tree)
tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
tree = do_balance(tree);
return tree;
}
void jpu_avltree_free(avl_node_t *tree)
{
if (!tree)
return;
if (!tree->left && !tree->right) {
P_FREE(tree);
return;
}
jpu_avltree_free(tree->left);
tree->left = NULL;
jpu_avltree_free(tree->right);
tree->right = NULL;
}
static avl_node_t *remove_approx_value(avl_node_t *tree, avl_node_t **found, vmem_key_t key)
{
*found = NULL;
if (!tree) {
return NULL;
}
if (key == tree->key) {
*found = tree;
tree = do_unlink(tree);
} else if (key > tree->key) {
tree->right = remove_approx_value(tree->right, found, key);
} else {
tree->left = remove_approx_value(tree->left, found, key);
if (!*found) {
*found = tree;
tree = do_unlink(tree);
}
}
if (tree)
tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
tree = do_balance(tree);
return tree;
}
static void set_blocks_free(jpeg_mm_t *mm, int pageno, int npages)
{
int last_pageno = pageno + npages - 1;
int i;
page_t *page;
page_t *last_page;
assert(npages);
if (last_pageno >= mm->num_pages) {
// DPRINT("set_blocks_free: invalid last page number: %d\n", last_pageno);
assert(0);
return;
}
for (i = pageno; i <= last_pageno; i++) {
mm->page_list[i].used = 0;
mm->page_list[i].alloc_pages = 0;
mm->page_list[i].first_pageno = -1;
}
page = &mm->page_list[pageno];
page->alloc_pages = npages;
last_page = &mm->page_list[last_pageno];
last_page->first_pageno = pageno;
mm->free_tree = avltree_insert(mm->free_tree, MAKE_KEY(npages, pageno), page);
}
static void set_blocks_alloc(jpeg_mm_t *mm, int pageno, int npages)
{
int last_pageno = pageno + npages - 1;
int i;
page_t *page;
page_t *last_page;
if (last_pageno >= mm->num_pages) {
// DPRINT("set_blocks_free: invalid last page number: %d\n", last_pageno);
assert(0);
return;
}
for (i = pageno; i <= last_pageno; i++) {
mm->page_list[i].used = 1;
mm->page_list[i].alloc_pages = 0;
mm->page_list[i].first_pageno = -1;
}
page = &mm->page_list[pageno];
page->alloc_pages = npages;
last_page = &mm->page_list[last_pageno];
last_page->first_pageno = pageno;
mm->alloc_tree = avltree_insert(mm->alloc_tree, MAKE_KEY(page->addr, 0), page);
}
int jmem_init(jpeg_mm_t *mm, unsigned long addr, unsigned long size)
{
int i;
mm->base_addr = (addr + (VMEM_PAGE_SIZE - 1)) & ~(VMEM_PAGE_SIZE - 1);
mm->mem_size = size & ~VMEM_PAGE_SIZE;
mm->num_pages = mm->mem_size / VMEM_PAGE_SIZE;
mm->page_list = (page_t *)
P_ALLOC(mm->num_pages * sizeof(page_t));
mm->free_tree = NULL;
mm->alloc_tree = NULL;
mm->free_page_count = mm->num_pages;
mm->alloc_page_count = 0;
// printf("page list addr: 0x%llx\n", mm->page_list);
for (i = 0; i < mm->num_pages; i++) {
mm->page_list[i].pageno = i;
mm->page_list[i].addr = mm->base_addr + i * VMEM_PAGE_SIZE;
mm->page_list[i].alloc_pages = 0;
mm->page_list[i].used = 0;
mm->page_list[i].first_pageno = -1;
}
set_blocks_free(mm, 0, mm->num_pages);
return 0;
}
int jmem_exit(jpeg_mm_t *mm)
{
if (!mm) {
// DPRINT("vmem_exit: invalid handle\n");
return -1;
}
if (mm->free_tree) {
jpu_avltree_free(mm->free_tree);
}
if (mm->alloc_tree) {
jpu_avltree_free(mm->alloc_tree);
}
P_FREE(mm->page_list);
return 0;
}
unsigned long jmem_alloc(jpeg_mm_t *mm, unsigned int size, unsigned long pid)
{
avl_node_t *node;
page_t *free_page;
int npages, free_size;
int alloc_pageno;
unsigned long ptr;
if (!mm) {
// DPRINT("vmem_alloc: invalid handle\n");
return -1;
}
if (size <= 0)
return -1;
npages = (size + VMEM_PAGE_SIZE - 1) / VMEM_PAGE_SIZE;
mm->free_tree = remove_approx_value(mm->free_tree, &node, MAKE_KEY(npages, 0));
if (!node) {
return -1;
}
free_page = node->page;
free_size = KEY_TO_VALUE(node->key);
alloc_pageno = free_page->pageno;
set_blocks_alloc(mm, alloc_pageno, npages);
if (npages != free_size) {
int free_pageno = alloc_pageno + npages;
set_blocks_free(mm, free_pageno, (free_size - npages));
}
P_FREE(node);
ptr = mm->page_list[alloc_pageno].addr;
mm->alloc_page_count += npages;
mm->free_page_count -= npages;
return ptr;
}
int jmem_free(jpeg_mm_t *mm, unsigned long ptr, unsigned long pid)
{
unsigned long addr;
avl_node_t *found;
page_t *page;
int pageno, prev_free_pageno, next_free_pageno;
int prev_size, next_size;
int merge_page_no, merge_page_size, free_page_size;
if (!mm) {
// DPRINT("vmem_free: invalid handle\n");
return -1;
}
addr = ptr;
mm->alloc_tree = avltree_remove(mm->alloc_tree, &found, MAKE_KEY(addr, 0));
if (!found) {
// DPRINT("vmem_free: 0x%08x not found\n", addr);
return -1;
}
/* find previous free block */
page = found->page;
pageno = page->pageno;
free_page_size = page->alloc_pages;
prev_free_pageno = pageno - 1;
prev_size = -1;
if (prev_free_pageno >= 0) {
if (mm->page_list[prev_free_pageno].used == 0) {
prev_free_pageno = mm->page_list[prev_free_pageno].first_pageno;
prev_size = mm->page_list[prev_free_pageno].alloc_pages;
}
}
/* find next free block */
next_free_pageno = pageno + page->alloc_pages;
next_free_pageno = (next_free_pageno == mm->num_pages) ? -1 : next_free_pageno;
next_size = -1;
if (next_free_pageno >= 0) {
if (mm->page_list[next_free_pageno].used == 0) {
next_size = mm->page_list[next_free_pageno].alloc_pages;
}
}
P_FREE(found);
/* merge */
merge_page_no = page->pageno;
merge_page_size = page->alloc_pages;
if (prev_size >= 0) {
mm->free_tree = avltree_remove(mm->free_tree, &found, MAKE_KEY(prev_size, prev_free_pageno));
if (!found) {
assert(0);
return -1;
}
merge_page_no = found->page->pageno;
merge_page_size += found->page->alloc_pages;
P_FREE(found);
}
if (next_size >= 0) {
mm->free_tree = avltree_remove(mm->free_tree, &found, MAKE_KEY(next_size, next_free_pageno));
if (!found) {
assert(0);
return -1;
}
merge_page_size += found->page->alloc_pages;
P_FREE(found);
}
page->alloc_pages = 0;
page->first_pageno = -1;
set_blocks_free(mm, merge_page_no, merge_page_size);
mm->alloc_page_count -= free_page_size;
mm->free_page_count += free_page_size;
return 0;
}
int jmem_get_info(jpeg_mm_t *mm, jmem_info_t *info)
{
if (!mm) {
// DPRINT("vmem_get_info: invalid handle\n");
return -1;
}
if (!info) {
return -1;
}
info->total_pages = mm->num_pages;
info->alloc_pages = mm->alloc_page_count;
info->free_pages = mm->free_page_count;
info->page_size = VMEM_PAGE_SIZE;
return 0;
}

View File

@ -0,0 +1,71 @@
#ifndef __JPU_VIDEO_MEMORY_MANAGEMENT_H__
#define __JPU_VIDEO_MEMORY_MANAGEMENT_H__
typedef struct _jmem_info_struct {
unsigned long total_pages;
unsigned long alloc_pages;
unsigned long free_pages;
unsigned long page_size;
} jmem_info_t;
#if defined(WIN32) || defined(WIN64)
#if (_MSC_VER == 1200)
typedef _int64 vmem_key_t;
#else
typedef unsigned long long vmem_key_t;
#endif
#else
typedef unsigned long long vmem_key_t;
#endif
#define VMEM_PAGE_SIZE (16 * 1024)
#define MAKE_KEY(_a, _b) (((vmem_key_t)(_a)) << 32 | (_b))
#define KEY_TO_VALUE(_key) ((_key) >> 32)
typedef struct page_struct {
int pageno;
unsigned long addr;
int used;
int alloc_pages;
int first_pageno;
} page_t;
typedef struct avl_node_struct {
vmem_key_t key;
int height;
page_t *page;
struct avl_node_struct *left;
struct avl_node_struct *right;
} avl_node_t;
typedef struct _jpeg_mm_struct {
avl_node_t *free_tree;
avl_node_t *alloc_tree;
page_t *page_list;
int num_pages;
unsigned long base_addr;
unsigned long mem_size;
void *mutex;
int free_page_count;
int alloc_page_count;
} jpeg_mm_t;
#if defined(__cplusplus)
extern "C" {
#endif
extern int jmem_init(jpeg_mm_t *mm, unsigned long addr, unsigned long size);
extern int jmem_exit(jpeg_mm_t *mm);
extern unsigned long jmem_alloc(jpeg_mm_t *mm, unsigned int size, unsigned long pid);
extern int jmem_free(jpeg_mm_t *mm, unsigned long ptr, unsigned long pid);
extern int jmem_get_info(jpeg_mm_t *mm, jmem_info_t *info);
#if defined(__cplusplus)
}
#endif
#endif /* __JPU_VIDEO_MEMORY_MANAGEMENT_H__ */

View File

@ -0,0 +1,162 @@
#include "config.h"
#ifndef NPT_REGDEFINE_H_INCLUDED
#define NPT_REGDEFINE_H_INCLUDED
//------------------------------------------------------------------------------
// REGISTER BASE
//------------------------------------------------------------------------------
#define TOP_BASE 0x03000000
#define TOP_USB_PHY_CTRSTS_REG (TOP_BASE + 0x48)
#define UPCR_EXTERNAL_VBUS_VALID_OFFSET 0
#define TOP_DDR_ADDR_MODE_REG (TOP_BASE + 0x64)
#define DAMR_REG_USB_REMAP_ADDR_39_32_OFFSET 16
#define DAMR_REG_USB_REMAP_ADDR_39_32_MSK (0xff)
#define DAMR_REG_VD_REMAP_ADDR_39_32_OFFSET 24
#define DAMR_REG_VD_REMAP_ADDR_39_32_MSK (0xff)
#define JPEG_INTRPT_REQ 75
#define NPT_REG_SIZE 0x300
#define NPT_REG_BASE (void *)(0x10000000 + 0x3000)
#define VC_REG_BASE (void *)(0x0B000000 + 0x30000)
#define NPT_BASE 0x00
/*--------------------------------------------------------------------
* NIEUPORT REGISTERS
*------------------------------------------------------------------
*/
// MAIN CONTROL REGISTER
// [3] - start partial encoding [2] - pic stop en/decoding[1] - pic init
// en/decoding [0] - pic start en/decoding
#define MJPEG_PIC_START_REG (NPT_BASE + 0x000)
// [8] - stop [7:4] - partial buffer interrupt [3] - overflow, [2] - bbc
// interrupt, [1] - error, [0] - done
#define MJPEG_PIC_STATUS_REG (NPT_BASE + 0x004)
// [27:24] - error restart idx, [23:12] - error MCU pos X, [11:0] - error MCU
// pos Y
#define MJPEG_PIC_ERRMB_REG (NPT_BASE + 0x008)
// [27:16] - MCU pos X, [11:0] - MCU pos Y
#define MJPEG_PIC_SETMB_REG (NPT_BASE + 0x00C)
// [12:7] huffman table index [6] - user huffman en, [4] - TC direction, [3] -
// encoder enable, [1:0] - operation mode
#define MJPEG_PIC_CTRL_REG (NPT_BASE + 0x010)
#define MJPEG_PIC_SIZE_REG (NPT_BASE + 0x014)
#define MJPEG_MCU_INFO_REG (NPT_BASE + 0x018)
// [4] - rot-mir enable, [3:0] - rot-mir mode
#define MJPEG_ROT_INFO_REG (NPT_BASE + 0x01C)
#define MJPEG_SCL_INFO_REG (NPT_BASE + 0x020)
// [1] - sensor interface clear, [0] - display interface clear
#define MJPEG_IF_INFO_REG (NPT_BASE + 0x024)
#define MJPEG_CLP_INFO_REG (NPT_BASE + 0x028)
// [31:16] - # of line in 1 partial buffer, [5:3] - # of partial buffers [2:0] -
// # of request
#define MJPEG_OP_INFO_REG (NPT_BASE + 0x02C)
#define MJPEG_DPB_CONFIG_REG (NPT_BASE + 0x030)
#define MJPEG_DPB_BASE00_REG (NPT_BASE + 0x034)
#define MJPEG_DPB_BASE01_REG (NPT_BASE + 0x038)
#define MJPEG_DPB_BASE02_REG (NPT_BASE + 0x03C)
#define MJPEG_DPB_BASE10_REG (NPT_BASE + 0x040)
#define MJPEG_DPB_BASE11_REG (NPT_BASE + 0x044)
#define MJPEG_DPB_BASE12_REG (NPT_BASE + 0x048)
#define MJPEG_DPB_BASE20_REG (NPT_BASE + 0x04C)
#define MJPEG_DPB_BASE21_REG (NPT_BASE + 0x050)
#define MJPEG_DPB_BASE22_REG (NPT_BASE + 0x054)
#define MJPEG_DPB_BASE30_REG (NPT_BASE + 0x058)
#define MJPEG_DPB_BASE31_REG (NPT_BASE + 0x05C)
#define MJPEG_DPB_BASE32_REG (NPT_BASE + 0x060)
#define MJPEG_DPB_YSTRIDE_REG (NPT_BASE + 0x064)
#define MJPEG_DPB_CSTRIDE_REG (NPT_BASE + 0x068)
#define MJPEG_WRESP_CHECK_REG (NPT_BASE + 0x06C)
#define MJPEG_CLP_BASE_REG (NPT_BASE + 0x070)
#define MJPEG_CLP_SIZE_REG (NPT_BASE + 0x074)
#define MJPEG_HUFF_CTRL_REG (NPT_BASE + 0x080)
#define MJPEG_HUFF_ADDR_REG (NPT_BASE + 0x084)
#define MJPEG_HUFF_DATA_REG (NPT_BASE + 0x088)
#define MJPEG_QMAT_CTRL_REG (NPT_BASE + 0x090)
#define MJPEG_QMAT_ADDR_REG (NPT_BASE + 0x094)
#define MJPEG_QMAT_DATA_REG (NPT_BASE + 0x098)
#define MJPEG_COEF_CTRL_REG (NPT_BASE + 0x0A0)
#define MJPEG_COEF_ADDR_REG (NPT_BASE + 0x0A4)
#define MJPEG_COEF_DATA_REG (NPT_BASE + 0x0A8)
#define MJPEG_RST_INTVAL_REG (NPT_BASE + 0x0B0)
#define MJPEG_RST_INDEX_REG (NPT_BASE + 0x0B4)
#define MJPEG_RST_COUNT_REG (NPT_BASE + 0x0B8)
#define MJPEG_INTR_MASK_REG (NPT_BASE + 0x0C0)
#define MJPEG_CYCLE_INFO_REG (NPT_BASE + 0x0C8)
#define MJPEG_DPCM_DIFF_Y_REG (NPT_BASE + 0x0F0)
#define MJPEG_DPCM_DIFF_CB_REG (NPT_BASE + 0x0F4)
#define MJPEG_DPCM_DIFF_CR_REG (NPT_BASE + 0x0F8)
// GBU CONTROL REGISTER
#define MJPEG_GBU_CTRL_REG \
(NPT_BASE + \
0x100) // [3] - GBU flush for encoding [2] - init GBU for decoding [1]
// - init GBU ff emulation for decoding [0] - reserved
#define MJPEG_GBU_PBIT_BUSY_REG (NPT_BASE + 0x104)
#define MJPEG_GBU_BT_PTR_REG (NPT_BASE + 0x110)
#define MJPEG_GBU_WD_PTR_REG (NPT_BASE + 0x114)
#define MJPEG_GBU_TT_CNT_REG (NPT_BASE + 0x118)
//#define MJPEG_GBU_TT_CNT_REG+4 (NPT_BASE + 0x11C)
#define MJPEG_GBU_PBIT_08_REG (NPT_BASE + 0x120)
#define MJPEG_GBU_PBIT_16_REG (NPT_BASE + 0x124)
#define MJPEG_GBU_PBIT_24_REG (NPT_BASE + 0x128)
#define MJPEG_GBU_PBIT_32_REG (NPT_BASE + 0x12C)
#define MJPEG_GBU_BBSR_REG (NPT_BASE + 0x140)
#define MJPEG_GBU_BBER_REG (NPT_BASE + 0x144)
#define MJPEG_GBU_BBIR_REG (NPT_BASE + 0x148)
#define MJPEG_GBU_BBHR_REG (NPT_BASE + 0x14C)
#define MJPEG_GBU_BCNT_REG (NPT_BASE + 0x158)
#define MJPEG_GBU_FF_RPTR_REG (NPT_BASE + 0x160)
#define MJPEG_GBU_FF_WPTR_REG (NPT_BASE + 0x164)
// BBC CONTROL REGISTER
#define MJPEG_BBC_END_ADDR_REG (NPT_BASE + 0x208)
#define MJPEG_BBC_WR_PTR_REG (NPT_BASE + 0x20C)
#define MJPEG_BBC_RD_PTR_REG (NPT_BASE + 0x210)
#define MJPEG_BBC_EXT_ADDR_REG (NPT_BASE + 0x214)
#define MJPEG_BBC_INT_ADDR_REG (NPT_BASE + 0x218)
#define MJPEG_BBC_DATA_CNT_REG (NPT_BASE + 0x21C)
#define MJPEG_BBC_COMMAND_REG \
(NPT_BASE + 0x220) // [2:1] - endianness [0] - load/save
#define MJPEG_BBC_BUSY_REG (NPT_BASE + 0x224)
#define MJPEG_BBC_CTRL_REG \
(NPT_BASE + 0x228) // [2:1] - endianness [0] - BBC auto run
#define MJPEG_BBC_CUR_POS_REG (NPT_BASE + 0x22C)
#define MJPEG_BBC_BAS_ADDR_REG (NPT_BASE + 0x230)
#define MJPEG_BBC_STRM_CTRL_REG \
(NPT_BASE + \
0x234) // [31] - end of bitstream file [23:0] - stream counter
#define MJPEG_BBC_FLUSH_CMD_REG (NPT_BASE + 0x238)
#endif