first add sdk

This commit is contained in:
jialexd 2019-04-02 16:34:25 +08:00
commit f91efd1250
3915 changed files with 1291882 additions and 0 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,96 @@
#include "mmf_source.h"
#include "sample_aac.h"
static unsigned int base_ts;
void* aacf_mod_open(void)
{
base_ts = xTaskGetTickCount();
return (void*)1;
}
void aacf_mod_close(void* ctx)
{
(void)ctx;
return;
}
int aacf_mod_set_param(void* ctx, int cmd, int arg)
{
(void)ctx;
(void)cmd;
(void)arg;
return 0;
}
static unsigned char* seek_to_next(unsigned char* ptr, unsigned char* ptr_end)
{
//ptr+=7;
while(ptr < ptr_end){
if(ptr[0]==0xff && (ptr[1]>>4)==0x0f)
break;
ptr++;
}
if(ptr>=ptr_end) return NULL;
unsigned char * temp = ptr+3;
u32 ausize = ((*temp&0x03)<<11)|(*(temp+1)<<3)|((*(temp+2)&0xe0)>>5);
ptr+=ausize;
if(ptr>=ptr_end)
return NULL;
else{
while(ptr < ptr_end){
if(ptr[0]==0xff && (ptr[1]>>4)==0x0f)
return ptr;
ptr++;
}
return NULL;
}
}
static unsigned char *sample = (unsigned char*)aac_sample;
static unsigned char *next_sample = (unsigned char *)aac_sample;
static u8 *ptr = NULL;
int aacf_mod_handle(void* ctx, void* b)
{
int ret = 0;
(void)ctx;
exch_buf_t *exbuf = (exch_buf_t*)b;
/*get uvc buffer for new data*/
if(exbuf->state!=STAT_READY){
/*we will carry single AU for each rtp packet*/
sample = next_sample;
next_sample = seek_to_next(sample, (unsigned char*)aac_sample+aac_sample_size);
if(next_sample == NULL)
{
//replay
exbuf->len = aac_sample + aac_sample_size - sample;
next_sample = (unsigned char*)aac_sample;
}else{
exbuf->len = next_sample - sample;
}
exbuf->index = 0;
exbuf->data = sample;
//exbuf->timestamp = 0;
base_ts += 1024;
exbuf->timestamp = base_ts;
//vTaskDelay(500);
exbuf->state = STAT_READY;
}
return 0;
}
msrc_module_t aacf_module =
{
.create = aacf_mod_open,
.destroy = aacf_mod_close,
.set_param = aacf_mod_set_param,
.handle = aacf_mod_handle,
};

View file

@ -0,0 +1,243 @@
#include "mmf_source.h"
//uvc/v4l2 header files
#include "videodev2.h"
#include "uvcvideo.h"
#include "v4l2_intf.h"
#include "driver/geo/patch_uvc_geo.h"
#define CHANNEL_CNT 4
static int chl_table[CHANNEL_CNT] = {0};
extern mux_stream_t mux_stream;
#define CLEAR(x) memset(&(x), 0, sizeof(x))
typedef struct __mxuvc_context{
int width;
int height;
int frame_rate;
int fmt_type;
int compression_ratio;
}mxuvc_context;
//------------------------------------------------------------------------------
void* geo_mod_open(void)
{
/*init usb driver prior to init uvc driver*/
_usb_init();
if(wait_usb_ready() < 0)
return NULL;
/*init uvc driver*/
if(uvc_stream_init() < 0)
// Maybe not correct
return NULL;
mxuvc_context *mxuvc_ctx = malloc(sizeof(mxuvc_context));
if(!mxuvc_ctx) return NULL;
// default value
mxuvc_ctx->fmt_type = V4L2_PIX_FMT_H264;
mxuvc_ctx->width = 1280;
mxuvc_ctx->height = 720;
mxuvc_ctx->frame_rate = 30;
mxuvc_ctx->compression_ratio = 0;
return mxuvc_ctx;
}
void geo_mod_close(void* ctx)
{
uvc_stream_free();
free((struct mxuvc_context *)ctx);
_usb_deinit();
}
int geo_mod_set_param(void* ctx, int cmd, int arg)
{
int i, ret = 0;
unsigned int temp = 0;
unsigned int frame = 0;
unsigned short width = 0;
unsigned short high = 0;
video_format_t format = 0;
mxuvc_context* mxuvc_ctx = (mxuvc_context*)ctx;
// format mapping
// FMT_V_MJPG FMT_V_H264
int codec_map[]={V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_H264};
switch(cmd){
case CMD_ENABLE_CHANNEL:
if(arg >= 0 && arg <= CHANNEL_CNT)
chl_table[arg] = 1;
break;
case CMD_DISABLE_CHANNEL:
if(arg >= 0 && arg <= CHANNEL_CNT)
chl_table[arg] = 0;
break;
case CMD_SET_HEIGHT:
mxuvc_ctx->height = arg;
break;
case CMD_SET_WIDTH:
mxuvc_ctx->width = arg;
break;
case CMD_SET_FRAMERATE:
mxuvc_ctx->frame_rate = arg;
break;
case CMD_SET_CPZRATIO:
mxuvc_ctx->compression_ratio = arg;
break;
case CMD_SET_FRAMETYPE:
mxuvc_ctx->fmt_type = codec_map[arg&0xF];
break;
case CMD_SET_APPLY:
//if(uvc_set_param(uvc_ctx->fmt_type, &uvc_ctx->width, &uvc_ctx->height, &uvc_ctx->frame_rate, &uvc_ctx->compression_ratio) < 0)
// ret = EIO;
break;
case CMD_SET_STREAMMING:
if(arg == ON){ // stream on
for(i = 0; i < CHANNEL_CNT; i++)
{
if(chl_table[i])
{
if(mxuvc_video_start(i) < 0)
ret = -EIO;
}
}
}else{ // stream off
for(i = 0; i < CHANNEL_CNT; i++)
{
if(!chl_table[i])
{
if(mxuvc_video_stop(i) < 0)
ret = -EIO;
}
}
}
break;
default:
ret = ENOTSUPP;
break;
}
return ret;
}
//static int first_packet = 0; //VLC need timestamps of each stream at the beginning of streaming
/* first_packet | state
* 0 | init state: allow all packets
* get audio / \ get video |
* 1 2 | 1: allow video; 2: allow audio
* get video \ / get audio |
* 3 | final: allow all packets
*/
int geo_mod_handle(void* ctx, void* b)
{
int ret = 0;
exch_buf_t *exbuf = (exch_buf_t*)b;
video_info_t info;
int channel_id;
uint8_t *data_buf;
uint32_t data_size;
uint64_t ts;
struct v4l2_buffer buf;
if(exbuf->state==STAT_USED){
memset(&buf, 0, sizeof(struct v4l2_buffer));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP /*V4L2_MEMORY_DMABUF*/;
buf.index = exbuf->index;
buf.field = /*V4L2_FIELD_ANY*/V4L2_FIELD_NONE;
buf.timestamp = rtw_get_current_time();
ret = v4l_usr_ioctl(mux_stream.fd, VIDIOC_QBUF, (void *)&buf);
if (ret < 0){
printf("\n\rread_frame mmap method enqueue buffer failed 1");
//mxuvc_video_stop(CH1);
return -EIO;
}
exbuf->state = STAT_INIT;
}
if(exbuf->state!=STAT_READY){
recap:
memset(&buf, 0, sizeof(struct v4l2_buffer));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP /*V4L2_MEMORY_DMABUF*/;
ret = v4l_usr_ioctl(mux_stream.fd, VIDIOC_DQBUF, (void *)&buf);
if (ret < 0){
printf("\r\nread_frame mmap method dequeue buffer failed 2");
//mxuvc_video_stop(CH1);
return -EIO;
}
/*manipulate buf data if necessary*/
CLEAR(info);
ret = qbox_parse_header((unsigned char*)buf.m.offset, &channel_id, &info.format, &data_buf, &data_size, &ts, &info.metadata);
//if((ret<0)||(channel_id == CH2)||(channel_id==CH1&&first_packet==2)||(channel_id==8&&first_packet==1)) {//can filter unwanted here //do not process H264 data from ch2
//if((ret<0)||(channel_id == CH2)||(channel_id==8)) {//can filter unwanted here //do not process H264 data from ch2
if((ret<0)||(channel_id == CH2)) {
ret = v4l_usr_ioctl(mux_stream.fd, VIDIOC_QBUF, (void *)&buf);
if (ret < 0){
printf("\r\nread_frame mmap method enqueue buffer failed 3");
//mxuvc_video_stop(CH1);
return -EIO;
}
goto recap;
}
int this_id = FMT_AV_UNKNOWN;
switch(info.format){
case VID_FORMAT_AAC_RAW:
this_id = FMT_A_MP4A_LATM;
break;
case VID_FORMAT_H264_TS:
case VID_FORMAT_H264_RAW:
this_id = FMT_V_H264;
break;
default:
printf("\r\nUnsupport format is met");
return -EOPNOTSUPP;
}
switch(this_id){
case FMT_A_MP4A_LATM:
//printf("AAC");
get_adts_header(data_size, data_buf);
exbuf->codec_fmt = FMT_A_MP4A_LATM;
break;
case FMT_V_H264:
//printf("H264");
exbuf->codec_fmt = FMT_V_H264;
break;
default:
printf("\r\nUnexpected error in event_handler");
break;
}
/*fill payload*/
exbuf->index = buf.index;
exbuf->data = data_buf;
exbuf->len = data_size;
if(this_id == FMT_A_MP4A_LATM){
exbuf->timestamp = (u32)( ts*16/90);//ts*16000/1000/90
}
else{
exbuf->timestamp = (u32) ts;
}
exbuf->state = STAT_READY;
}
return 0;
}
msrc_module_t geo_module =
{
.create = geo_mod_open,
.destroy = geo_mod_close,
.set_param = geo_mod_set_param,
.handle = geo_mod_handle,
};

View file

@ -0,0 +1,84 @@
#include "mmf_source.h"
#include "sample_h264.h"
void* h264f_mod_open(void)
{
return (void*)1;
}
void h264f_mod_close(void* ctx)
{
(void)ctx;
return;
}
int h264f_mod_set_param(void* ctx, int cmd, int arg)
{
(void)ctx;
(void)cmd;
(void)arg;
return 0;
}
static unsigned char* seek_to_next(unsigned char* ptr, unsigned char* ptr_end)
{
ptr+=3;
while( ptr < ptr_end ){
if(ptr[0]==0 && ptr[1]==0){
if(ptr[2]==0 && ptr[3]==1 )
return ptr;
else if(ptr[2]==1)
return ptr;
}
ptr++;
}
return NULL;
}
static unsigned char *sample = (unsigned char*)h264_sample;
static unsigned char *next_sample = (unsigned char *)h264_sample;
u8 *ptr = NULL;
int h264f_mod_handle(void* ctx, void* b)
{
int ret = 0;
(void)ctx;
exch_buf_t *exbuf = (exch_buf_t*)b;
/*get uvc buffer for new data*/
if(exbuf->state!=STAT_READY){
sample = next_sample;
ptr = sample;
next_sample = seek_to_next(sample, (unsigned char*)h264_sample+h264_sample_len);
if(next_sample == NULL)
{
//replay
exbuf->len = h264_sample + h264_sample_len - sample;
next_sample = (unsigned char*)h264_sample;
}else{
exbuf->len = next_sample - sample;
}
exbuf->index = 0;
exbuf->data = sample;
exbuf->timestamp = 0;
//vTaskDelay(500);
exbuf->state = STAT_READY;
}
return 0;
}
msrc_module_t h264f_module =
{
.create = h264f_mod_open,
.destroy = h264f_mod_close,
.set_param = h264f_mod_set_param,
.handle = h264f_mod_handle,
};

View file

@ -0,0 +1,46 @@
#include "mmf_source.h"
#include "h264_encode.h"
void* h264_unit_open(void)
{
struct h264_context *h264_ctx = (struct h264_context *) malloc(sizeof(struct h264_context));
if (h264_ctx == NULL) {
return NULL;
}
memset(h264_ctx, 0, sizeof(struct h264_context));
h264_stream_init(h264_ctx);
h264_enc_init(h264_ctx);
//voe_init(h264_ctx);
//isp_init(h264_ctx);
return h264_ctx;
}
void h264_unit_close(void* ctx)
{
free((struct h264_context *)ctx);
}
int h264_unit_set_param(void* ctx, int cmd, int arg)
{
return 0;
}
int h264_unit_handle(void* ctx, void* b)
{
int ret = 0;
ret = h264_stream_get_frame(ctx, b);
return 0;
}
msrc_module_t h264_unit_module =
{
.create = h264_unit_open,
.destroy = h264_unit_close,
.set_param = h264_unit_set_param,
.handle = h264_unit_handle,
};

View file

@ -0,0 +1,140 @@
#include "mmf_source_i2s_file.h"
static i2s_buf_context i2s_buf;
static u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
static u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
static unsigned char encoder_buf[G711_FSIZE];
static i2s_buf_context * buf_ctx=NULL;
static i2s_t i2s_obj;
static void set_i2s_buf_context(i2s_buf_context * des){
buf_ctx = des;
buf_ctx -> raw_data = i2s_rx_buf;
}
int i2s_mod_handle(void* ctx, void* b)
{
int ret = 0;
static unsigned int time_count = 0;
(void)ctx;
exch_buf_t *exbuf = (exch_buf_t*)b;
unsigned char * source =i2s_buf.raw_data;
/*get uvc buffer for new data*/
if(exbuf->state!=STAT_READY){
G711_encoder((short *)(i2s_buf.raw_data+i2s_buf.data_start), encoder_buf, i2s_buf.mode, G711_FSIZE);
i2s_buf.data_start=(i2s_buf.data_start+2*G711_FSIZE)%(I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM);
i2s_buf.len = (i2s_buf.data_end-i2s_buf.data_start+(I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM))%(I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM);
exbuf->len = G711_FSIZE;
exbuf->index = 0;
exbuf->data = encoder_buf;
time_count+=160;
exbuf->timestamp = time_count;
exbuf->state = STAT_READY;
}
return 0;
}
static void i2s_tx_complete(void *data, char* pbuf){
return ;
}
static void i2s_rx_complete(void *data, char* pbuf)
{
i2s_t *obj = (i2s_t *)data;
if(buf_ctx != NULL){// i2s write to buffer, rtsp read from buffer, so keeps len below half of the buffer
if(buf_ctx->len > I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM/2){
buf_ctx->data_start = (buf_ctx->data_start+I2S_DMA_PAGE_SIZE) % (I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM);
buf_ctx->len -=I2S_DMA_PAGE_SIZE;
}
buf_ctx->data_end = (buf_ctx->data_end+I2S_DMA_PAGE_SIZE) % (I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM);
buf_ctx->len +=I2S_DMA_PAGE_SIZE;
}
i2s_recv_page(obj); // submit a new page for receive
return ;
}
void i2s_mod_init()
{
//i2s_t i2s_obj;
i2s_buf.len = i2s_buf.data_start = i2s_buf.data_end = 0;
set_i2s_buf_context(&i2s_buf);
vTaskDelay(1000);
alc5651_init();
alc5651_init_interface2(); // connect to ALC interface 2
i2s_obj.channel_num = CH_MONO;
i2s_obj.sampling_rate = SR_8KHZ;
i2s_obj.word_length = WL_16b;
i2s_obj.direction = I2S_DIR_RX;//TODO: need to check direction before i2s_set_dma_buffer
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)i2s_tx_complete, (uint32_t)&i2s_obj);
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)i2s_rx_complete, (uint32_t)&i2s_obj);
/* rx need clock, let tx out first */
switch(i2s_obj.direction){
case I2S_DIR_TX:
i2s_send_page(&i2s_obj, (uint32_t*)i2s_get_tx_page(&i2s_obj));
break;
case I2S_DIR_TXRX:
i2s_send_page(&i2s_obj, (uint32_t*)i2s_get_tx_page(&i2s_obj));//don't break, need i2s_recv_page
case I2S_DIR_RX:
i2s_recv_page(&i2s_obj);
break;
default:
break;
}
}
void* i2s_mod_open(void)
{
i2s_mod_init();
return (void*)1;
}
void i2s_mod_close(void* ctx)
{
(void)ctx;
return;
}
int i2s_mod_set_param(void* ctx, int cmd, int arg)
{
int ret = 0;
switch(cmd){
case CMD_SET_FRAMETYPE:
if(arg == FMT_A_PCMU)
i2s_buf.mode = I2S_MODE_G711U;
else if(arg == FMT_A_PCMA)
i2s_buf.mode = I2S_MODE_G711A;
else
i2s_buf.mode = I2S_MODE_G711A;//default
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
msrc_module_t i2s_module =
{
.create = i2s_mod_open,
.destroy = i2s_mod_close,
.set_param = i2s_mod_set_param,
.handle = i2s_mod_handle,
};

View file

@ -0,0 +1,35 @@
#ifndef MMF_SOURCE_I2S_FILE_H
#define MMF_SOURCE_I2S_FILE_H
#include "mmf_source.h"
#include "FreeRTOS.h"
#include "task.h"
//#include "example_rtsp_server_i2s.h"
#include "rtsp/rtsp_api.h"
#include "sockets.h"
#include "lwip/netif.h"
#include "i2s_api.h"
#include "alc5651.h"
#include "g711\g711_codec.h"
#include "gpio_api.h" // mbed
#include "gpio_irq_api.h"
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#include "dlist.h"
#include "basic_types.h"
#include "osdep_service.h"
#define I2S_DMA_PAGE_SIZE 320 // 2 ~ 4096
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
#define RECV_PAGE_NUM I2S_DMA_PAGE_NUM
#define G711_FSIZE 160
#define I2S_MODE_SWITCH PE_5
#define I2S_SCLK_PIN PC_1
#define I2S_WS_PIN PC_0
#define I2S_SD_PIN PC_2
#endif /* MMF_SOURCE_I2S_FILE_H */

View file

@ -0,0 +1,15 @@
#ifndef _MEDIA_MODULES_H
#define _MEDIA_MODULES_H
#include "../mmf_source.h"
//list all avaliable modules here
extern msrc_module_t uvc_module;
extern msrc_module_t geo_module;
extern msrc_module_t mjpgf_module;
extern msrc_module_t h264f_module;
extern msrc_module_t h264_unit_module;
extern msrc_module_t aacf_module;
extern msrc_module_t pcmuf_module;
extern msrc_module_t i2s_module;
extern msrc_module_t rtp_src_module;
#endif

View file

@ -0,0 +1,60 @@
#include "mmf_source.h"
#include "sample_jpeg.h"
void* mjpgf_mod_open(void)
{
return (void*)1;
}
void mjpgf_mod_close(void* ctx)
{
(void)ctx;
return;
}
int mjpgf_mod_set_param(void* ctx, int cmd, int arg)
{
(void)ctx;
(void)cmd;
(void)arg;
return 0;
}
static int cnt = 0;
int mjpgf_mod_handle(void* ctx, void* b)
{
int ret = 0;
(void)ctx;
exch_buf_t *exbuf = (exch_buf_t*)b;
/*get uvc buffer for new data*/
if(exbuf->state!=STAT_READY){
if(cnt++&0x1){
exbuf->data = (unsigned char *)PIC_320x240_2;
exbuf->len = PIC_LEN_2;
}else{
exbuf->data = (unsigned char *)PIC_320x240_1;
exbuf->len = PIC_LEN_1;
}
exbuf->index = 0;
exbuf->timestamp = 0;
//vTaskDelay(500);
exbuf->state = STAT_READY;
}
return 0;
}
msrc_module_t mjpgf_module =
{
.create = mjpgf_mod_open,
.destroy = mjpgf_mod_close,
.set_param = mjpgf_mod_set_param,
.handle = mjpgf_mod_handle,
};

View file

@ -0,0 +1,72 @@
#include "mmf_source.h"
#include "sample_pcmu.h"
static unsigned int base_ts;
void* pcmuf_mod_open(void)
{
return (void*)1;
}
void pcmuf_mod_close(void* ctx)
{
(void)ctx;
return;
}
int pcmuf_mod_set_param(void* ctx, int cmd, int arg)
{
(void)ctx;
(void)cmd;
(void)arg;
return 0;
}
#define G711F_SIZE 160
static unsigned char *sample=(unsigned char *)pcmu_sample;
static unsigned char *next_sample=(unsigned char *)pcmu_sample;
int pcmuf_mod_handle(void* ctx, void* b)
{
int ret = 0;
(void)ctx;
exch_buf_t *exbuf = (exch_buf_t*)b;
/*get uvc buffer for new data*/
if(exbuf->state!=STAT_READY){
unsigned char * source=(unsigned char*)pcmu_sample;
sample=next_sample;
if(sample-source >= pcmu_sample_size){//replay
sample = source;
next_sample = source+G711F_SIZE;
}
else{
next_sample+=G711F_SIZE;
if(next_sample - source >= pcmu_sample_size){
next_sample = source + pcmu_sample_size;
}
}
exbuf->len = next_sample-sample;
exbuf->index = 0;
exbuf->data = sample;
//exbuf->timestamp = 0;
base_ts += 160;
exbuf->timestamp = base_ts;
//vTaskDelay(500);
exbuf->state = STAT_READY;
}
return 0;
}
msrc_module_t pcmuf_module =
{
.create = pcmuf_mod_open,
.destroy = pcmuf_mod_close,
.set_param = pcmuf_mod_set_param,
.handle = pcmuf_mod_handle,
};

View file

@ -0,0 +1,302 @@
#include "mmf_source.h"
#include "wifi_conf.h"
#include "lwip/api.h" //netconn use
#include <lwip/sockets.h>
#include "rtsp/rtp_api.h"
#define MAX_SELECT_SOCKET 8
#define DEFAULT_RTP_PORT 16384
#if CONFIG_EXAMPLE_MP3_STREAM_RTP
#define G711_BLK_SIZE (634)
#define AUDIO_BUF_SIZE (646) //160 BYTE DATA + 12 BYTE RTP HEADER
#else
#define G711_BLK_SIZE (160)
#define AUDIO_BUF_SIZE (172) //160 BYTE DATA + 12 BYTE RTP HEADER
#endif
#define AUDIO_BUF_DEPTH (4)
typedef struct rtp_exbuf_type
{
u8 buf[AUDIO_BUF_SIZE];
int len;
}rtp_exbuf_t;
typedef struct rtp_client_type
{
TaskHandle_t task_handle;
xQueueHandle cache_queue;
xQueueHandle done_queue;
struct connect_context connect_ctx;
_sema rtp_sema;
u8 rtp_shutdown;
}rtp_client_t;
//static u8* priv_buf[AUDIO_BUF_DEPTH];
static rtp_exbuf_t rtp_buf;
static int q_depth = 0;
static long listen_time_s = 0;
static long listen_time_us = 20000; //20ms
int rtp_client_start(void *param)
{
rtp_client_t *rtp_ctx = (rtp_client_t *)param;
u32 start_time, current_time;
int ret = 0;
int len, offset;
rtp_hdr_t rtp_header;
struct sockaddr_in rtp_addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
fd_set read_fds;
struct timeval listen_timeout;
int mode = 0;
int opt = 1;
u16 last_seq = 0;
start_time = rtw_get_current_time();
wext_get_mode(WLAN0_NAME, &mode);
printf("\n\rwlan mode:%d", mode);
switch(mode)
{
case(IW_MODE_MASTER)://AP mode
while(wifi_is_ready_to_transceive(RTW_AP_INTERFACE) < 0)
{
vTaskDelay(1000);
current_time = rtw_get_current_time();
if((current_time - start_time) > 60000)
{
printf("\n\rwifi Tx/Rx not ready...");
return ret;
}
}
break;
case(IW_MODE_INFRA)://STA mode
case(IW_MODE_AUTO)://when ameba doesn't join bss
while(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) < 0)
{
vTaskDelay(1000);
current_time = rtw_get_current_time();
if((current_time - start_time) > 60000)
{
printf("\n\rwifi Tx/Rx not ready...");
return ret;
}
}
break;
default:
printf("\n\rillegal wlan state!rtp client cannot start");
return ret;
}
wext_get_mode(WLAN0_NAME, &mode);
printf("\n\rwlan mode:%d", mode);
vTaskDelay(1000);
if((rtp_ctx->connect_ctx.socket_id = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("\n\rcreate rtp client socket failed!");
return 0;//???
}
if((setsockopt(rtp_ctx->connect_ctx.socket_id, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt))) < 0){
printf("\r\n Error on setting socket option");
goto exit;
}
memset(&rtp_addr, 0, addrlen);
rtp_addr.sin_family = AF_INET;
rtp_addr.sin_addr.s_addr = INADDR_ANY;
rtp_addr.sin_port = htons(rtp_ctx->connect_ctx.server_port);
if (bind(rtp_ctx->connect_ctx.socket_id,(struct sockaddr *)&rtp_addr, addrlen)<0) {
printf("bind failed\r\n");
goto exit;
}
rtp_ctx->rtp_shutdown = 0;
while(!rtp_ctx->rtp_shutdown)
{
FD_ZERO(&read_fds);
listen_timeout.tv_sec = listen_time_s;
listen_timeout.tv_usec = listen_time_us;
FD_SET(rtp_ctx->connect_ctx.socket_id, &read_fds);
if(select(MAX_SELECT_SOCKET, &read_fds, NULL, NULL, &listen_timeout))
{
//q_depth = uxQueueSpacesAvailable(rtp_ctx->done_queue);
//if(q_depth > 0)
if(xQueueReceive(rtp_ctx->done_queue, (void *)&rtp_buf, 0xFFFFFFFF) != pdTRUE){
continue;
//insert silence here
}
//printf("\n\ro");
memset(rtp_buf.buf, 0, AUDIO_BUF_SIZE);
len = recvfrom(rtp_ctx->connect_ctx.socket_id, rtp_buf.buf, AUDIO_BUF_SIZE, 0, (struct sockaddr *)&rtp_addr, &addrlen);
rtp_buf.len = len;
xQueueSend(rtp_ctx->cache_queue, (void *)&rtp_buf, 0xFFFFFFFF);
}else{
//printf("\n\r.");
//insert silence here
}
}
exit:
close(rtp_ctx->connect_ctx.socket_id);
return ret;
}
void rtp_client_init(void *param)
{
rtp_client_t *rtp_ctx = (rtp_client_t *)param;
rtw_init_sema(&rtp_ctx->rtp_sema, 0);
while(1)
{
if(rtw_down_timeout_sema(&rtp_ctx->rtp_sema,100))
{
if(rtp_client_start(rtp_ctx) < 0)
goto exit;
}
}
exit:
rtp_ctx->rtp_shutdown = 0;
rtw_free_sema(&rtp_ctx->rtp_sema);
vTaskDelete(NULL);
}
void* rtp_mod_open(void)
{
rtp_client_t *rtp_ctx = malloc(sizeof(rtp_client_t));
if(rtp_ctx == NULL)
return NULL;
memset(rtp_ctx, 0, sizeof(rtp_client_t));
/* set default port */
rtp_ctx->connect_ctx.socket_id = -1;
rtp_ctx->connect_ctx.server_port = DEFAULT_RTP_PORT;
/* create a rtp client to receive audio data */
if(xTaskCreate(rtp_client_init, ((const char*)"rtp_client_init"), 512, rtp_ctx, 2, &rtp_ctx->task_handle) != pdPASS) {
//printf("\r\n geo_rtp_client_init: Create Task Error\n");
free(rtp_ctx);
return NULL;
}
return (void*)rtp_ctx;
}
void rtp_mod_close(void* ctx)
{
rtp_client_t *rtp_ctx = (rtp_client_t *)ctx;
if(!rtp_ctx->task_handle && xTaskGetCurrentTaskHandle()!=rtp_ctx->task_handle)
vTaskDelete(rtp_ctx->task_handle);
free(rtp_ctx);
}
int rtp_mod_set_param(void* ctx, int cmd, int arg)
{
int ret = 0;
rtp_client_t *rtp_ctx = (rtp_client_t *)ctx;
switch(cmd)
{
case(CMD_SET_PRIV_BUF):
if(arg==1)//initially set queue
{
rtp_ctx->cache_queue = xQueueCreate(AUDIO_BUF_DEPTH, sizeof(rtp_exbuf_t));
rtp_ctx->done_queue = xQueueCreate(AUDIO_BUF_DEPTH, sizeof(rtp_exbuf_t));
}else if(arg==2)//reset queue
{
xQueueReset(rtp_ctx->cache_queue);
xQueueReset(rtp_ctx->done_queue);
}else if(arg==0)//delete queue
{
vQueueDelete(rtp_ctx->cache_queue);
vQueueDelete(rtp_ctx->done_queue);
break;
}else{
ret = -EINVAL;
break;
}
for(int i = 0; i < AUDIO_BUF_DEPTH; i++)
{
xQueueSend(rtp_ctx->done_queue, (void*)&rtp_buf, 0xFFFFFFFF);
}
break;
case(CMD_SET_STREAMMING):
if(arg == ON){ // stream on
rtw_up_sema(&rtp_ctx->rtp_sema);
}else{ // stream off
rtp_ctx->rtp_shutdown = 0;
}
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
//give audio data here
rtp_exbuf_t tmp_exbuf[3];
static int tmp_order = 0;
static u16 last_seq = 0;
int rtp_mod_handle(void* ctx, void* b)
{
int ret = 0;
int q_depth = 0;
rtp_client_t *rtp_ctx = (rtp_client_t *)ctx;
exch_buf_t *exbuf = (exch_buf_t*)b;
rtp_hdr_t rtp_header;
int offset;
if(exbuf->state==STAT_USED){
xQueueSend(rtp_ctx->done_queue, (void *)&tmp_exbuf[exbuf->index], 0xFFFFFFFF);
exbuf->state = STAT_INIT;
}
//decide if audio cache is enough for send
q_depth = uxQueueSpacesAvailable(rtp_ctx->cache_queue);
//printf("\n\rQ-%d", q_depth);
if(q_depth >= AUDIO_BUF_DEPTH/2)
return -EAGAIN;
if(xQueueReceive(rtp_ctx->cache_queue, (void *)&tmp_exbuf[tmp_order], 0xFFFFFFFF) != pdTRUE)
return -EAGAIN;
offset = rtp_parse_header(tmp_exbuf[tmp_order].buf, &rtp_header, 1);
//printf("\n\r%d-%dB", offset, tmp_exbuf[tmp_order].len);
/* for data loss debugging */
#if 1
if(last_seq == 0)
last_seq = ntohs(rtp_header.seq);
else
{
if((ntohs(rtp_header.seq) - last_seq)>1)
printf("\n\r(%d-%d)", last_seq, ntohs(rtp_header.seq));
last_seq = ntohs(rtp_header.seq);
}
#endif
#if CONFIG_EXAMPLE_MP3_STREAM_RTP
if((rtp_header.pt == RTP_PT_PCMU) || (rtp_header.pt == RTP_PT_DYN_BASE) || (rtp_header.pt == RTP_PT_MPA))
#else
if(rtp_header.pt == RTP_PT_PCMU)
#endif
{
if(exbuf->state!=STAT_READY){
exbuf->index = tmp_order;
exbuf->data = tmp_exbuf[tmp_order].buf + offset;
exbuf->len = tmp_exbuf[tmp_order].len - offset;
//exbuf->timestamp = ?;
exbuf->state = STAT_READY;
tmp_order++;
if(tmp_order == 3)
tmp_order = 0;
}
}
return ret;
}
msrc_module_t rtp_src_module =
{
.create = rtp_mod_open,
.destroy = rtp_mod_close,
.set_param = rtp_mod_set_param,
.handle = rtp_mod_handle,
};

View file

@ -0,0 +1,150 @@
#include "mmf_source.h"
//uvc/v4l2 header files
#include "videodev2.h"
#include "uvcvideo.h"
#include "v4l2_driver.h"
#include "uvc_intf.h"
void* uvc_mod_open(void)
{
/*init usb driver prior to init uvc driver*/
_usb_init();
if(wait_usb_ready() < 0)
return NULL;
/*init uvc driver*/
if(uvc_stream_init() < 0)
// Maybe not correct
return NULL;
struct uvc_context *uvc_ctx = malloc(sizeof(struct uvc_context));
if(!uvc_ctx) return NULL;
// default value
uvc_ctx->fmt_type = UVC_FORMAT_MJPEG;
uvc_ctx->width = 640;
uvc_ctx->height = 480;
uvc_ctx->frame_rate = 30;
uvc_ctx->compression_ratio = 0;
return uvc_ctx;
}
void uvc_mod_close(void* ctx)
{
uvc_stream_free();
free((struct uvc_context *)ctx);
_usb_deinit();
}
int uvc_mod_set_param(void* ctx, int cmd, int arg)
{
int ret = 0;
int *parg = NULL;
struct uvc_context* uvc_ctx = (struct uvc_context*)ctx;
// format mapping
// FMT_V_MJPG FMT_V_H264
int codec_map[]={UVC_FORMAT_MJPEG, UVC_FORMAT_H264};
switch(cmd){
case CMD_SET_HEIGHT:
uvc_ctx->height = arg;
break;
case CMD_SET_WIDTH:
uvc_ctx->width = arg;
break;
case CMD_SET_FRAMERATE:
uvc_ctx->frame_rate = arg;
break;
case CMD_SET_CPZRATIO:
uvc_ctx->compression_ratio = arg;
break;
case CMD_SET_FRAMETYPE:
uvc_ctx->fmt_type = codec_map[arg&0xF];
break;
case CMD_SET_APPLY:
if(uvc_set_param(uvc_ctx->fmt_type, &uvc_ctx->width, &uvc_ctx->height, &uvc_ctx->frame_rate, &uvc_ctx->compression_ratio) < 0)
ret = EIO;
break;
case CMD_GET_STREAM_READY:
parg = (int *)arg;
*parg = uvc_is_stream_ready();
break;
case CMD_GET_STREAM_STATUS:
parg = (int *)arg;
*parg = uvc_is_stream_on();
break;
case CMD_SET_STREAMMING:
if(arg == ON){ // stream on
if(uvc_stream_on() < 0)
ret = EIO;
}else{ // stream off
uvc_stream_off();
}
break;
default:
ret = ENOTSUPP;
break;
}
return ret;
}
int cnt = 0;
//#include "sample_jpeg.h"
int uvc_mod_handle(void* ctx, void* b)
{
int ret = 0;
exch_buf_t *exbuf = (exch_buf_t*)b;
struct uvc_buf_context buf;
if(exbuf->state==STAT_USED){
memset(&buf, 0, sizeof(struct uvc_buf_context));
buf.index = exbuf->index;
ret = uvc_qbuf(&buf);
exbuf->state = STAT_INIT;
}
/*get uvc buffer for new data*/
if(exbuf->state!=STAT_READY){
ret = uvc_dqbuf(&buf);
if(buf.index < 0){
return -EAGAIN;
}//empty buffer retrieved set payload state as IDLE
if((uvc_buf_check(&buf)<0)||(ret < 0)){
printf("\n\rbuffer error!");
uvc_stream_off();
return -EIO; // should return error
}
/*
if(cnt++&0x1){
exbuf->data = (unsigned char *)PIC_320x240_2;
exbuf->len = PIC_LEN_2;
}else{
exbuf->data = (unsigned char *)PIC_320x240_1;
exbuf->len = PIC_LEN_1;
}
*/
exbuf->index = buf.index;
exbuf->data = buf.data;
exbuf->len = buf.len;
exbuf->timestamp = 0;
//vTaskDelay(500);
exbuf->state = STAT_READY;
}
return 0;
}
msrc_module_t uvc_module =
{
.create = uvc_mod_open,
.destroy = uvc_mod_close,
.set_param = uvc_mod_set_param,
.handle = uvc_mod_handle,
};

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff