ffmpeg_VideoTranscode.c 7.8 KB

/* Includes ------------------------------------------------------------------*/
#include <fcntl.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>

// 自建库 
#include "../VideoTranscode.h"
#include "JZsdkLib.h"

/* Private constants ---------------------------------------------------------*/
#define FFMPEG_CMD_BUF_SIZE                 (256 + 256)

//转码模式
#define H264_TRANSCODETO_JPG        (1)
#define H264_TRAMSCODETO_MP4        (2)
#define H264_TRAMSCODETO_JPG_BURST        (3)

/* Private types -------------------------------------------------------------*/
static void *ffmpeg_VideoTranscodeTask(void *arg);

static int tanscodemode = 0;
static int GPS_Receive_Date = 0;
static int GPS_Receive_Time = 0;


extern int VideoTranscode_Flag ; //视频转码标志位,off为转码完毕,on为转码完成
extern int PhotoTranscode_Flag ;  //图片转码标志位,off为转码完毕,on为转码完成

FILE *NUMBER_SET_fp;
char number_set[6];


//互斥锁
static pthread_mutex_t TranscodeLock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t TransCond = PTHREAD_COND_INITIALIZER;

//转码服务函数
// 服务初始化函数
T_JZsdkReturnCode ffmpeg_VideoTranscode_Sever(void)
{

	pthread_t WriteDataTask;
	pthread_attr_t task_attribute; //线程属性
	pthread_attr_init(&task_attribute);  //初始化线程属性
	pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED);      //设置线程分离属性
	int opus_Protection = pthread_create(&WriteDataTask,&task_attribute,ffmpeg_VideoTranscodeTask,NULL);		//线程
	if(opus_Protection != 0)
	{
		JZSDK_LOG_ERROR("创建视频转码线程失败!");
		return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
	}
    
    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

/*

            转码函数部分

*/

// 拍照转码函数
static T_JZsdkReturnCode ffmpeg_ShootPhoto_transcode()
{
    //打开转码标志位
    if (PhotoTranscode_Flag == JZ_FLAGCODE_ON)
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }
    PhotoTranscode_Flag = JZ_FLAGCODE_ON;

    //ffmpeg指令
    char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];    
    int ret;

    //地址拼接
    char str1[40] = "/root/sdcard/DCIM/Photos/PSDK_PHOTO";
    int  str2 ;
    char str3[6] = ".jpg";

	char *ffmpeg_ShootPhoto_CallBack_InPath =  "/root/sdcard/DCIM/Photos/temp.h264"; 
    char ffmpeg_ShootPhoto_CallBack_OutPath[FFMPEG_CMD_BUF_SIZE];

    //输出名字修改
    NUMBER_SET_fp = fopen("/root/sdcard/DCIM/Photos/pthoto_number.txt","r+");
    if(NUMBER_SET_fp == NULL)
    {
        NUMBER_SET_fp = fopen("/root/sdcard/DCIM/Photos/pthoto_number.txt","w+");
        fwrite("00000", 1, 5, NUMBER_SET_fp);
        fseek(NUMBER_SET_fp, 0, SEEK_SET);
    }   
    
    fread(number_set, 1, 5, NUMBER_SET_fp);
    str2 = atoi(number_set) + 1;
    snprintf(number_set, 6, "%05d", str2);

    fseek(NUMBER_SET_fp, 0, SEEK_SET);
    fwrite(number_set, 1, 5, NUMBER_SET_fp);

    //snprintf(ffmpeg_ShootPhoto_CallBack_OutPath, 256, "%s_%d_%d%s", str1,GPS_Receive_Date,GPS_Receive_Time,str2);
    snprintf(ffmpeg_ShootPhoto_CallBack_OutPath, 256, "%s_%s%s", str1, number_set, str3);

    fclose(NUMBER_SET_fp);
    NUMBER_SET_fp = NULL;
    
    JZSDK_LOG_INFO("ffmpeg_ShootPhoto_CallBack_OutPath:%s",ffmpeg_ShootPhoto_CallBack_OutPath);
    //JZSDK_LOG_INFO("%s",ffmpeg_ShootPhoto_CallBack_OutPath);

    //将h264照片转换为jpg格式
    snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE,
             "echo \"y\" | ffmpeg -i \"%s\" -y -f image2 -t 0.001 -s 1980*1080 \"%s\" >/dev/null 2>&1", 
             ffmpeg_ShootPhoto_CallBack_InPath,
             ffmpeg_ShootPhoto_CallBack_OutPath);

    //JZSDK_LOG_INFO("ffmpegCmdStr:%s",ffmpegCmdStr);
    JZSDK_LOG_INFO("录像保存位置:%s",ffmpeg_ShootPhoto_CallBack_OutPath);


    JZsdk_RunSystemCmd(ffmpegCmdStr);

    PhotoTranscode_Flag = JZ_FLAGCODE_OFF;
}

// 录像转码函数
static void ffmpeg_RecordVideo_transcode()
{
    //打开转码标志位
    if (VideoTranscode_Flag == JZ_FLAGCODE_ON)
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }
    VideoTranscode_Flag = JZ_FLAGCODE_ON;

    //ffmpeg指令
    char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];    

    char *ffmpeg_RecordVideo_InPath =  "/root/sdcard/DCIM/Videos/temp.h264"; 
    char ffmpeg_RecordVideo_OutPath[FFMPEG_CMD_BUF_SIZE];   


    //转码
    char str1[40] = "/root/sdcard/DCIM/Videos/PSDK_VIDEO";
    int  str2;
    char str3[10] = ".mp4";

    //输出名字修改
    NUMBER_SET_fp = fopen("/root/sdcard/DCIM/Videos/video_number.txt","r+");
    if(NUMBER_SET_fp == NULL)
    {
        NUMBER_SET_fp = fopen("/root/sdcard/DCIM/Videos/video_number.txt","w+");
        fwrite("00000", 1, 5, NUMBER_SET_fp);
        fseek(NUMBER_SET_fp, 0, SEEK_SET);
    }   
    
    fread(number_set, 1, 5, NUMBER_SET_fp);
    str2 = atoi(number_set) + 1;
    snprintf(number_set, 6, "%05d", str2);

    fseek(NUMBER_SET_fp, 0, SEEK_SET);
    fwrite(number_set, 1, 5, NUMBER_SET_fp);

    //snprintf(ffmpeg_RecordVideo_OutPath, 256, "%s_%d_%d%s", str1,GPS_Receive_Date,GPS_Receive_Time,str2);
    snprintf(ffmpeg_RecordVideo_OutPath, 256, "%s_%s%s", str1, number_set, str3);

    fclose(NUMBER_SET_fp);
    NUMBER_SET_fp = NULL;

    //将h264视频转换为mp4格式
    snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE,
             "echo \"y\" | ffmpeg -i \"%s\" -y -vcodec copy \"%s\" >/dev/null 2>&1",
                ffmpeg_RecordVideo_InPath,
                ffmpeg_RecordVideo_OutPath);

    //ffmpeg -f h264 -i xxx.264 -vcodec copy xxx.mp4
    //JZSDK_LOG_INFO("ffmpegCmdStr:%s",ffmpegCmdStr);

    JZSDK_LOG_INFO("录像保存位置:%s",ffmpeg_RecordVideo_OutPath);

    JZsdk_RunSystemCmd(ffmpegCmdStr);

    VideoTranscode_Flag = JZ_FLAGCODE_OFF;

}


// 连拍转码函数
static void ffmpeg_ShootPhoroBurst_transcode()
{
    
    //ffmpeg指令
    char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];    
    char *ffmpeg_ShootPhoroBurst_InPath =  "/root/sdcard/DCIM/Videos/temp.h264"; 
    char ffmpeg_ShootPhoroBurst_OutPath[FFMPEG_CMD_BUF_SIZE];   


    //转码
    char str1[40] = "/root/sdcard/DCIM/Photos/video_";
    char str2[10] = ".mp4";

    //根据时间写名字
    snprintf(ffmpeg_ShootPhoroBurst_OutPath, 256, "%s_%d_%d%s", str1,GPS_Receive_Date,GPS_Receive_Time,str2);

    //将h264照片转换为jpg格式
    snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE,
             "echo \"y\" | ffmpeg -i \"%s\" -r 25 -f image2 -t 0.001 -s 1280*720 \"%s\" >/dev/null 2>&1", 
             ffmpeg_ShootPhoroBurst_InPath,
             ffmpeg_ShootPhoroBurst_OutPath);

    //ffmpeg -i output.mp4 -r 30 -f image2 foo-%05d.jpeg
    JZSDK_LOG_INFO("录像保存位置:%s",ffmpeg_ShootPhoroBurst_OutPath);

    
    JZsdk_RunSystemCmd(ffmpegCmdStr);
    
}

/*

            转码解锁函数

*/

//拍照转码解锁函数
void ffmpeg_H264_tanscodeto(int mode)
{
    tanscodemode = mode;

    pthread_mutex_unlock(&TranscodeLock);
}

/*

            gps时间接受函数

*/
void ffmpeg_tanscode_DateAndTime_Receive(int date,int time)
{
    GPS_Receive_Date = date;
    GPS_Receive_Time = time;
}


//转码线程
static void *ffmpeg_VideoTranscodeTask(void *arg)
{


    while (1) {

        pthread_mutex_lock(&TranscodeLock);

        JZSDK_LOG_INFO("s_VideoTranscode_Mutex解锁线程");

        //如果为拍照转码
        if(tanscodemode == H264_TRANSCODETO_JPG)
        {
            // //ffmpeg_CameraTransLock(true);
            ffmpeg_ShootPhoto_transcode();
            //ffmpeg_CameraTransLock(false);
        }

        //如果为录像转码
        if(tanscodemode == H264_TRAMSCODETO_MP4)
        {
            //ffmpeg_CameraTransLock(true);
            ffmpeg_RecordVideo_transcode();
            //ffmpeg_CameraTransLock(false);

        }
        
        // //如果为连拍转码
        // if(tanscodemode == H264_TRAMSCODETO_JPG_BURST)
        // {
        //     ffmpeg_ShootPhoroBurst_transcode();
        // }

        tanscodemode = JZ_FLAGCODE_OFF;
    }
}