main_dvpp.cpp 8.6 KB
#include <iostream>
#include <pthread.h>
#include <thread>
#include <chrono>
#include <unistd.h>


#ifdef _WIN32
#include "Winsock2.h"
#pragma comment(lib, "ws2_32.lib")
#endif

#ifdef __linux__
#include "arpa/inet.h"
#endif

#include "../interface/FFNvDecoderManager.h"
#include "../interface/utiltools.hpp"

#define MIN_RTP_PORT		10000
#define MAX_RTP_PORT		60000

// ȡ MIN_RTP_PORT(10000)~MAX_RTP_PORT(60000)֮�������˿�(ż���������������˿ڿ���)
int allocRtpPort() {

	static int s_rtpPort = MIN_RTP_PORT;
	if (MIN_RTP_PORT == s_rtpPort)
	{
		srand((unsigned int)time(NULL));
		s_rtpPort = MIN_RTP_PORT + (rand() % MIN_RTP_PORT);
	}

	if (s_rtpPort % 2)
		++s_rtpPort;

	while (true)
	{
		s_rtpPort += 2;
		s_rtpPort = s_rtpPort >= MAX_RTP_PORT ? MIN_RTP_PORT : s_rtpPort;

		int i = 0;
		for (; i < 2; i++)
		{
			sockaddr_in sRecvAddr;
			int s = socket(AF_INET, SOCK_DGRAM, 0);

			sRecvAddr.sin_family = AF_INET;        
			sRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);    
			sRecvAddr.sin_port = htons(s_rtpPort + i); 

			int nResult = bind(s, (sockaddr *)&sRecvAddr, sizeof(sRecvAddr));
			if (nResult != 0)
			{
				break;
			}

			nResult = close(s);
			if (nResult != 0)
			{
				printf("closesocket failed:%d\n", nResult);
				break;
			}
		}

		if (i == 2)
			break;
	}

	return s_rtpPort;
}





unsigned char *pHwRgb[2] = {nullptr, nullptr};

int sum1 = 0;
int sum2 = 0;


string data_home = "/mnt/data/cmhu/tmp/";




/**
 * 注意: gpuFrame 在解码器设置的显卡上,后续操作要十分注意这一点,尤其是多线程情况
 * */
void postDecoded(const void * userPtr, DeviceRgbMemory* devFrame){
    AbstractDecoder* decoder = (AbstractDecoder*)userPtr;
    if (decoder!= nullptr)
    {
    }

    if(devFrame){
        delete devFrame;
        devFrame = nullptr;
    }
}

long start_time = 0;
long end_time = 0;
bool count_flag = false;
int count = 0;
int count_std = 100;


static int sum = 0;
unsigned char *pHwData = nullptr;

void postDecoded0(const void * userPtr, DeviceRgbMemory* devFrame){
    // std::this_thread::sleep_for(std::chrono::milliseconds(30000));

    AbstractDecoder* decoder = (AbstractDecoder*)userPtr;
    if (decoder!= nullptr)
    {
        // cout << "decode name: " << decoder->getName() << endl;
        if (decoder->getName() == "dec")
        {
            if (! count_flag)
            {
                count_flag = true;
                count = 0;
                end_time = start_time = UtilTools::get_cur_time_ms();
            }
            count++;
            sum ++ ;
            if (count >= count_std)
            {
                // end_time = UtilTools::get_cur_time_ms();
                // long time_using = end_time - start_time;
                // double time_per_frame = double(time_using)/count_std ;
                // cout << count_std << "帧用时:" << time_using << "ms 每帧用时:" << time_per_frame << "ms" << endl;
                cout << decoder->getName() << " keyframe: " << devFrame->isKeyFrame() << " width: " << devFrame->getWidth() << " height: "<< devFrame->getHeight() << endl;
                // cout << gpuFrame->pts << endl;

                count_flag = false;
            }
            // cout << "帧数:" << sum << endl;
        }
    }
}

void decode_finished_cbk(const void* userPtr){
    cout << "当前时间戳: " << UtilTools::get_cur_time_ms() << endl;
}

bool decode_request_stream_cbk(const char* deviceId){
    cout << "需在此请求流" << endl;
    return true;
}

// string test_uri = "rtmp://192.168.10.56:1935/objecteye/1";
// string test_uri = "/home/cmhu/data/output_800x480.mp4";
// string test_uri = "/home/cmhu/data/output_1920x1080.mp4";
// string test_uri = "rtsp://176.10.0.2:8554/stream";
// string test_uri = "/mnt/f/fiss/test_data/h265.mp4";
// string test_uri = "rtsp://176.10.0.4:8554/stream";
// string test_uri = "rtsp://admin:admin@123456@192.168.60.176:554/cam/realmonitor?channel=1&subtype=0";
string test_uri = "/home/huchunming/data/woyikewangh265.mp4";

void createDecode(int index, const char* gpu_id){
    FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
    MgrDecConfig config;
    config.name = "dec" + to_string(index);
    config.cfg.uri = test_uri;
    config.cfg.post_decoded_cbk = postDecoded;
    config.cfg.decode_finished_cbk = decode_finished_cbk;
    config.cfg.force_tcp = true;
    config.dec_type = DECODER_TYPE_FFMPEG;

    config.cfg.gpuid = gpu_id;
    // if (index % 2 == 0)
    // {
    //     config.cfg.gpuid = "0";
    // }
    // else
    // {
    //     config.cfg.gpuid = "0";
    // }
    
    AbstractDecoder* decoder = pDecManager->createDecoder(config);
    if (!decoder)
    {
        return ;
    }
    pDecManager->setPostDecArg(config.name, decoder);
    pDecManager->setFinishedDecArg(config.name, decoder);
    pDecManager->startDecodeByName(config.name);
}

void createGB28181Decode(int index, char* gpu_id, int port){
    FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
    MgrDecConfig config;
    config.name = "dec" + to_string(index);
    config.cfg.uri = config.name;
    config.cfg.post_decoded_cbk = postDecoded;
    config.cfg.decode_finished_cbk = decode_finished_cbk;
    config.cfg.request_stream_cbk = decode_request_stream_cbk;
    config.cfg.force_tcp = true;

    config.dec_type = DECODER_TYPE_GB28181;
    config.cfg.port = port;//allocRtpPort();

    config.cfg.gpuid = gpu_id;
    
    AbstractDecoder* decoder = pDecManager->createDecoder(config);
    if (!decoder)
    {
        return ;
    }
    pDecManager->setPostDecArg(config.name, decoder);
    pDecManager->setFinishedDecArg(config.name, decoder);
    pDecManager->startDecodeByName(config.name);
}

void createDvppDecoder(int index, char* devId, int channelId){
    FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
    MgrDecConfig config;
    config.name = "dec" + to_string(index);
    config.cfg.uri = test_uri;
    config.cfg.post_decoded_cbk = postDecoded;
    config.cfg.decode_finished_cbk = decode_finished_cbk;
    config.cfg.force_tcp = true;
    config.dec_type = DECODER_TYPE_DVPP;

    config.cfg.gpuid = devId;
    
    AbstractDecoder* decoder = pDecManager->createDecoder(config);
    if (!decoder)
    {
        cout << "创建解码器失败" << endl;
        return ;
    }
    pDecManager->setPostDecArg(config.name, decoder);
    pDecManager->setFinishedDecArg(config.name, decoder);
    pDecManager->startDecodeByName(config.name);
}

void logFF(void *, int level, const char *fmt, va_list ap)
{
    vfprintf(stdout, fmt, ap);
}


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

    // test_uri = argv[1];
    char* gpuid = argv[2];
    int port = atoi(argv[3]);
    cout << test_uri << "   gpu_id:" << gpuid << "   port:" << port << endl;

    // av_log_set_callback(&logFF);

    // CheckCUDAProperty(atoi(gpuid));

    pthread_t m_decode_thread;
    pthread_create(&m_decode_thread,0,
        [](void* arg)
        {
            // cudaSetDevice(atoi(gpuid));
            while (true)
            {
                std::this_thread::sleep_for(std::chrono::seconds(10));
                FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
                int count = pDecManager->count();
                cout << "当前时间:" << UtilTools::get_cur_time_ms() << "  当前运行路数: " << pDecManager->count() << endl;
            }  

            return (void*)0;
        }
    ,nullptr);


    FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
    int i = 0;

    while (true)
    {
        int ch = getchar();
        if (ch == 'q')
        {
            break;
        }

        switch (ch)
        {
        case 'f':
        case 'F':
            createDecode(i, gpuid);
            i++;
            break;
        case 'g':
        case 'G':
            createGB28181Decode(i, gpuid, port);
            i++;
            break;
        case 'd':
        case 'D':
            createDvppDecoder(i, gpuid, 0);
            i++;
            break;
        case 'r':
        case 'R':
            pDecManager->resumeDecoder("dec0");
            break;
        case 'p':
        case 'P':
            pDecManager->pauseDecoder("dec0");
            break;

        case 'c':
        case 'C':
            i--;
            pDecManager->closeDecoderByName("dec" + to_string(i));
            break;

        case 'i':
        case 'I':
        {
            int w,h;
            pDecManager->getResolution("dec0", w,h);
            printf( "%s : %dx%d\n", "dec0" , w,h );
        }
            break;

        default:
            break;
        }

        /* code */
    }

    cout << "总共帧数:" << sum << endl;
    pDecManager->closeAllDecoder();
}