不需要进行大数据量的拷贝就可以进行数据传输

这几天在工作中遇到一个问题:

从网络中接收数据,数据量很大,大概在每秒钟10MB左右,也可以说是视频YUV数据的传输。当接收到这些数据后再将这些数据进行编码。

在这个接收和传入编码的过程中不能进行大数据量的拷贝工作,(原因我们都知道,拷贝这么多的数量在ARM上会占用太多的资源),对此我写了一个队列来完成该事情。

由于是YUV图像数据,每帧的大小都是定值,所分配的内存空间大小也都一致。我暂且将我的队列大小定为25个,因为一秒的PAL帧是25左右。另外我分配了多分配两个内存(这两个很重要):其中一个作为第一个从网络上接收的数据存放用,另一个作为第一个出队列用。在这里可能说的不够清楚。-----意思很简单,为了不进行大数据量的拷贝工作,我只进行内存地址的交换。

原理:每次进队列的操作是:保存进入队列的地址,返回一个新的没有使用的地址

        每次出队列的操作是:保存一个使用过的地址,返回一个队列中存放的地址。

 

具体看代码:

 

进队列的操作:

MS_INT32 enqueue_sq_yuv(YUV_FRAME *e)
{ //e插入队尾作为新元素
 //lock_pend(1,SYS_FOREVER);
    YUV_FRAME tmp;

    memcpy (&tmp,e,sizeof(YUV_FRAME));

    if(q == NULL)
    {
        printf("ERROR:sqqueue_yuv not create/n");
        return MD_FAILED;
    }
 lock(lockHandleYuv);
 if ((q->rear + 1) % DEF_MAX_QUEUES_SIZE_YUV == q->front)
 {
        memcpy(e,&(q->base[q->rear]),sizeof(YUV_FRAME));
       
        q->front = (q->front + 1) % DEF_MAX_QUEUES_SIZE_YUV;
  //printf("WARN: sqqueue_yuv is fulling q->rear[%d]/n",q->rear);
       
        //lock_post(1);
  //unlock(lockHandleYuv);
  //return MD_FAILED;
 }else
    {
        memcpy(e,&(q->base[q->rear]),sizeof(YUV_FRAME));
  //printf("INFO: sqqueue_yuv isn't full q->front[%d] q->rear[%d]/n",q->front,q->rear);
    }
  
 //q->base[q->rear] = e;
 memcpy(&(q->base[q->rear]),&tmp,sizeof(YUV_FRAME));
 
 q->rear = (q->rear + 1) % DEF_MAX_QUEUES_SIZE_YUV;
 //lock_post(1);
 unlock(lockHandleYuv);
 return MD_OK;
}

 

出队列的操作:

MS_INT32 dequeue_sq_yuv( YUV_FRAME *e)
{ //出队,返回首元素e的值
 //lock_pend(1,SYS_FOREVER);
    YUV_FRAME tmp;

    memcpy (&tmp,e,sizeof(YUV_FRAME));
    if(q == NULL)
    {
        printf("ERROR: dequeue_sq_yuv sqqueue_yuv not create/n");
        return MD_FAILED;
    }
 lock(lockHandleYuv);
 if (q->front == q->rear)
 {
  //lock_post(1);
  unlock(lockHandleYuv);
  //printf("WARN: dequeue_sq_yuv sqqueue_yuv is empty q->rear[%d]/n",q->rear);
  return MD_FAILED;
 }else
    {
  //printf("INFO: dequeue_sq_yuv sqqueue_yuv isn't empty q->front[%d] q->rear)[%d]/n",q->front,q->rear);
    } 
 //*e = q->base[q->front];
 memcpy(e,&(q->base[q->front]),sizeof(YUV_FRAME));
 if(0)
    {
        e->data = tmp.data;
        memcpy(e->data,q->base[q->front].data,704*576*3/2);

    }else
    {
     memcpy(&(q->base[q->front]),&tmp,sizeof(YUV_FRAME));

    }
    q->front = (q->front + 1) % DEF_MAX_QUEUES_SIZE_YUV;
 //lock_post(1);
 unlock(lockHandleYuv);
 return MD_OK;
}

经过上面的进队和出队便可以进行操作使用。下面是完整的代码

 


#ifndef _YUV_QUEUES_H_
#define _YUV_QUEUES_H_

#include "C2Htype.h"

#define DEF_MAX_QUEUES_SIZE_YUV  10

typedef struct strYUV_FRAME{
 MS_INT32 *pflag;
 MU_INT32 *data;
 MS_INT32 resave[2];
}YUV_FRAME;

typedef struct {
 YUV_FRAME *base;
 MS_INT32 front;
 MS_INT32 rear;
} sqqueue_yuv;


MS_INT32 initqueue_sq_yuv( void ) ;//初始化队列

MS_INT32 enqueue_sq_yuv(YUV_FRAME* e) ;//??en,??de

MS_INT32 dequeue_sq_yuv(YUV_FRAME *e) ;//??e

MS_INT32 queuelength_sq_yuv( void ); //??

MS_INT32 deletequeue_sq_yuv(void) ;//???

MS_INT32 CreatQueue_yuv(MS_INT32 bufSize);

MS_INT32 DestroyQueue_yuv(MS_INT32 bufSize);

 

#endif

 

 

#include "../include/yuv_queues.h"

 

static sqqueue_yuv *q = NULL;
static M_HANDLE lockHandleYuv = NULL;

MS_INT32 initqueue_sq_yuv(void)
{ //初始化顺序队
 q = (sqqueue_yuv *) MM_calloc(sizeof(sqqueue_yuv),0,4);//
 
 q->base = (YUV_FRAME *) MM_alloc(DEF_MAX_QUEUES_SIZE_YUV * sizeof (YUV_FRAME),4);
    memset(q->base,0,DEF_MAX_QUEUES_SIZE_YUV * sizeof (YUV_FRAME));

 if (!q->base)
  return MD_FAILED; //存储分配失败
 q->front = q->rear = 0;
 
 CreatLock(&lockHandleYuv);
 if(lockHandleYuv==NULL)
 {
  printf("ERROR: initqueue_sq_yuv->CreatLock error/n");
  deletequeue_sq_yuv();
  return MD_FAILED;
 }
   
    printf("OK: Create sqqueue_yuv is %08x ,Create Lock is %08x/n",(MU_INT32)q,(MU_INT32)lockHandleYuv);

 return MD_OK;
}

MS_INT32 enqueue_sq_yuv(YUV_FRAME *e)
{ //e插入队尾作为新元素
 //lock_pend(1,SYS_FOREVER);
    YUV_FRAME tmp;

    memcpy (&tmp,e,sizeof(YUV_FRAME));

    if(q == NULL)
    {
        printf("ERROR:sqqueue_yuv not create/n");
        return MD_FAILED;
    }
 lock(lockHandleYuv);
 if ((q->rear + 1) % DEF_MAX_QUEUES_SIZE_YUV == q->front)
 {
        memcpy(e,&(q->base[q->rear]),sizeof(YUV_FRAME));
       
        q->front = (q->front + 1) % DEF_MAX_QUEUES_SIZE_YUV;
  //printf("WARN: sqqueue_yuv is fulling q->rear[%d]/n",q->rear);
       
        //lock_post(1);
  //unlock(lockHandleYuv);
  //return MD_FAILED;
 }else
    {
        memcpy(e,&(q->base[q->rear]),sizeof(YUV_FRAME));
  //printf("INFO: sqqueue_yuv isn't full q->front[%d] q->rear[%d]/n",q->front,q->rear);
    }
  
 //q->base[q->rear] = e;
 memcpy(&(q->base[q->rear]),&tmp,sizeof(YUV_FRAME));
 
 q->rear = (q->rear + 1) % DEF_MAX_QUEUES_SIZE_YUV;
 //lock_post(1);
 unlock(lockHandleYuv);
 return MD_OK;
}

MS_INT32 dequeue_sq_yuv( YUV_FRAME *e)
{ //出队,返回首元素e的值
 //lock_pend(1,SYS_FOREVER);
    YUV_FRAME tmp;

    memcpy (&tmp,e,sizeof(YUV_FRAME));
    if(q == NULL)
    {
        printf("ERROR: dequeue_sq_yuv sqqueue_yuv not create/n");
        return MD_FAILED;
    }
 lock(lockHandleYuv);
 if (q->front == q->rear)
 {
  //lock_post(1);
  unlock(lockHandleYuv);
  //printf("WARN: dequeue_sq_yuv sqqueue_yuv is empty q->rear[%d]/n",q->rear);
  return MD_FAILED;
 }else
    {
  //printf("INFO: dequeue_sq_yuv sqqueue_yuv isn't empty q->front[%d] q->rear)[%d]/n",q->front,q->rear);
    } 
 //*e = q->base[q->front];
 memcpy(e,&(q->base[q->front]),sizeof(YUV_FRAME));
 if(0)
    {
        e->data = tmp.data;
        memcpy(e->data,q->base[q->front].data,704*576*3/2);

    }else
    {
     memcpy(&(q->base[q->front]),&tmp,sizeof(YUV_FRAME));

    }
    q->front = (q->front + 1) % DEF_MAX_QUEUES_SIZE_YUV;
 //lock_post(1);
 unlock(lockHandleYuv);
 return MD_OK;
}

MS_INT32 queuelength_sq_yuv(void) //求对长
{
 return (q->rear - q->front + DEF_MAX_QUEUES_SIZE_YUV) % DEF_MAX_QUEUES_SIZE_YUV;
}

MS_INT32 deletequeue_sq_yuv(void) //删除
{
 if (q != NULL)
 {
  if(NULL != q->base)
   MM_free(q->base,DEF_MAX_QUEUES_SIZE_YUV * sizeof (YUV_FRAME));
   
  MM_free(q,sizeof(sqqueue_yuv));
       
        q = NULL;
  
 }
 return MD_OK;
}

MS_INT32 CreatQueue_yuv(MS_INT32 bufSize)
{
    MU_INT32 i;
    YUV_FRAME tFrame;
    memset(&tFrame,0,sizeof(YUV_FRAME));
    tFrame.data = (MU_INT32 *) MM_alloc(bufSize,4);

    if(tFrame.data == NULL)
    {
        printf("ERROR:CreatQueue_yuv error/n");
        return MD_FAILED;
    }

    initqueue_sq_yuv();
   
    for(i =0;i < DEF_MAX_QUEUES_SIZE_YUV;i++)
    {
        if(tFrame.data == NULL)
        {
            tFrame.data = (MU_INT32 *) MM_alloc(bufSize,4);

            if(tFrame.data == NULL)
            {
                printf("ERROR:CreatQueue_yuv %d  error/n",i);
                return MD_FAILED;
            }else
            {
                //printf("CreatQueue_yuv %d:%08x/n",i,tFrame.data);
            }

        }else
        {
                //printf("CreatQueue_yuv had %d:%08x/n",i,tFrame.data);
        }
        enqueue_sq_yuv(&tFrame);

    }

    return MD_OK;
}

MS_INT32 DestroyQueue_yuv(MS_INT32 bufSize)
{
    MU_INT32 rtn,i;
    YUV_FRAME tFrame;

    memset(&tFrame,0,sizeof(YUV_FRAME));
   
    if(q == NULL)
    {
        printf("ERROR:sqqueue_yuv not create/n");
        return MD_FAILED;
    }

    for(i =0;i < DEF_MAX_QUEUES_SIZE_YUV;i++)
    {
        rtn = dequeue_sq_yuv(&tFrame);
        if(rtn == MD_FAILED)
            continue;
        if(tFrame.data != NULL)
        {
            //printf("INFO:delete %d tFrame.data 0x%08x/n",i,tFrame.data);

   MM_free(tFrame.data,bufSize);

            tFrame.data = NULL;

        }
    }

    deletequeue_sq_yuv() ;
   
    printf("OK: DestroyQueue_yuv ok/n");
   
    return MD_OK;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值