VideoMgmt_Thread_Multi.c 4.3 KB
/**************************************************
 * 
 *    文件名:VideoMgmt的多线程处理模式
 * 
 * **********************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#include "JZsdkLib.h"
#include "BaseConfig.h"

#include "./VideoMgmt.h"
#include "../MediaParm.h"
#include "./VideoMgmt_Parm.h"


static void *VideoMgmt_VideoStreamFlow_Thread(void *args)
{
    struct VideoMgmt_VideoStreamFlow *VideoPush = (struct VideoMgmt_VideoStreamFlow *)args;  
    int delay_time_ms = (1000/VideoPush->FrameNumber); //得出延时的ms

    unsigned char *FreezeData = NULL;
    unsigned int FreezeDataLen = 0;
    int VideoFreezeFlag = JZ_FLAGCODE_OFF;

    while (1)
    { 
        delayMs(delay_time_ms);

        //判断是否用视频流是否用的是当前这个
        if (VideoPush->VideoStreamFlowIndex != VideoMgmt_GetVideoStreamFlowIndexNum())
        {
            continue; 
        }

        //推流操作
        //读取数据
        unsigned char *data = NULL;  
        unsigned int data_len = 0;  
        
        //如果视频为大疆H264型 或 JZH264型
        if (VIDEOMGMT_VIDEO_TPYE == VIDEOMGMT_TPYE_DJIH264 || VIDEOMGMT_VIDEO_TPYE == VIDEOMGMT_TPYE_JZH264 ) 
        {
            VideoMgmt_read_data((void **)VideoPush->index, &data, &data_len, VIDEOMGMT_USE_FRAMEEND, VIDEO_FRAME_AUD_NO1_LEN); //读取
            memcpy(data + data_len, FrameAudInfo_NO1, VIDEO_FRAME_AUD_NO1_LEN);
            data_len = data_len + VIDEO_FRAME_AUD_NO1_LEN;
        }
        else
        {
            VideoMgmt_read_data((void **)VideoPush->index, &data, &data_len, JZ_FLAGCODE_OFF, JZ_FLAGCODE_OFF); //读取
        }

        //获取冻结标志位
        VideoMgmt_param(JZ_FLAGCODE_SET, VIDEO_MGMT_FREEZE, &VideoFreezeFlag);

        //冻结功能
        if (VideoFreezeFlag == JZ_FLAGCODE_ON)
        {
            //如果冻结数据为空,且 当前为i帧
            if (FreezeData == NULL && data[4] == 0x67)
            {
                FreezeDataLen = data_len;
                JZsdk_Malloc((void **)&FreezeData, data_len);
                memcpy(FreezeData, data, data_len);
            }
        }
        
        //冻结开了就推送冻结画面
        if (VideoFreezeFlag == JZ_FLAGCODE_ON && FreezeDataLen != 0)
        {
            VideoMgmt_VideoStreamToDeal(FreezeData, FreezeDataLen);
        }
        //否则推送正常画面
        else
        {
            VideoMgmt_VideoStreamToDeal(data, data_len);
        }

        // 释放数据(如果有必要的话)  
        if (data) {  
            printf("释放1\n");
            free(data);  
            data = NULL;  
        }  
        data_len = 0;

        if (VideoFreezeFlag == JZ_FLAGCODE_OFF)
        {
            if (FreezeData) {  
                free(FreezeData);  
                FreezeData = NULL;  
            }    
            FreezeDataLen = 0;
        }        
    }

    pthread_exit(NULL);  
    return NULL;  
}




/************************
 * 
 *  开启流转区块
 *  
 * 
 * 
 * ***********************/
T_JZsdkReturnCode VideoMgmt_VideoStreamFlow_Init(int FrameNumber, void **index, int VideoStreamFlowIndex)
{
    struct VideoMgmt_VideoStreamFlow *VideoStreamFlow = NULL;
    
    // 分配新内存并复制数据
    VideoStreamFlow = (struct VideoMgmt_VideoStreamFlow *)malloc(sizeof(struct VideoMgmt_VideoStreamFlow));  
    if (VideoStreamFlow == NULL) {  
        JZSDK_LOG_ERROR("视频流流转模块注册失败");  
        return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;  
    }  

    VideoStreamFlow->index = index;
    VideoStreamFlow->FrameNumber = FrameNumber;
    VideoStreamFlow->VideoStreamFlowIndex = VideoStreamFlowIndex;

    //创建视频流流转线程
    pthread_t ReadDataTask;
	pthread_attr_t task_attribute; //线程属性
	pthread_attr_init(&task_attribute);  //初始化线程属性
	pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED);      //设置线程分离属性
	int ret = pthread_create(&ReadDataTask,&task_attribute,(void *)VideoMgmt_VideoStreamFlow_Thread,VideoStreamFlow);		//线程
	if(ret != 0)
	{
		JZSDK_LOG_ERROR("创建视频流流转线程失败!");
		return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
	}

    JZSDK_LOG_INFO("视频流流转模块初始化完毕");

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}