Files
TAIXIN/project/module_code/h264_user.c

623 lines
14 KiB
C
Raw Normal View History

#include "sys_config.h"
#include "tx_platform.h"
#include "osal/string.h"
#include <csi_kernel.h>
#include "stream_frame.h"
#include "osal/task.h"
#include "osal_file.h"
#include "video_app/video_app.h"
#include "lwip/api.h"
#include "lwip/sockets.h"
#include "lwip/etharp.h"
#include "utlist.h"
#include "jpgdef.h"
#include "lib/lcd/lcd.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/netdb.h"
#include "lwip/sys.h"
#include "lwip/ip_addr.h"
#include "lwip/tcpip.h"
#include "netif/ethernetif.h"
#include "dhcpd_eloop/dhcpd_eloop.h"
#include "hal/gpio.h"
#include "hal/pwm.h"
#include "hal/uart.h"
#include "hal/csc.h"
#include "dev/csc/hgcsc.h"
#include "lib/video/dvp/jpeg/jpg.h"
#define MIN(a,b) ( (a)>(b)?b:a )
#define MAX(a,b) ( (a)>(b)?a:b )
#define H264_DIR "0:/DCIM"
#define H264_FILE_NAME "264"
uint8_t name_rec_photo_h264[32];
static uint32_t a2i(char *str)
{
uint32_t ret = 0;
uint32_t indx =0;
char str_buf[32];
memset(str_buf,0,32);
while(str[indx] != '\0'){
if(str[indx] == '.') break;
str_buf[indx] = str[indx];
indx++;
}
printf("str_buf:%s str:%s\r\n",str_buf,str);
indx = 0;
while(str_buf[indx] != '\0'){
if(str_buf[indx] >= '0' && str_buf[indx] <='9'){
ret = ret*10+str_buf[indx]-'0';
}
indx ++;
}
return ret;
}
static void *creat_h264_file(char *dir_name)
{
DIR avi_dir;
FRESULT ret;
FILINFO finfo;
uint32_t indx= 0;
void *fp;
char filepath[64];
ret = f_opendir(&avi_dir,dir_name);
if(ret != FR_OK){
f_mkdir(dir_name);
f_opendir(&avi_dir,dir_name);
}
while(1){
ret = f_readdir(&avi_dir,&finfo);
if(ret != FR_OK || finfo.fname[0] == 0) break;
indx = MAX(indx,a2i(finfo.fname));
}
f_closedir(&avi_dir);
indx++;
sprintf(filepath,"%s/h%d.%s",dir_name,indx,H264_FILE_NAME);
printf("filepath:%s\r\n",filepath);
fp = osal_fopen(filepath,"wb+");
return fp;
}
static int opcode_func(stream *s,void *priv,int opcode)
{
int res = 0;
//_os_printf("%s:%d\topcode:%d\n",__FUNCTION__,__LINE__,opcode);
switch(opcode)
{
case STREAM_OPEN_ENTER:
break;
case STREAM_OPEN_EXIT:
{
enable_stream(s,1);
}
break;
case STREAM_OPEN_FAIL:
break;
default:
//ĬÈ϶¼·µ»Ø³É¹¦
break;
}
return res;
}
uint8_t uart4_buf_h264[16];
uint8_t uart4_buf_h264_result[16];
static struct os_semaphore uart4_buf_sem = {0,NULL};
static struct os_semaphore h264_buf_sem = {0,NULL};
void uart_user_sema_init()
{
os_sema_init(&uart4_buf_sem,0);
}
void uart_user_sema_down(int32 tmo_ms)
{
os_sema_down(&uart4_buf_sem,tmo_ms);
}
void uart_user_sema_up()
{
os_sema_up(&uart4_buf_sem);
}
void h264_user_sema_init()
{
os_sema_init(&h264_buf_sem,0);
}
void h264_user_sema_down(int32 tmo_ms)
{
os_sema_down(&h264_buf_sem,tmo_ms);
}
void h264_user_sema_up()
{
os_sema_up(&h264_buf_sem);
}
volatile uint8_t scale3_oe_select = 0;
int32 uart_user_handler_irq(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2)
{
struct uart_device *rx_uart = (struct uart_device *)dev_get(HG_UART1_DEVID);
memcpy(uart4_buf_h264_result,uart4_buf_h264,16);
if(UART_IRQ_FLAG_TIME_OUT == irq){
uart_gets(rx_uart,uart4_buf_h264,16);
if(uart4_buf_h264[0]!=0xff){
//rx_send_flag=1;
}
printf("uart4_buf_result:%d\n",uart4_buf_h264_result[0]);
if(uart4_buf_h264_result[0] == 0xfa){
if(scale3_oe_select == 0){
scale3_oe_select = 1;
}else{
scale3_oe_select = 0;
}
}else
{
uart_user_sema_up();
}
}
if(UART_IRQ_FLAG_DMA_RX_DONE == irq){
uart_gets(rx_uart,uart4_buf_h264,16);
//printf("uart4_buf111:%d\n",uart4_buf[0]);
uart_user_sema_up();
}
return 0;
}
void h264_wakeup_from_net(){
uart_user_sema_up();
}
void uart_user_rx_config(){
uart_user_sema_init();
#if 1
struct uart_device *rx_uart = (struct uart_device *)dev_get(HG_UART1_DEVID);
//uart_open(rx_uart,921600);
uart_open(rx_uart,921600);
uart_ioctl(rx_uart,UART_IOCTL_CMD_SET_TIME_OUT,9216/5,1);
uart_ioctl(rx_uart,UART_IOCTL_CMD_USE_DMA,1,0); //ÒªÊÖ¶¯¿ªÆôÊÇ·ñΪdma
uart_request_irq(rx_uart,uart_user_handler_irq,UART_IRQ_FLAG_TIME_OUT|UART_IRQ_FLAG_DMA_RX_DONE,(uint32_t)64);
uart_gets(rx_uart,uart4_buf_h264,16);
#endif
}
uint32 h264_write_len = 0;
uint8 *buf1_goble;
uint8 *buf2_goble;
uint8 *buf_save_goble;
uint8 buf_select = 0;
uint32_t h264_sram_buf[512];
void h264_write_sdcard_thread(uint32 arg_bf){
void *fp;
uint8_t w_card = 1;
uint32_t offset_wr = 0;
uint32_t ofset_len = 0;
retry_create:
fp = creat_h264_file(H264_DIR);
if(fp == NULL){
printf("create file 264 error\r\n");
w_card = 0;
}else{
printf("create 264 file ok\r\n");
w_card = 1;
}
ofset_len = 0;
while(1){
h264_user_sema_down(-1);
offset_wr = 0;
if(w_card){
printf("S(%d)",h264_write_len);
ofset_len += h264_write_len;
if(buf_select == 0){
osal_fwrite(buf2_goble,1,h264_write_len,fp);
}
else{
osal_fwrite(buf1_goble,1,h264_write_len,fp);
}
printf("E(%d)",ofset_len);
if(ofset_len > 10*1024*1024){
osal_fclose(fp);
goto retry_create;
}
}
}
}
extern volatile uint8 h264_error;
void h264_user_demo_thread(){
struct h264_device *h264_dev;
struct data_structure *get_f = NULL;
struct stream_h264_data_s *dest_list;
struct stream_h264_data_s *dest_list_tmp;
struct stream_h264_data_s *el,*tmp;
k_task_handle_t h264_write_task_handle;
uint8 file_num = 0;
uint8 *buf_cache;
uint32 cache_len = 0;
uint32 sd_save_len = 0;
uint32 cache_num = 0;
uint32 itk = 0;
//uint8_t cnt_264;
//uint8_t wdat;
stream *s = NULL;
void *fp;
uint32_t node_len;
uint32_t total_len = 0;
FRESULT res;
FATFS *fs;
DWORD fre_clust, fre_sect, tot_sect;
uint32_t flen;
uint32_t ofset_len = 0;
uint32_t num = 0;
uint8_t w_card = 1;
uint8_t w_cache_run = 0;
uint8_t *h264_buf_addr = NULL;
buf1_goble = (uint8*)av_psram_malloc(512*1024);
buf2_goble = (uint8*)av_psram_malloc(512*1024);
//buf_save_goble = (uint8*)av_psram_malloc(2*1024*1024);
h264_dev = (struct h264_device *)dev_get(HG_H264_DEVID);
uart_user_rx_config();
h264_user_sema_init();
//csi_kernel_task_new((k_task_entry_t)h264_write_sdcard_thread, "h264_write_card_thread", NULL, 25, 0, NULL, 2048, &h264_write_task_handle);
mp4_demo();
//h264_write_card:
uart_user_sema_down(-1);
printf("uart up..........................................................................................................\r\n");
s = open_stream_available(R_RECORD_H264,0,8,opcode_func,NULL);
h264_write_card:
file_num++;
h264_set_oe_select(h264_dev,1,file_num%2);
h264_enc(VPP_DATA0,1280,720,0,0,0);
//h264_enc(SCALER_DATA,1920,1088,0,0,0);
ofset_len = 0;
//cnt_264 = 0;
//wdat = 0x55;
cache_len = 0;
cache_num = 0;
w_cache_run = 0;
buf_select = 0;
start_h264();
while(1){
get_f = recv_real_data(s);
if(get_f){
printf("get_f(%08x)",get_f);
dest_list = (struct stream_h264_data_s *)GET_DATA_BUF(get_f);
dest_list_tmp = dest_list;
flen = get_stream_real_data_len(get_f);
node_len = GET_NODE_LEN(get_f);
h264_buf_addr = (uint8_t *)GET_JPG_BUF(get_f);
#if 0
for(itk = 0;itk < flen;itk++){
h264_buf_addr[itk] = wdat;
cnt_264++;
if((cnt_264%4) == 0){
wdat = 0x55;
cnt_264 = 0;
}
else if((cnt_264%4) == 1)
wdat = 0xAA;
else if((cnt_264%4) == 2)
wdat = 0x66;
else if((cnt_264%4) == 3){
wdat = 0xCC;
}
}
#endif
// printf("addr:%08x len:%d\r\n",h264_buf_addr,flen);
if(buf_select == 0)
hw_memcpy(buf1_goble + cache_len,h264_buf_addr,flen);
else
hw_memcpy(buf2_goble + cache_len,h264_buf_addr,flen);
printf("F(%d)",flen);
sd_save_len += flen;
cache_len += flen;
cache_num++;
if(cache_num == 8){
w_cache_run = 1;
}
if(w_cache_run)
{
if(buf_select == 0)
printf("\r\nSBUF1\r\n");
else
printf("\r\nSBUF2\r\n");
buf_select ^= BIT(0);
h264_write_len = cache_len;
h264_user_sema_up();
printf("W(%d)",h264_write_len);
printf("ofset_len:%x\r\n",ofset_len);
ofset_len += cache_len;
if(ofset_len > 10*1024*1024){
w_card = 0;
printf("CARD END:%d",ofset_len);
stop_h264();
free_data(get_f);
while(get_f)
{
get_f = recv_real_data(s);
free_data(get_f);
}
get_f = NULL;
os_sleep_ms(1000);
goto h264_write_card;
}
}
if(cache_num == 8){
cache_num = 0;
cache_len = 0;
w_cache_run = 0;
}
printf("free(%08x)",get_f);
free_data(get_f);
get_f = NULL;
}else{
if(h264_error == 1){
w_card = 0;
printf("CARD END");
stop_h264();
osal_fclose(fp);
free_data(get_f);
get_f = NULL;
os_sleep_ms(1000);
goto h264_write_card;
}
os_sleep_ms(10);
}
}
}
volatile uint8 csc_finish = 0;
void csc_done(uint32 irq_flag,uint32 irq_data,uint32 param1){
csc_finish = 1;
}
__psram_data uint8 h264_dec_file[1*1024*1024] __aligned(32);
extern uint8 *video_decode_mem;
extern uint32 p1_w,p1_h;
extern uint32 scale_p1_w;
void data_deal(uint8_t *src,uint8_t *des,uint32_t w,uint32_t h){
uint8_t *r;
uint8_t *g;
uint8_t *b;
uint32_t i;
r = src;
g = &src[w*h];
b = &src[2*w*h];
printf("r:%08x g:%08x b:%08x adr:%08x \r\n",r,g,b,des );
for(i = 0;i < w*h;i++){
des[i*3] = b[i];
des[i*3+1] = g[i];
des[i*3+2] = r[i];
}
}
void h264_user_demo_dec_thread(){
void *fp;
uint8_t *buf;
uint32_t offset_sps_start = 0;
uint8_t *buf2;
uint8_t *buf3;
uint32_t itk = 0;
uint32_t offset_sps_len = 0;
uint32_t data_count;
uint8_t frame_start_find;
uint8_t *photo_sd_cache = NULL;
uint32_t data_len;
uint32_t file_ip_len;
uint32_t offset_len;
uint32_t tmep;
uint8_t name[16];
uint8_t *pt8;
uint8_t *pt8_dec;
struct h264_device *h264_dev;
struct csc_device *csc_dev;
struct scale_device *scale2_dev;
struct scale_device *scale3_dev;
csc_dev = (struct csc_device *)dev_get(HG_CSC_DEVID);
h264_dev = (struct h264_device *)dev_get(HG_H264_DEVID);
scale2_dev = (struct scale_device *)dev_get(HG_SCALE2_DEVID);
scale3_dev = (struct scale_device *)dev_get(HG_SCALE3_DEVID);
os_printf("csc_dev :%x\r\n", csc_dev);
scale_from_h264_config(scale2_dev,1280,720,320,240,10);
//scale_from_h264_config(scale2_dev,1280,720,320,240,10);
jpeg_file_get(name,0,"H");
printf("name:%s\r\n",name);
sprintf((char *)name_rec_photo_h264,"%s%s","0:DCIM/",name);
fp = osal_fopen((const char*)name_rec_photo_h264,"rb");
if(!fp){
_os_printf("f_open %s error\r\n",name_rec_photo_h264);
goto h264_dec_end;
}
data_len = osal_fsize(fp);
_os_printf("data_len:%d\r\n",data_len);
photo_sd_cache = malloc(1024);
data_count = 1024;
frame_start_find = 0;
file_ip_len = 0;
pt8_dec = h264_dec_file;
while(data_len != 0){
if(data_len > 1024){
osal_fread(photo_sd_cache,1,data_count,fp);
data_len = data_len - 1024;
}
else{
osal_fread(photo_sd_cache,1,data_len,fp);
data_count = data_len;
data_len = 0;
}
pt8 = photo_sd_cache;
for(itk = 0;itk < data_count;itk++){
if(pt8[itk] == 0x00){
//if((pt8[itk+1] == 0x0100)&&(pt8[itk+2] == 0x4d67))
if((pt8[itk+1] == 0x00)&&(pt8[itk+2] == 0x00)&&(pt8[itk+3] == 0x01)&&(pt8[itk+4] == 0x67)&&(pt8[itk+5] == 0x4d)){
if(offset_sps_start == 1){
h264_dec_file[offset_sps_len] = 0x00;
h264_dec_file[offset_sps_len+1] = 0x00;
h264_dec_file[offset_sps_len+2] = 0x00;
h264_dec_file[offset_sps_len+3] = 0x01;
sys_dcache_clean_range(h264_dec_file,offset_sps_len+4);
printf("dec len:%d\r\n",offset_sps_len);
h264_dec_src_264(h264_dec_file,offset_sps_len,1280,720);
printf("dec end close\r\n");
}
offset_sps_start = 1;
offset_sps_len = 0;
#if 0
if(frame_start_find == 0){
frame_start_find = 1;
}else{
frame_start_find = 0;
offset_len = data_count - itk*2;
}
#endif
}
}
if(offset_sps_start == 1){
pt8_dec[offset_sps_len] = pt8[itk];
offset_sps_len++;
}
}
#if 0
if(frame_start_find == 0){
tmep = data_count - offset_len;
hw_memcpy(h264_dec_file+file_ip_len,photo_sd_cache,tmep);
file_ip_len = file_ip_len+tmep;
os_printf("file_ip_len:%d\r\n",file_ip_len);
h264_dec_file[file_ip_len] = 0x00;
h264_dec_file[file_ip_len+1] = 0x00;
h264_dec_file[file_ip_len+2] = 0x00;
h264_dec_file[file_ip_len+3] = 0x01;
sys_dcache_clean_range(h264_dec_file,file_ip_len);
h264_dec_src_264(h264_dec_file,file_ip_len,1280,720);
//h264_dec_src_264(h264_dec_file,file_ip_len,1280,720);
hw_memcpy(h264_dec_file,photo_sd_cache+tmep,offset_len);
file_ip_len = offset_len;
frame_start_find = 1;
}else{
hw_memcpy(h264_dec_file+file_ip_len,photo_sd_cache,data_count-offset_sps);
//printf("data_count:%d\r\n",data_count);
file_ip_len += data_count;
}
#endif
}
osal_fclose(fp);
h264_dec_end:
buf = (uint8*)av_psram_malloc(scale_p1_w*p1_h*3);
buf3 = (uint8*)av_psram_malloc(scale_p1_w*p1_h*3);
buf2= (uint8*)av_psram_malloc(160*120*3);
//buf2 = (uint8*)av_psram_malloc(scale_p1_w*p1_h*3);
#if 1
csc_init(csc_dev);
csc_set_type(csc_dev, 1);
csc_set_photo_size(csc_dev, 320, 240);
csc_set_format(csc_dev, CSC_YUV420P, CSC_YUV444P);
csc_set_input_addr(csc_dev,video_decode_mem,video_decode_mem+scale_p1_w*p1_h,video_decode_mem+scale_p1_w*p1_h+scale_p1_w*p1_h/4);
csc_set_output_addr(csc_dev,buf,buf+scale_p1_w*p1_h,buf+scale_p1_w*p1_h*2);
csc_request_irq(csc_dev,CSC_DONE_IRQ,(csc_irq_hdl )&csc_done,(uint32)csc_dev);
csc_finish = 0;
printf("csc kick run..\r\n");
csc_start_run(csc_dev);
while(csc_finish == 0);
printf("yuv420P %08x====> yuv444P finish %08x\r\n",video_decode_mem,buf);
csc_init(csc_dev);
csc_set_type(csc_dev, 0);
csc_set_format(csc_dev, CSC_YUV444P, CSC_RGB565);
csc_set_input_addr(csc_dev,buf,buf+scale_p1_w*p1_h,buf+scale_p1_w*p1_h*2);
csc_set_output_addr(csc_dev,buf3,buf3+scale_p1_w*p1_h,buf3+scale_p1_w*p1_h*2);
csc_finish = 0;
csc_start_run(csc_dev);
while(csc_finish == 0);
printf("yuv444P %08x ====> rgb565 finish %08x\r\n",buf,buf3);
scale2_all_frame(scale2_dev,FRAME_YUV420P,320,240,160,120,video_decode_mem,buf2);
printf("yuv420P %08x ====> yuv420p finish %08x\r\n",video_decode_mem,buf2);
#else
scale3_all_frame(scale3_dev,320,240,160,120,0,1,video_decode_mem,buf);
os_sleep_ms(10);
scale2_all_frame(scale2_dev,FRAME_RGB888P,160,120,80,80,buf,buf2);
#endif
while(1){
os_sleep_ms(1000);
}
}
void user_hardware_config()
{
k_task_handle_t h264_task_handle;
//csi_kernel_task_new((k_task_entry_t)h264_user_demo_dec_thread, "h264_thread", NULL, 25, 0, NULL, 2048, &h264_task_handle);
csi_kernel_task_new((k_task_entry_t)h264_user_demo_thread, "h264_thread", NULL, 25, 0, NULL, 2048, &h264_task_handle);
}