#include <stdio.h>
#include <iostream>
#include "../common/comm.h"
#include "../common/iobuffer.h"
#include "api.h"
#include "protocol.pb.h"
#include "message_queue.h"
#include <signal.h>
#include <cstring>
#include <stdlib.h>




void daemonize(void) {
  signal(SIGTTOU, SIG_IGN);
  signal(SIGTTIN, SIG_IGN);
  signal(SIGTSTP, SIG_IGN);
  if (0 != fork()) exit(0);
  if (-1 == setsid()) exit(0);
  signal(SIGHUP, SIG_IGN);
  if (0 != fork()) exit(0);
  //if (0 != chdir("/")) exit(0);
}
 
bool checkOnly()
{
    const char filename[]  = "./lockfile";
    int fd = open (filename, O_WRONLY | O_CREAT , 0644);
    int flock = lockf(fd, F_TLOCK, 0 );
    if (fd == -1) {
        return false;
    }
    //给文件加锁
    if (flock == -1) {
        return false;
    }
    //程序退出后,文件自动解锁
    return true;
}
std::string getpath()
{
	  char exec_name [BUFSIZ];
	 readlink ("/proc/self/exe", exec_name, BUFSIZ);
	 int32_t len=strlen(exec_name);
     for(int i=len;i>=0;i--)
     {
         if(exec_name[i]=='/')
           {
               exec_name[i]=0;
               break;
           }
     }
	 return std::string(exec_name);
}


int main(int argc,char *argv[])
{

   //system("pulseaudio --start");
  //  daemonize();
    auto path=getpath();
    std::cout<<path<<std::endl;
    if(-1==chdir(path.c_str())) return 0;
    
    if(checkOnly()==false) 
    {
        std::cout<<"进程已经在运行"<<std::endl;
        return 0;
    }

    
    
    //20231106-YUV转h.264
    
    /*
	AVCodec* codec = NULL;
	//AVCodecContext* codecContent = NULL;
	//AVPacket* packet = NULL;
	//AVFrame* frame = NULL;

    FILE* inFile = nullptr;
	FILE* outFile = nullptr;


    //查找指定编码器

    codec = avcodec_find_encoder(AV_CODEC_ID_H264);
	if (codec == NULL)
		printf("could not find h264 encoder!\r\n");
    else
        printf("could find h264 encoder!\r\n");
       */ 
    /*
    //申请编码器上下文
	codecContent = avcodec_alloc_context3(codec);
	if (codecContent == nullptr)
		printf("could not alloc h264 content!\r\n");

    //必设参数
	codecContent->width = 1280;
	codecContent->height = 720;
	codecContent->time_base = AVRational{ 1, 25 };
    codecContent->max_b_frames = 1;
	codecContent->pix_fmt = AV_PIX_FMT_YUV420P;
	codecContent->gop_size = 10; //关键帧间隔,默认250
	codecContent->framerate = AVRational{ 25, 1 };
 
	//初始化编码器上下文
	ret = avcodec_open2(codecContent, codec, NULL);
	if (ret < 0) 
		printf("Could not open codec: \r\n");

    packet = av_packet_alloc();
	if (packet == nullptr)
		printf("alloc packet error\r\n");
 
	frame = av_frame_alloc();
	if (packet == nullptr)
		printf("alloc frame error\r\n");

    //必设参数
	frame->width = codecContent->width;
	frame->height = codecContent->height;
	frame->format = codecContent->pix_fmt;

    //申请视频数据存储空间
	ret = av_frame_get_buffer(frame, 0);
	if (ret)
		printf("alloc frame buffer error!\r\n");

    inFile = fopen(inFileName, "rb");
	if (inFile == nullptr)
		printf("error to open inFile: %s\r\n", inFileName);

    outFile = fopen(outFileName, "wb+");
	if (inFile == nullptr)
		printf("error to open outFile: %s\n", outFileName);

    int framecount = 0;
	frame->pts = 0;
 
	int start_time = av_gettime() / 1000; //毫秒级
    while (!feof(inFile))
	{
		ret = av_frame_is_writable(frame);
		if (ret < 0)
			ret = av_frame_make_writable(frame);
 
 
		fread(frame->data[0], 1, frame->width * frame->height, inFile); //y
		fread(frame->data[1], 1, frame->width * frame->height / 4, inFile); //u
		fread(frame->data[2], 1, frame->width * frame->height / 4, inFile);  //v
 
		printf("encode frame num: %d\n", ++framecount);
 
 
		frame->pts += 1000 / (codecContent->time_base.den / codecContent->time_base.num);
		encode(codecContent, packet, frame, outFile);
 
	}
    
    encode(codecContent, packet, nullptr, outFile);
	printf("encode time cost: %d ms\n ", av_gettime() / 1000 - start_time);
 
	av_packet_free(&packet);
	av_frame_free(&frame);
	avcodec_free_context(&codecContent);
	fclose(inFile);
	fclose(outFile);
    */
   /*
   int16_t hi=(int16_t)(0x8c & 0x00FF);
   int16_t low= (int16_t)(0x9E & 0x00FF);
   unsigned int mmmm = (hi<<8)|low;
    */
    CMessageQueue Q;
    Q.Create();
	while(true)
    {
		Q.Process();
	}
    //gtk_main();
     
    return 0;
}