音视频传输,音频优先传输之队列

typedef struct 
{
    unsigned char *Buff;
    unsigned int Head;
    unsigned int Tail;
    unsigned int Len;
    unsigned int VaildLen;
    unsigned int InvaildLen;
}QUEUE_S;

char USER_QueueInit(QUEUE_S *pq, unsigned long buff_size);//初始化队列  
void USER_QueueDestroy( QUEUE_S* pq ); //销毁队列
char USER_QueuePush( QUEUE_S* pq, const unsigned char* dat, unsigned int len );//入队  
unsigned int USER_QueueGetTop(QUEUE_S *pq, unsigned char *rtval, unsigned int len);//获取队头的值,但不删除,返回从队列中读取的字节数 
void USER_QueuePop(QUEUE_S *pq, unsigned int len);//出队  
unsigned int USER_QueueGetVaildLenght(QUEUE_S* pq);
char USER_QueueIsFull(QUEUE_S *pq);
char USER_QueueIsEmpty(QUEUE_S *pq);


char USER_QueueInit( QUEUE_S* pq, unsigned long buff_size ) //初始化队列
{
    pq->Buff = ( HI_U8* )malloc( sizeof( HI_U8 ) * buff_size );
    if ( NULL == pq->Buff )
    {
        printf( "%s: malloc failed!\n", __FUNCTION__ );
        return -1;
    }
    pq->Head = 0;
    pq->Tail = 0;
    pq->Len = buff_size;
    pq->VaildLen = 0;
    pq->InvaildLen = buff_size - 1;     //队列头前面一个字节不能存放数据,如果存了,头跟尾指向同一个地方
    
    return 0;
}

void USER_QueueDestroy( QUEUE_S* pq ) //销毁队列
{
    free(pq->Buff);
}


char USER_QueuePush( QUEUE_S* pq, const unsigned char* dat, unsigned int len ) //入队
{
    unsigned int i;

    if ( ( USER_QueueIsFull( pq ) ) || ( pq->InvaildLen < len ) )
    {
        return -1;
    }
    for( i = 0; i < len; i++ )
    {
        pq->Buff[pq->Tail] = dat[i];
        pq->Tail = ( pq->Tail + 1 ) % pq->Len;
    }

    pq->VaildLen += len;
    pq->InvaildLen = pq->InvaildLen - len;
    return 0;
}


unsigned int USER_QueueGetTop( QUEUE_S* pq, unsigned char *rtval, unsigned int len ) //获取队头的值,但不删除
{
    unsigned int temp, i;
    unsigned int temp_Head = pq->Head;

    if ( USER_QueueIsEmpty( pq ) )
    {
        return 0;
    }

    if( ( pq->Len - pq->InvaildLen - 1) < len )
    {
        temp = pq->Len - pq->InvaildLen -1;
    }
    else
    {
        temp = len;
    }

    for( i = 0; i < temp; i++ )
    {
        rtval[i] = pq->Buff[temp_Head];
        temp_Head = ( temp_Head + 1 ) % pq->Len;
    }

    return temp;
}


void USER_QueuePop( QUEUE_S* pq, unsigned int len ) //出队
{
    if ( USER_QueueIsEmpty( pq ) )
    {
        return;
    }

    if( pq->VaildLen <= len )
    {
        pq->Head = pq->Tail;
        pq->VaildLen = 0;
        //队列头前面一个字节不能存放数据,如果存了,头跟尾指向同一个地方
        pq->InvaildLen = pq->Len-1;
    }
    else
    {
        pq->Head = ( pq->Head + len ) % pq->Len;
        pq->VaildLen -= len;
        pq->InvaildLen += len;
    }
}


unsigned int USER_QueueGetVaildLenght(QUEUE_S* pq)
{
    return pq->VaildLen;
}
char USER_QueueIsFull( QUEUE_S* pq )
{
    return ( pq->Tail + 1 ) % pq->Len == pq->Head;
}
char USER_QueueIsEmpty( QUEUE_S* pq )
{
    return pq->Tail == pq->Head;;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中的FFmpeg库提供了强大的功能,可以用来实现行车记录仪的视频录制功能。 首先,我们需要在Android项目中集成FFmpeg库。可以通过在build.gradle文件中添加FFmpeg库的依赖来实现。然后,在代码中使用JNI来调用FFmpeg库的相关功能。 接下来,我们需要实现视频录制的逻辑。首先,要初始化音视频的采集参数,包括视频帧率、分辨率、音频采样率等。然后,通过Android的Camera API来获取相机实例,并设置预览参数。接着,通过FFmpeg来编码音视频数据,并将编码后的数据写入到视频文件中。 在录制过程中,我们可以通过Android的传感器API获取设备的加速度、方向等信息,以及通过GPS模块获取位置信息,并将这些信息写入到视频文件的metadata中。 另外,为了提高录制的实时性和稳定性,我们可以使用多线程技术来实现数据的采集、编码和写入操作,并使用缓冲队列来平衡不同线程之间的数据传输。此外,也可以通过设置合理的编码参数,如码率、GOP等来控制视频文件的质量和大小。 最后,当需要停止录制时,我们只需要释放相机资源,并关闭FFmpeg的编码和写入操作,最终生成的视频文件就是我们所期望的行车记录仪视频。 综上所述,通过Android中的FFmpeg库,我们可以实现行车记录仪的视频录制功能,并将视频、音频数据以及其他相关信息进行编码和写入。这样,我们就可以轻松实现行车记录仪这种实用的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值