493 lines
11 KiB
C
Executable File
493 lines
11 KiB
C
Executable File
#include <stdlib.h>
|
|
#include <common/bk_include.h>
|
|
#include <os/mem.h>
|
|
#include <os/str.h>
|
|
|
|
#include <driver/jpeg_dec.h>
|
|
#include <driver/jpeg_dec_types.h>
|
|
#include <driver/timer.h>
|
|
|
|
#include <modules/jpeg_decode_sw.h>
|
|
#include <modules/tjpgd.h>
|
|
|
|
#include "lcd_act.h"
|
|
|
|
#include <driver/media_types.h>
|
|
#include <lcd_decode.h>
|
|
#include <driver/dma.h>
|
|
#include "bk_general_dma.h"
|
|
#include <soc/mapping.h>
|
|
#if CONFIG_SYS_CPU0 && CONFIG_MAILBOX
|
|
#include <driver/mailbox_channel.h>
|
|
#endif
|
|
|
|
#define TAG "lcd_dec"
|
|
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
|
|
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
|
|
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
|
|
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
|
|
|
|
|
|
extern media_debug_t *media_debug;
|
|
beken_semaphore_t dec_sem;
|
|
|
|
#if CONFIG_SOC_BK7256XX
|
|
uint8_t jpeg_dec_dma = 0;
|
|
#endif
|
|
|
|
static lcd_decode_t s_lcd_decode = {0};
|
|
#if CONFIG_SYS_CPU0 && CONFIG_MAILBOX
|
|
static void decode_mailbox_rx_isr(void *param, mb_chnl_cmd_t *cmd_buf)
|
|
{
|
|
bk_err_t ret;
|
|
|
|
if (cmd_buf->hdr.cmd == EVENT_LCD_DEC_SW_MBRSP)
|
|
{
|
|
ret = rtos_set_semaphore(&s_lcd_decode.dec_sem);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s semaphore get failed: %d\n", __func__, ret);
|
|
}
|
|
s_lcd_decode.result = (uint8_t)cmd_buf->param3;
|
|
}
|
|
|
|
if (cmd_buf->hdr.cmd == EVENT_LCD_DEC_SW_OPEN_MBRSP)
|
|
{
|
|
ret = rtos_set_semaphore(&s_lcd_decode.dec_sem);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s semaphore get failed: %d\n", __func__, ret);
|
|
}
|
|
s_lcd_decode.result = (uint8_t)cmd_buf->param3;
|
|
}
|
|
}
|
|
#endif
|
|
static void lcd_driver_decoder_timeout(timer_id_t timer_id)
|
|
{
|
|
bk_err_t ret = BK_FAIL;
|
|
|
|
bk_timer_stop(TIMER_ID3);
|
|
|
|
bk_jpeg_dec_stop();
|
|
media_debug->isr_decoder--;
|
|
|
|
s_lcd_decode.decode_timeout = true;
|
|
LOGE("%s \n", __func__);
|
|
|
|
ret = rtos_set_semaphore(&s_lcd_decode.dec_sem);
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s semaphore set failed: %d\n", __func__, ret);
|
|
}
|
|
}
|
|
|
|
|
|
static void jpeg_dec_eof_cb(jpeg_dec_res_t *result)
|
|
{
|
|
bk_err_t ret = BK_FAIL;
|
|
s_lcd_decode.decode_err = false;
|
|
|
|
media_debug->isr_decoder++;
|
|
|
|
bk_timer_stop(TIMER_ID3);
|
|
|
|
if (s_lcd_decode.decoder_frame)
|
|
{
|
|
s_lcd_decode.decoder_frame->height = result->pixel_y;
|
|
s_lcd_decode.decoder_frame->width = result->pixel_x ;
|
|
s_lcd_decode.decoder_frame->length = result->pixel_y * result->pixel_x *2;
|
|
}
|
|
|
|
if (result->ok == false)
|
|
{
|
|
s_lcd_decode.decode_err = true;
|
|
media_debug->isr_decoder--;
|
|
LOGD("%s decoder error\n", __func__);
|
|
}
|
|
|
|
ret = rtos_set_semaphore(&s_lcd_decode.dec_sem);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s semaphore set failed: %d\n", __func__, ret);
|
|
}
|
|
}
|
|
|
|
bk_err_t lcd_hw_decode_start(frame_buffer_t *src_frame, frame_buffer_t *dst_frame)
|
|
{
|
|
int ret = BK_OK;
|
|
s_lcd_decode.decoder_frame = dst_frame;
|
|
s_lcd_decode.decode_timeout = false;
|
|
#if CONFIG_SOC_BK7236XX
|
|
ret = bk_jpeg_dec_hw_start(src_frame->length, src_frame->frame, dst_frame->frame);
|
|
#else // CONFIG_SOC_BK7256XX
|
|
uint32_t length = src_frame->length;
|
|
uint32_t left_len = 0;
|
|
if (src_frame->fmt == PIXEL_FMT_JPEG && src_frame->type == UVC_CAMERA)
|
|
{
|
|
if (src_frame->length <= 128 * 1024)
|
|
{
|
|
if (src_frame->length <= 0xFFFF)
|
|
{
|
|
dma_memcpy_by_chnl((void*)JPEG_SRAM_ADDRESS, src_frame->frame,
|
|
(length % 4) ? ((length / 4 + 1) * 4) : length, jpeg_dec_dma);
|
|
}
|
|
else
|
|
{
|
|
dma_memcpy_by_chnl((void*)JPEG_SRAM_ADDRESS, src_frame->frame, 0xFFFF, jpeg_dec_dma);
|
|
left_len = length - 0xFFFF;
|
|
dma_memcpy_by_chnl((void*)JPEG_SRAM_ADDRESS + 0xFFFF, src_frame + 0xFFFF,
|
|
(left_len % 4) ? ((left_len / 4 + 1) * 4) : left_len, jpeg_dec_dma);
|
|
}
|
|
ret = bk_jpeg_dec_hw_start(src_frame->length, (void*)JPEG_SRAM_ADDRESS, dst_frame->frame);
|
|
}
|
|
else
|
|
{
|
|
LOGE("uvc output image too large!\n");
|
|
ret = BK_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = bk_jpeg_dec_hw_start(src_frame->length, src_frame->frame, dst_frame->frame);
|
|
}
|
|
#endif
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s, length:%d\r\n", __func__, src_frame->length);
|
|
return ret;
|
|
}
|
|
|
|
bk_timer_start(TIMER_ID3, 200, lcd_driver_decoder_timeout);
|
|
|
|
ret = rtos_get_semaphore(&s_lcd_decode.dec_sem, BEKEN_NEVER_TIMEOUT);
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s semaphore get failed: %d\n", __func__, ret);
|
|
}
|
|
if(s_lcd_decode.decode_timeout == true)
|
|
ret = BK_LCD_DECODE_TIMEOUT;
|
|
if(s_lcd_decode.decode_err == true)
|
|
ret = BK_LCD_DECODE_ERR;
|
|
|
|
return ret;
|
|
}
|
|
|
|
bk_err_t lcd_sw_jpegdec_start(frame_buffer_t *frame, frame_buffer_t *dst_frame)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
#if CONFIG_LCD_SW_DECODE
|
|
jd_output_format *format = NULL;
|
|
sw_jpeg_dec_res_t result;
|
|
format = os_malloc(sizeof(jd_output_format));
|
|
if (format == NULL)
|
|
{
|
|
LOGE("%s no buffer\n", __func__);
|
|
ret = BK_FAIL;
|
|
goto out;
|
|
}
|
|
media_debug->isr_decoder++;
|
|
switch (dst_frame->fmt)
|
|
{
|
|
case PIXEL_FMT_RGB565:
|
|
format->format = JD_FORMAT_RGB565;
|
|
format->scale = 1;
|
|
format->byte_order = JD_BIG_ENDIAN;
|
|
break;
|
|
case PIXEL_FMT_YUYV:
|
|
format->format = JD_FORMAT_YUYV;
|
|
format->scale = 0;
|
|
format->byte_order = JD_LITTLE_ENDIAN;
|
|
break;
|
|
case PIXEL_FMT_VUYY:
|
|
format->format = JD_FORMAT_VUYY;
|
|
format->scale = 0;
|
|
format->byte_order = JD_LITTLE_ENDIAN;
|
|
break;
|
|
default:
|
|
format->format = JD_FORMAT_VYUY;
|
|
format->scale = 0;
|
|
format->byte_order = JD_LITTLE_ENDIAN;
|
|
break;
|
|
}
|
|
|
|
jd_set_output_format(format);
|
|
ret = bk_jpeg_dec_sw_start(JPEGDEC_BY_FRAME, frame->frame, dst_frame->frame, frame->length, 0, &result);
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s sw decoder error\n", __func__);
|
|
media_debug->isr_decoder--;
|
|
goto out;
|
|
}
|
|
else
|
|
{
|
|
dst_frame->height = result.pixel_y;
|
|
dst_frame->width = result.pixel_x ;
|
|
}
|
|
out:
|
|
if (format)
|
|
{
|
|
os_free(format);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
bk_err_t lcd_sw_minor_jpegdec_start(frame_buffer_t *frame, frame_buffer_t *dst_frame)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
#if CONFIG_LCD_SW_DECODE
|
|
jd_output_format *format = NULL;
|
|
format = os_malloc(sizeof(jd_output_format));
|
|
if (format == NULL)
|
|
{
|
|
LOGE("%s no buffer\n", __func__);
|
|
ret = BK_FAIL;
|
|
goto out;
|
|
}
|
|
media_debug->isr_decoder++;
|
|
|
|
switch (dst_frame->fmt)
|
|
{
|
|
case PIXEL_FMT_RGB565:
|
|
format->format = JD_FORMAT_RGB565;
|
|
format->scale = 1;
|
|
format->byte_order = JD_BIG_ENDIAN;
|
|
break;
|
|
case PIXEL_FMT_YUYV:
|
|
format->format = JD_FORMAT_YUYV;
|
|
format->scale = 0;
|
|
format->byte_order = JD_LITTLE_ENDIAN;
|
|
break;
|
|
case PIXEL_FMT_VUYY:
|
|
format->format = JD_FORMAT_VUYY;
|
|
format->scale = 0;
|
|
format->byte_order = JD_LITTLE_ENDIAN;
|
|
break;
|
|
default:
|
|
format->format = JD_FORMAT_VYUY;
|
|
format->scale = 0;
|
|
format->byte_order = JD_LITTLE_ENDIAN;
|
|
break;
|
|
}
|
|
#if CONFIG_SYS_CPU0 && CONFIG_MAILBOX
|
|
mb_chnl_cmd_t mb_cmd;
|
|
mb_cmd.hdr.cmd = EVENT_LCD_DEC_SW_MBCMD;
|
|
mb_cmd.param1 = (uint32_t)frame;
|
|
mb_cmd.param2 = (uint32_t)dst_frame;
|
|
mb_cmd.param3 = (uint32_t)format;
|
|
s_lcd_decode.result = BK_FAIL;
|
|
ret = mb_chnl_write(MB_CHNL_DEC, &mb_cmd);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s mb_chnl_write failed: %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
//LOGI("%s wait rotate\n", __func__);
|
|
ret = rtos_get_semaphore(&s_lcd_decode.dec_sem, BEKEN_NEVER_TIMEOUT);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s semaphore get failed: %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
if (s_lcd_decode.result != BK_OK)
|
|
{
|
|
|
|
media_debug->isr_decoder--;
|
|
LOGE("%s sw decoder error\n", __func__);
|
|
goto out;
|
|
}
|
|
#endif
|
|
out:
|
|
if (format)
|
|
{
|
|
os_free(format);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
bk_err_t lcd_hw_decode_init(void)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
media_debug->isr_decoder = 0;
|
|
media_debug->err_dec = 0;
|
|
|
|
ret = rtos_init_semaphore_ex(&s_lcd_decode.dec_sem, 1, 0);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s hw dec_sem init failed: %d\n", __func__, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = bk_jpeg_dec_driver_init();
|
|
#if(1) //enable jpeg complete int isr
|
|
bk_jpeg_dec_isr_register(DEC_END_OF_FRAME, jpeg_dec_eof_cb);
|
|
#else //enable uvc ppi 640X480 jpeg 24 line decode complete int isr
|
|
bk_jpeg_dec_isr_register(DEC_END_OF_LINE_NUM, jpeg_dec_line_cb);
|
|
#endif
|
|
|
|
#if CONFIG_SOC_BK7256XX
|
|
jpeg_dec_dma = bk_dma_alloc(DMA_DEV_JPEG);
|
|
if ((jpeg_dec_dma < DMA_ID_0) || (jpeg_dec_dma >= DMA_ID_MAX))
|
|
{
|
|
LOGE("%s, jpeg dec malloc dma fail \r\n", __func__);
|
|
return BK_FAIL;
|
|
}
|
|
|
|
LOGI("%s, malloc dma channal %d\n", __func__, jpeg_dec_dma);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
bk_err_t lcd_hw_decode_deinit(void)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
bk_jpeg_dec_driver_deinit();
|
|
|
|
#if CONFIG_SOC_BK7256XX
|
|
bk_dma_stop(jpeg_dec_dma);
|
|
bk_dma_deinit(jpeg_dec_dma);
|
|
bk_dma_free(DMA_DEV_JPEG, jpeg_dec_dma);
|
|
#endif
|
|
|
|
ret = rtos_deinit_semaphore(&s_lcd_decode.dec_sem);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s dec_sem deinit failed: %d\n", __func__, ret);
|
|
return ret;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bk_err_t lcd_sw_decode_init(media_decode_mode_t sw_dec_mode)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
LOGI("%s \n", __func__);
|
|
ret = rtos_init_semaphore_ex(&s_lcd_decode.dec_sem, 1, 0);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s sw dec_sem init failed: %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
#if CONFIG_LCD_SW_DECODE
|
|
//jd_set_format(JD_FORMAT_YUYV);
|
|
if (sw_dec_mode == SOFTWARE_DECODING_MINOR)
|
|
{
|
|
#if CONFIG_SYS_CPU0 && CONFIG_MAILBOX
|
|
/* Mailbox */
|
|
mb_chnl_open(MB_CHNL_DEC, NULL);
|
|
mb_chnl_ctrl(MB_CHNL_DEC, MB_CHNL_SET_RX_ISR, decode_mailbox_rx_isr);
|
|
|
|
mb_chnl_cmd_t mb_cmd;
|
|
mb_cmd.hdr.cmd = EVENT_LCD_DEC_SW_OPEN_MBCMD;
|
|
mb_cmd.param1 = true;
|
|
s_lcd_decode.result = BK_FAIL;
|
|
ret = mb_chnl_write(MB_CHNL_DEC, &mb_cmd);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s mb_chnl_write failed: %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
ret = rtos_get_semaphore(&s_lcd_decode.dec_sem, BEKEN_NEVER_TIMEOUT);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s semaphore get failed: %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
if (s_lcd_decode.result != BK_OK)
|
|
{
|
|
LOGE("%s error\n", __func__);
|
|
goto out;
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
ret = bk_jpeg_dec_sw_init(NULL, 0);
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s dec_sem init failed: %d\n", __func__, ret);
|
|
return ret;
|
|
}
|
|
}
|
|
#endif
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
bk_err_t lcd_sw_decode_deinit(media_decode_mode_t sw_dec_mode)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
LOGI("%s sw_dec_mode = %d\n", __func__, sw_dec_mode);
|
|
if (sw_dec_mode == SOFTWARE_DECODING_MINOR)
|
|
{
|
|
#if CONFIG_SYS_CPU0 && CONFIG_MAILBOX
|
|
/* Mailbox */
|
|
mb_chnl_cmd_t mb_cmd;
|
|
mb_cmd.hdr.cmd = EVENT_LCD_DEC_SW_OPEN_MBCMD;
|
|
mb_cmd.param1 = false;
|
|
s_lcd_decode.result = BK_FAIL;
|
|
ret = mb_chnl_write(MB_CHNL_DEC, &mb_cmd);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s mb_chnl_write failed: %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
ret = rtos_get_semaphore(&s_lcd_decode.dec_sem, BEKEN_NEVER_TIMEOUT);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s semaphore get failed: %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
if (s_lcd_decode.result != BK_OK)
|
|
{
|
|
LOGE("%s sw decoder error\n", __func__);
|
|
goto out;
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
bk_jpeg_dec_sw_deinit();
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s dec_sem init failed: %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
ret = rtos_deinit_semaphore(&s_lcd_decode.dec_sem);
|
|
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("%s dec_sem deinit failed: %d\n", __func__, ret);
|
|
return ret;
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|