Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources
This commit is contained in:
409
sdk/app/spook/frame.c
Normal file
409
sdk/app/spook/frame.c
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Nathan Lutchansky <lutchann@litech.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
//#include <test_util.h>
|
||||
#include <csi_config.h>
|
||||
|
||||
#include <event.h>
|
||||
#include <log.h>
|
||||
#include <frame.h>
|
||||
#include <list.h>
|
||||
//#include <linux/linux_mutex.h>
|
||||
#include "spook_config.h"
|
||||
#include "rtp.h"
|
||||
|
||||
#include "lwip/api.h"
|
||||
#include <csi_kernel.h>
|
||||
|
||||
#include "csi_core.h"
|
||||
#include "list.h"
|
||||
|
||||
#include "jpgdef.h"
|
||||
|
||||
|
||||
#include "osal/sleep.h"
|
||||
|
||||
#ifdef USB_EN
|
||||
#include "dev/usb/uvc_host.h"
|
||||
#endif
|
||||
|
||||
#include "osal/string.h"
|
||||
|
||||
|
||||
#include "stream_frame.h"
|
||||
#include "basic_include.h"
|
||||
#include "lib/multimedia/msi.h"
|
||||
#include "lib/heap/av_heap.h"
|
||||
#include "lib/heap/av_psram_heap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC av_psram_malloc
|
||||
#define STREAM_FREE av_psram_free
|
||||
#define STREAM_ZALLOC av_psram_zalloc
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC av_malloc
|
||||
#define STREAM_LIBC_FREE av_free
|
||||
#define STREAM_LIBC_ZALLOC av_zalloc
|
||||
|
||||
|
||||
#define MAX_RTSP_JPG_RECV 28
|
||||
struct jpg_rtsp_msi {
|
||||
struct msi *msi;
|
||||
uint8_t filter_type; //暂时只是支持某个类型的数据(0xffff是不过滤,只是判断stype)
|
||||
uint8_t srcID;
|
||||
//struct os_event evt;
|
||||
//RBUFFER_DEF(data, struct framebuff *, MAX_RTSP_JPG_RECV);
|
||||
};
|
||||
|
||||
#define MAX_RTSP_AUDIO_RECV 10
|
||||
struct rtsp_audio_msi {
|
||||
struct msi *msi;
|
||||
};
|
||||
|
||||
static int32 rtsp_jpg_action(struct msi *msi, uint32 cmd_id, uint32 param1, uint32 param2)
|
||||
{
|
||||
struct jpg_rtsp_msi *jpg_rtsp = (struct jpg_rtsp_msi *)msi->priv;
|
||||
int32_t ret = RET_OK;
|
||||
//os_printf("cmd_id:%d\n",cmd_id);
|
||||
switch (cmd_id) {
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
os_printf("%s:%d\taddr:%X\n",__FUNCTION__,__LINE__,RETURN_ADDR());
|
||||
STREAM_LIBC_FREE(jpg_rtsp);
|
||||
}
|
||||
break;
|
||||
case MSI_CMD_TRANS_FB:
|
||||
{
|
||||
struct framebuff *fb = (struct framebuff *)param1;
|
||||
//来源要匹配
|
||||
if(jpg_rtsp->srcID && jpg_rtsp->srcID != fb->srcID)
|
||||
{
|
||||
ret = RET_ERR;
|
||||
break;
|
||||
}
|
||||
if(jpg_rtsp->filter_type != (uint8_t)~0)
|
||||
{
|
||||
ret = RET_ERR;
|
||||
if(jpg_rtsp->filter_type == fb->stype)
|
||||
{
|
||||
ret = RET_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSI_CMD_SET_SPEED: //设置播放倍速,控制数据读取行为
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t rtsp_audio_action(struct msi *msi, uint32_t cmd_id, uint32_t param1, uint32_t param2)
|
||||
{
|
||||
struct rtsp_audio_msi *audio_rtsp = (struct rtsp_audio_msi*)msi->priv;
|
||||
int32_t ret = RET_OK;
|
||||
switch(cmd_id) {
|
||||
case MSI_CMD_TRANS_FB:
|
||||
{
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
case MSI_CMD_POST_DESTROY:
|
||||
{
|
||||
STREAM_LIBC_FREE(audio_rtsp);
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct msi *rtsp_msi_init(const char *name,uint8_t filter_type,uint8_t srcID)
|
||||
{
|
||||
struct msi *rtsp_msi = msi_new(name,MAX_RTSP_JPG_RECV,NULL);
|
||||
struct jpg_rtsp_msi *jpg_rtsp = rtsp_msi->priv;
|
||||
|
||||
if(!jpg_rtsp)
|
||||
{
|
||||
jpg_rtsp = (struct jpg_rtsp_msi*)STREAM_LIBC_ZALLOC(sizeof(struct jpg_rtsp_msi));
|
||||
jpg_rtsp->filter_type = filter_type;
|
||||
jpg_rtsp->srcID = srcID;
|
||||
rtsp_msi->priv = (void*)jpg_rtsp;
|
||||
rtsp_msi->action = rtsp_jpg_action;
|
||||
jpg_rtsp->msi = rtsp_msi;
|
||||
rtsp_msi->priv = (void*)jpg_rtsp;
|
||||
}
|
||||
rtsp_msi->enable = 1;
|
||||
return rtsp_msi;
|
||||
}
|
||||
|
||||
struct msi *rtsp_audio_msi_init(const char *name)
|
||||
{
|
||||
struct msi *rtsp_audio_msi = msi_new(name, MAX_RTSP_AUDIO_RECV,NULL);
|
||||
struct rtsp_audio_msi *audio_rtsp = rtsp_audio_msi->priv;
|
||||
|
||||
if(!audio_rtsp) {
|
||||
audio_rtsp = (struct rtsp_audio_msi*)STREAM_LIBC_ZALLOC(sizeof(struct rtsp_audio_msi));
|
||||
rtsp_audio_msi->priv = (void*)audio_rtsp;
|
||||
rtsp_audio_msi->action = (msi_action)rtsp_audio_action;
|
||||
audio_rtsp->msi = rtsp_audio_msi;
|
||||
}
|
||||
rtsp_audio_msi->enable = 1;
|
||||
return rtsp_audio_msi;
|
||||
}
|
||||
|
||||
void rtsp_msi_deinit(struct msi *msi)
|
||||
{
|
||||
if(msi)
|
||||
{
|
||||
msi->enable = 0;
|
||||
msi_destroy(msi);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rtsp_audio_msi_deinit(struct msi *msi)
|
||||
{
|
||||
if(msi)
|
||||
{
|
||||
msi->enable = 0;
|
||||
msi_destroy(msi);
|
||||
}
|
||||
}
|
||||
|
||||
struct frame *new_frame(void)
|
||||
{
|
||||
struct frame *f;
|
||||
|
||||
//新帧
|
||||
f = (struct frame*)STREAM_LIBC_MALLOC(sizeof(struct frame));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
struct frame *new_audio_frame(void)
|
||||
{
|
||||
struct frame *f;
|
||||
|
||||
//新帧
|
||||
f = (struct frame*)STREAM_LIBC_MALLOC(sizeof(struct frame));
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
struct frame_exchanger *new_exchanger_audio( int slots,
|
||||
frame_deliver_func func, void *d )
|
||||
{
|
||||
struct frame_exchanger *ex;
|
||||
ex = (struct frame_exchanger *)STREAM_LIBC_MALLOC( sizeof( struct frame_exchanger ) );
|
||||
|
||||
ex->f = func;
|
||||
ex->d = d;
|
||||
return ex;
|
||||
}
|
||||
|
||||
|
||||
struct frame_exchanger *new_exchanger( int slots,
|
||||
frame_deliver_func func, void *d )
|
||||
{
|
||||
struct frame_exchanger *ex;
|
||||
|
||||
ex = (struct frame_exchanger *)
|
||||
STREAM_LIBC_MALLOC( sizeof( struct frame_exchanger ) );
|
||||
ex->f = func;
|
||||
ex->d = d;
|
||||
|
||||
|
||||
|
||||
/* read_mutex is used to avoid closing the tcp when frame is sending through sendmsg */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return ex;
|
||||
}
|
||||
|
||||
int exchange_frame( struct frame_exchanger *ex, struct frame *frame )
|
||||
{
|
||||
ex->jf= frame;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void unref_frame( struct frame *f )
|
||||
{
|
||||
// int r;
|
||||
//del_frame
|
||||
if(!f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DEL_JPG_FRAME((struct framebuff *)f->get_f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int opcode_func(stream *s,void *priv,int opcode)
|
||||
{
|
||||
int res = 0;
|
||||
switch(opcode)
|
||||
{
|
||||
case STREAM_OPEN_ENTER:
|
||||
break;
|
||||
case STREAM_OPEN_EXIT:
|
||||
{
|
||||
enable_stream(s,1);
|
||||
}
|
||||
break;
|
||||
case STREAM_OPEN_FAIL:
|
||||
break;
|
||||
case STREAM_RECV_DATA_FINISH:
|
||||
break;
|
||||
|
||||
case STREAM_CLOSE_EXIT:
|
||||
os_printf("%s:%d close\n",__FUNCTION__,__LINE__);
|
||||
break;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
//默认都返回成功
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//正常这个就是运行就退出
|
||||
void err_rtsp_stream(struct rtp_node *node)
|
||||
{
|
||||
struct frame_exchanger *ex = node->video_ex;
|
||||
while(1)
|
||||
{
|
||||
ex->f( NULL, ex->d );
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
void spook_send_thread_stream(struct rtsp_priv *r)
|
||||
{
|
||||
struct rtp_node *node = r->live_node;
|
||||
struct frame_exchanger *ex = node->video_ex;
|
||||
struct frame_exchanger *audio_ex = node->audio_ex;
|
||||
struct jpg_rtsp_msi *jpg_rtsp = r->v_msi?(struct jpg_rtsp_msi *)r->v_msi->priv:NULL;
|
||||
struct rtsp_audio_msi *audio_rtsp = r->a_msi?(struct rtsp_audio_msi *)r->a_msi->priv:NULL;
|
||||
struct frame *jpeg;
|
||||
struct frame *audio;
|
||||
struct framebuff *fb = NULL;
|
||||
struct framebuff *audio_fb = NULL;
|
||||
|
||||
int count_times = 0;
|
||||
int get_times_out = 0;
|
||||
int cnt_num = 0;
|
||||
uint32_t time_for_count;
|
||||
uint32_t time = 0;
|
||||
time_for_count = os_jiffies();
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(audio_rtsp) {
|
||||
audio_fb = msi_get_fb(audio_rtsp->msi, 0);
|
||||
if(audio_fb && audio_fb->mtype != F_AUDIO) {
|
||||
msi_delete_fb(NULL, audio_fb);
|
||||
audio_fb = NULL;
|
||||
}
|
||||
if(audio_fb) {
|
||||
audio = audio_ex->jf;
|
||||
audio->get_f = (void*)audio_fb;
|
||||
audio->length = audio_fb->len;
|
||||
audio->timestamp = audio_fb->time;
|
||||
audio->format = FORMAT_AUDIO;
|
||||
audio_ex->f(audio,audio_ex->d);
|
||||
}
|
||||
}
|
||||
fb = msi_get_fb(jpg_rtsp->msi, 0);
|
||||
if(fb && (fb->mtype != F_H264 && fb->mtype != F_JPG))
|
||||
{
|
||||
msi_delete_fb(NULL, fb);
|
||||
fb = NULL;
|
||||
}
|
||||
if (fb)
|
||||
{
|
||||
jpeg = ex->jf;
|
||||
jpeg->get_f = (void*)fb;
|
||||
jpeg->node_len = fb->len;
|
||||
jpeg->d = (uint8_t*)fb->data;
|
||||
jpeg->first_length = fb->len;
|
||||
jpeg->length = fb->len;
|
||||
jpeg->timestamp = fb->time;
|
||||
jpeg->format = FORMAT_JPEG;
|
||||
|
||||
cnt_num++;
|
||||
if((os_jiffies() - time_for_count) > 1000){
|
||||
time_for_count = os_jiffies();
|
||||
_os_printf(KERN_INFO"cnt_num:%d\r\n",cnt_num);
|
||||
cnt_num = 0;
|
||||
}
|
||||
|
||||
_os_printf("#");
|
||||
ex->f( jpeg, ex->d );
|
||||
}
|
||||
|
||||
if(fb)
|
||||
{
|
||||
ex->ready = 0;
|
||||
count_times++;
|
||||
if(count_times>25)
|
||||
{
|
||||
_os_printf("time:%lld\n", os_jiffies() - time);
|
||||
count_times = 0;
|
||||
time = os_jiffies();
|
||||
}
|
||||
}
|
||||
if(!fb && !audio_fb)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
get_times_out++;
|
||||
if(get_times_out>1000)
|
||||
{
|
||||
ex->f( NULL, ex->d );
|
||||
get_times_out = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
get_times_out = 0;
|
||||
}
|
||||
|
||||
fb = NULL;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user