• 1223 and


    1218 ok

    #ifndef _CRT_SECURE_NO_WARNINGS
    #define _CRT_SECURE_NO_WARNINGS
    #endif
    #include <android/log.h>
    #include "xop/RtmpServer.h"
    #include "xop/HttpFlvServer.h"
    #include "xop/RtmpPublisher.h"
    #include "xop/RtmpClient.h"
    #include "xop/HttpFlvServer.h"
    #include "xop/H264Parser.h"
    #include "net/EventLoop.h"
    #include <errno.h>
    
    
    #define TEST_RTMP_PUSHER  1
    #define TEST_RTMP_CLIENT  0
    #define TEST_MULTI_THREAD 0
    #define RTMP_URL    "rtmp://127.0.0.1:1935/live/01"
    #define PUSH_FILE   "./test.h264"
    #define HTTP_URL    "http://127.0.0.1:8080/live/01.flv"
    
    
    #define TAG "zj"
    
    #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
    #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
    #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
    #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
    
    
    
    #define   GBUFF_MAX_SIZE 10*1024 * 1024
    #define   ONE_READ_SIZE 1024*1024
    
    char gbuf[GBUFF_MAX_SIZE] = { 0 };
    int  gbufDatasize = 0;
    int  gBytesRead = 0;
    
    int TestRtmpPublisher(xop::EventLoop *event_loop);
    char * sdPath = "data/data/com.example.testrtsp/1218.h264";
    
    void WriteGbufToFile(){
        FILE *m_file = NULL;
        m_file = fopen(sdPath, "wb");
        if (m_file == NULL)
        {
            LOGE("Open %s error %d!",sdPath,errno);
            return ;
        }    
        int ret = fwrite(gbuf,gbufDatasize,1,m_file);
        LOGE("ret %d --->!",ret);
          fclose(m_file);
        return;
    
    }
    
    
    int rtmpMain()
    {
        LOGE("rtmpMain---->");
    
        //WriteGbufToFile();
        //return 0;
    
        int count = 1; 
    #if TEST_MULTI_THREAD
        count = std::thread::hardware_concurrency();
    #endif
        xop::EventLoop event_loop(count);
    
        /* rtmp server example */
        auto rtmp_server = xop::RtmpServer::Create(&event_loop);
        rtmp_server->SetChunkSize(60000);
        //rtmp_server->SetGopCache(); /* enable gop cache */
        rtmp_server->SetEventCallback([](std::string type, std::string stream_path) {
            LOGE("[Event] %s, stream path: %s\n\n", type.c_str(), stream_path.c_str());
        });
        if (!rtmp_server->Start("0.0.0.0", 1935)) {
            LOGE("RTMP Server listen on 1935 failed.\n");
        }
    
        /* http-flv server example */
        /*
        xop::HttpFlvServer http_flv_server; 
        http_flv_server.Attach(rtmp_server);
        if (!http_flv_server.Start("0.0.0.0", 8080)) {
            printf("HTTP FLV Server listen on 8080 failed.\n");
        }*/
    
    #if TEST_RTMP_PUSHER
        /* rtmp pusher example */
        std::thread t([&event_loop] () {
            TestRtmpPublisher(&event_loop);
        });
        t.detach();
    #endif 
    /*
    #if    TEST_RTMP_CLIENT
        auto rtmp_client = xop::RtmpClient::Create(&event_loop);
        rtmp_client->SetFrameCB([](uint8_t* payload, uint32_t length, uint8_t codecId, uint32_t timestamp) {
            printf("recv frame, type:%u, size:%u,\n", codecId, length);
        });
    
        std::string status;
        if (rtmp_client->OpenUrl(RTMP_URL, 3000, status) != 0) {
            printf("Open url %s failed, status: %s\n", RTMP_URL, status.c_str());
        }
    #endif
    */
    
        while (1) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        
        rtmp_server->Stop();
        //http_flv_server.Stop();
        return 0;
    }
    
    
    class H264File
    {
    public:
        H264File(int bufSize = 5000000);
        ~H264File();
    
        bool open(const char *path);
        void Close();
    
        bool isOpened() const
        {
            return (m_file != NULL);
        }
    
        int readFrame(char *inBuf, int inBufSize, bool *bEndOfFrame);
        int readFrameFromGbuf(char* inBuf, int inBufSize, bool* bEndOfFrame);
        int readfileToGBbuf();
    private:
        FILE *m_file = NULL;
        char *m_buf = NULL;
        int m_bufSize = 0;
        int m_bytesUsed = 0;
        int m_count = 0;
    };
    
    H264File::H264File(int bufSize)
        : m_bufSize(bufSize)
    {
        m_buf = new char[m_bufSize];
    }
    
    H264File::~H264File()
    {
        delete m_buf;
    }
    
    bool H264File::open(const char *path)
    {
        m_file = fopen(path, "rb");
        if (m_file == NULL)
        {
            return false;
        }
    
        return true;
    }
    
    void H264File::Close()
    {
        if (m_file)
        {
            fclose(m_file);
            m_file = NULL;
            m_count = 0;
            m_bytesUsed = 0;
        }
    }
    
    /*
    int H264File::readfileToGBbuf() {
        fseek(m_file, 0, SEEK_SET);
        //fseek(m_file, 31, SEEK_SET);
        int bytesRead = (int)fread(gbuf, 1, GBUFF_MAX_SIZE, m_file);
        gbufDatasize = bytesRead;
        fclose(m_file);
        printf("readfileToGBbuf ----->\n");
        return 0;
    }*/
    
     int   pushOneFrame(char* inBuf, int inBufSize){
         if(gbufDatasize+inBufSize > 5*1024*1024) {
             LOGE("pushOneFrame out---- %d--->\n",gbufDatasize);
             return -1;
         }
          memcpy(gbuf+ gbufDatasize, inBuf, inBufSize);
          gbufDatasize += inBufSize;
          return 1;
     }
    
    int H264File::readFrameFromGbuf(char* inBuf, int inBufSize, bool* bEndOfFrame) {
        /*
        if (m_file == NULL)
        {
            return -1;
        }    
        */
        LOGE("readFrameFromGbuf %d",inBufSize);
        int tmpOneStepRead = ONE_READ_SIZE;
        if (gBytesRead >= gbufDatasize) gBytesRead = 0;
        if (gbufDatasize - gBytesRead < ONE_READ_SIZE)
            tmpOneStepRead = gbufDatasize - gBytesRead;
    
        memcpy(m_buf, gbuf+ gBytesRead, tmpOneStepRead);
        /*
        int bytesRead = (int)fread(m_buf, 1, m_bufSize, m_file);
        if (bytesRead == 0)
        {
            fseek(m_file, 0, SEEK_SET);
            m_count = 0;
            m_bytesUsed = 0;
            bytesRead = (int)fread(m_buf, 1, m_bufSize, m_file);
            if (bytesRead == 0)
            {
                this->Close();
                return -1;
            }
        }*/
        int bytesRead = tmpOneStepRead;
        bool bFindStart = false, bFindEnd = false;
    
        int i = 0, startCode = 3;
        *bEndOfFrame = false;
        for (i = 0; i < bytesRead - 5; i++)
        {
            if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 1)
            {
                startCode = 3;
            }
            else if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 0 && m_buf[i + 3] == 1)
            {
                startCode = 4;
            }
            else
            {
                continue;
            }
    
            if (((m_buf[i + startCode] & 0x1F) == 0x5 || (m_buf[i + startCode] & 0x1F) == 0x1) &&
                ((m_buf[i + startCode + 1] & 0x80) == 0x80))
            {
                bFindStart = true;
                i += 4;
                break;
            }
        }
    
        for (; i < bytesRead - 5; i++)
        {
            if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 1)
            {
                startCode = 3;
            }
            else if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 0 && m_buf[i + 3] == 1)
            {
                startCode = 4;
            }
            else
            {
                continue;
            }
    
            if (((m_buf[i + startCode] & 0x1F) == 0x7) || ((m_buf[i + startCode] & 0x1F) == 0x8)
                || ((m_buf[i + startCode] & 0x1F) == 0x6) || (((m_buf[i + startCode] & 0x1F) == 0x5
                    || (m_buf[i + startCode] & 0x1F) == 0x1) && ((m_buf[i + startCode + 1] & 0x80) == 0x80)))
            {
                bFindEnd = true;
                break;
            }
        }
    
        bool flag = false;
        if (bFindStart && !bFindEnd && m_count > 0)
        {
            flag = bFindEnd = true;
            i = bytesRead;
            *bEndOfFrame = true;
        }
    
        if (!bFindStart || !bFindEnd)
        {
            this->Close();
            return -1;
        }
    
        int size = (i <= inBufSize ? i : inBufSize);
        memcpy(inBuf, m_buf, size);
    
        if (!flag)
        {
            m_count += 1;
            m_bytesUsed += i;
        }
        else
        {
            m_count = 0;
            m_bytesUsed = 0;
        }
    
        //fseek(m_file, m_bytesUsed, SEEK_SET);
        gBytesRead = m_bytesUsed;
        return size;
    }
    
    
    
    int TestRtmpPublisher(xop::EventLoop *event_loop)
    {
        H264File h264_file;
        /*
        if (!h264_file.open(PUSH_FILE)) {
            LOGE("Open %s failed.\n", PUSH_FILE);
            return -1;
        }
        */
        /* push stream to local rtmp server */
        xop::MediaInfo media_info;
        auto publisher = xop::RtmpPublisher::Create(event_loop);
        publisher->SetChunkSize(60000);
    
        std::string status;
        if (publisher->OpenUrl(RTMP_URL, 3000, status) < 0) {
            LOGE("Open url %s failed, status: %s\n", RTMP_URL, status.c_str());
            return -1;
        }
    
        int buf_size = 500000;
        bool end_of_frame = false;
        bool has_sps_pps = false;
        uint8_t *frame_buf = new uint8_t[buf_size];
        //h264_file.readfileToGBbuf();
    
    
        while (publisher->IsConnected()) 
        {
            //int frameSize = h264_file.readFrame((char*)frame_buf, buf_size, &end_of_frame);
            int frameSize = h264_file.readFrameFromGbuf((char*)frame_buf, buf_size, &end_of_frame);
            if (frameSize > 0) {
                if (!has_sps_pps) {
                    if (frame_buf[3] == 0x67 || frame_buf[4] == 0x67) {
                        xop::Nal sps = xop::H264Parser::findNal(frame_buf, frameSize);
                        if (sps.first != nullptr && sps.second != nullptr && *sps.first == 0x67) {
                            media_info.sps_size = (uint32_t)(sps.second - sps.first + 1);
                            media_info.sps.reset(new uint8_t[media_info.sps_size], std::default_delete<uint8_t[]>());
                            memcpy(media_info.sps.get(), sps.first, media_info.sps_size);
    
                            xop::Nal pps = xop::H264Parser::findNal(sps.second, frameSize - (int)(sps.second - frame_buf));
                            if (pps.first != nullptr && pps.second != nullptr && *pps.first == 0x68) {
                                media_info.pps_size = (uint32_t)(pps.second - pps.first + 1);
                                media_info.pps.reset(new uint8_t[media_info.pps_size], std::default_delete<uint8_t[]>());
                                memcpy(media_info.pps.get(), pps.first, media_info.pps_size);
    
                                has_sps_pps = true;
                                publisher->SetMediaInfo(media_info); /* set sps pps */                            
                                LOGE("Start rtmp pusher, rtmp url: %s , http-flv url: %s \n\n", RTMP_URL, HTTP_URL);
                            }
                        }
                    }
                }
                
                if (has_sps_pps) {
                    publisher->PushVideoFrame(frame_buf, frameSize); /* send h.264 frame */
                }
            }
    
            std::this_thread::sleep_for(std::chrono::milliseconds(40));
        }
        
        delete frame_buf;
        return 0;
    }
    
    
    
    /*
    
    int H264File::readFrame(char *inBuf, int inBufSize, bool *bEndOfFrame)
    {
        printf("readFrame-------------------------->\n");
        if (m_file == NULL)
        {
            return -1;
        }
    
        int bytesRead = (int)fread(m_buf, 1, m_bufSize, m_file);
        if (bytesRead == 0)
        {
            fseek(m_file, 0, SEEK_SET);
            m_count = 0;
            m_bytesUsed = 0;
            bytesRead = (int)fread(m_buf, 1, m_bufSize, m_file);
            if (bytesRead == 0)
            {
                this->Close();
                return -1;
            }
        }
    
        bool bFindStart = false, bFindEnd = false;
    
        int i = 0, startCode = 3;
        *bEndOfFrame = false;
        for (i = 0; i < bytesRead - 5; i++)
        {
            if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 1)
            {
                startCode = 3;
            }
            else if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 0 && m_buf[i + 3] == 1)
            {
                startCode = 4;
            }
            else
            {
                continue;
            }
    
            if (((m_buf[i + startCode] & 0x1F) == 0x5 || (m_buf[i + startCode] & 0x1F) == 0x1) &&
                ((m_buf[i + startCode + 1] & 0x80) == 0x80))
            {
                bFindStart = true;
                i += 4;
                break;
            }
        }
    
        for (; i < bytesRead - 5; i++)
        {
            if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 1)
            {
                startCode = 3;
            }
            else if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 0 && m_buf[i + 3] == 1)
            {
                startCode = 4;
            }
            else
            {
                continue;
            }
    
            if (((m_buf[i + startCode] & 0x1F) == 0x7) || ((m_buf[i + startCode] & 0x1F) == 0x8)
                || ((m_buf[i + startCode] & 0x1F) == 0x6) || (((m_buf[i + startCode] & 0x1F) == 0x5
                    || (m_buf[i + startCode] & 0x1F) == 0x1) && ((m_buf[i + startCode + 1] & 0x80) == 0x80)))
            {
                bFindEnd = true;
                break;
            }
        }
    
        bool flag = false;
        if (bFindStart && !bFindEnd && m_count > 0)
        {
            flag = bFindEnd = true;
            i = bytesRead;
            *bEndOfFrame = true;
        }
    
        if (!bFindStart || !bFindEnd)
        {
            this->Close();
            return -1;
        }
    
        int size = (i <= inBufSize ? i : inBufSize);
        memcpy(inBuf, m_buf, size);
    
        if (!flag)
        {
            m_count += 1;
            m_bytesUsed += i;
        }
        else
        {
            m_count = 0;
            m_bytesUsed = 0;
        }
    
        fseek(m_file, m_bytesUsed, SEEK_SET);
        return size;
    }
    
    
    */

    1222 问题

    #ifndef _CRT_SECURE_NO_WARNINGS
    #define _CRT_SECURE_NO_WARNINGS
    #endif
    #include <android/log.h>
    #include "xop/RtmpServer.h"
    #include "xop/HttpFlvServer.h"
    #include "xop/RtmpPublisher.h"
    #include "xop/RtmpClient.h"
    #include "xop/HttpFlvServer.h"
    #include "xop/H264Parser.h"
    #include "net/EventLoop.h"
    #include <errno.h>
    
    #include "CGBlockRingBuffer.h"
    
    
    
    
    #define TEST_RTMP_PUSHER  1
    //#define TEST_RTMP_CLIENT  0
    //#define TEST_MULTI_THREAD 0
    #define RTMP_URL    "rtmp://127.0.0.1:1935/live/01"
    //#define RTMP_URL    "rtmp://192.168.5.100:1935/live/01"
    #define PUSH_FILE   "./test.h264"
    //#define PUSH_FILE   "./mcodec1214.h264"
    //#define PUSH_FILE   "./oneFrame.h264"
    
    //#define HTTP_URL    "http://127.0.0.1:8080/live/01.flv"
    
    //int TestRtmpPublisher(xop::EventLoop *event_loop);
    void TestMyRtmpPublisher();
    
    xop::EventLoop* g_event_loop = NULL;
    
    
    CGBlockRingBuffer* pRingBuffer =NULL;
    
    #define INIT_BUFFER_SIZE 10*1024*1024
    
    void TestMyWriteData();
    
    char * sdPath = "data/data/com.example.testrtsp/1222.h264";
    //--
    
    unsigned char fileBuf[2*1024*1024];
    void WriteGbufToFile(){
        FILE *m_file = NULL;
        m_file = fopen(sdPath, "wb");
        if (m_file == NULL)
        {
            LOGE("Open %s error %d!",sdPath,errno);
            return ;
        }    
        int size = pRingBuffer->Read(fileBuf,pRingBuffer->getCanRead());
        int ret1 = fwrite(fileBuf,size,1,m_file);
        LOGE("ret1 %d --->!",ret1);
          fclose(m_file);
        return;
    
    }
    //--
    int rtmpMain()
    {
        //-----
        if(NULL == pRingBuffer){
            pRingBuffer = new CGBlockRingBuffer();
            pRingBuffer->Init(INIT_BUFFER_SIZE);
        }
      
         
        LOGE("rtmpMain  %d ",__LINE__);
    
        // WriteGbufToFile();
        // return -1;
    
    
        //-----
    
        int count = 1; 
        /*
    #if TEST_MULTI_THREAD
        count = std::thread::hardware_concurrency();
    #endif
    */
        xop::EventLoop event_loop(count);
    
        /* rtmp server example */
        auto rtmp_server = xop::RtmpServer::Create(&event_loop);
        rtmp_server->SetChunkSize(60000);
        //rtmp_server->SetGopCache(); /* enable gop cache */
        rtmp_server->SetEventCallback([](std::string type, std::string stream_path) {
            LOGE("[Event] %s, stream path: %s\n\n", type.c_str(), stream_path.c_str());
        });
        if (!rtmp_server->Start("0.0.0.0", 1935)) {
            LOGE("RTMP Server listen on 1935 failed.\n");
        }
    
        g_event_loop = &event_loop;
    
        
    //#if TEST_RTMP_PUSHER
        // rtmp pusher example 
        std::thread t([&event_loop] () {
            //TestRtmpPublisher(&event_loop);
            TestMyRtmpPublisher();
        });
        t.detach();
    
    //#endif
    /*
        std::thread t1([&event_loop]() {
            //TestRtmpPublisher(&event_loop);
            TestMyWriteData();
            });
        t1.detach();
    
    */
    
        /*
    #if    TEST_RTMP_CLIENT
        auto rtmp_client = xop::RtmpClient::Create(&event_loop);
        rtmp_client->SetFrameCB([](uint8_t* payload, uint32_t length, uint8_t codecId, uint32_t timestamp) {
            printf("recv frame, type:%u, size:%u,\n", codecId, length);
        });
    
        std::string status;
        if (rtmp_client->OpenUrl(RTMP_URL, 3000, status) != 0) {
            printf("Open url %s failed, status: %s\n", RTMP_URL, status.c_str());
        }
    #endif
    */
        while (1) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        
        rtmp_server->Stop();
        //http_flv_server.Stop();
        return 0;
    }
    
    
    class H264File
    {
    public:
        H264File(int bufSize = 5000000);
        ~H264File();
    
        bool open(const char *path);
        void Close();
    
        bool isOpened() const
        {
            return (m_file != NULL);
        }
    
        //int readFrame(char *inBuf, int inBufSize, bool *bEndOfFrame);
        int readFrameFromGbuf(char* inBuf, int inBufSize, bool* bEndOfFrame);
    
       // int readfileToGBbuf();
    private:
        FILE *m_file = NULL;
        char *m_buf = NULL;
        int m_bufSize = 0;
        int m_bytesUsed = 0;
        int m_count = 0;
    };
    
    H264File::H264File(int bufSize)
        : m_bufSize(bufSize)
    {
        m_buf = new char[m_bufSize];
    }
    
    H264File::~H264File()
    {
        delete m_buf;
    }
    
    bool H264File::open(const char *path)
    {
        m_file = fopen(path, "rb");
        if (m_file == NULL)
        {
            return false;
        }
    
        return true;
    }
    
    void H264File::Close()
    {
        if (m_file)
        {
            fclose(m_file);
            m_file = NULL;
            m_count = 0;
            m_bytesUsed = 0;
        }
    }
    
    
    
    
    
    int   pushOneFrame(char* inBuf, int inBufSize) {
        if(NULL == pRingBuffer){
                pRingBuffer = new CGBlockRingBuffer();
                pRingBuffer->Init(INIT_BUFFER_SIZE);
                LOGE("init -------------->");
        }
    
    
        pRingBuffer->Write((unsigned char*)inBuf, inBufSize);
        return 1;
    }
    
    
    
    /*
    #define   GBUFF_MAX_SIZE 10*1024 * 1024
    char gbuf[GBUFF_MAX_SIZE] = { 0 };
    int  gbufDatasize = 0;
    int  gBytesRead = 0;
    
    //  ---- 模拟流
    void TestMyWriteData() {
        while (1) {
            if (gbufDatasize <= 0) continue;
            int tmpOneStepRead = (5*1024);
            if (gBytesRead >= gbufDatasize) 
                gBytesRead = 0;
            if (gbufDatasize - gBytesRead < (5 * 1024))
                tmpOneStepRead = gbufDatasize - gBytesRead;
            pRingBuffer->Write((unsigned char*)(gbuf + gBytesRead), tmpOneStepRead);
            gBytesRead += tmpOneStepRead;
            //printf("write %d", tmpOneStepRead);
            std::this_thread::sleep_for(std::chrono::milliseconds(30));
        }
    }
    
    int H264File::readfileToGBbuf() {
        fseek(m_file, 0, SEEK_SET);
        //fseek(m_file, 31, SEEK_SET);
        int bytesRead = (int)fread(gbuf, 1, GBUFF_MAX_SIZE, m_file);
        gbufDatasize = bytesRead;
        fclose(m_file);
        return 0;
    }
    //---
    */
    
    int H264File::readFrameFromGbuf(char* inBuf, int inBufSize, bool* bEndOfFrame) {
    
    
        int tmpOneStepRead = pRingBuffer->getNotRead((unsigned  char*)m_buf, inBufSize);
        int bytesRead = tmpOneStepRead;
        bool bFindStart = false, bFindEnd = false;
    
        int i = 0, startCode = 3;
        *bEndOfFrame = false;
        for (i = 0; i < bytesRead - 5; i++)
        {
            if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 1)
            {
                startCode = 3;
            }
            else if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 0 && m_buf[i + 3] == 1)
            {
                startCode = 4;
            }
            else
            {
                continue;
            }
    
            if (((m_buf[i + startCode] & 0x1F) == 0x5 || (m_buf[i + startCode] & 0x1F) == 0x1) &&
                ((m_buf[i + startCode + 1] & 0x80) == 0x80))
            {
                bFindStart = true;
                i += 4;
                break;
            }
        }
    
        for (; i < bytesRead - 5; i++)
        {
            if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 1)
            {
                startCode = 3;
            }
            else if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 0 && m_buf[i + 3] == 1)
            {
                startCode = 4;
            }
            else
            {
                continue;
            }
    
            if (((m_buf[i + startCode] & 0x1F) == 0x7) || ((m_buf[i + startCode] & 0x1F) == 0x8)
                || ((m_buf[i + startCode] & 0x1F) == 0x6) || (((m_buf[i + startCode] & 0x1F) == 0x5
                    || (m_buf[i + startCode] & 0x1F) == 0x1) && ((m_buf[i + startCode + 1] & 0x80) == 0x80)))
            {
                bFindEnd = true;
                break;
            }
        }
    
        bool flag = false;
        if (bFindStart && !bFindEnd && m_count > 0)
        {
            flag = bFindEnd = true;
            i = bytesRead;
            *bEndOfFrame = true;
            LOGE("! find\n");
        }
    
        if (!bFindStart || !bFindEnd)
        {
            LOGE("!not find\n");
            this->Close();
            return -1;
        }
    
        int size = (i <= inBufSize ? i : inBufSize);
    
        int ret = pRingBuffer->Read((unsigned char*)inBuf, size);
        if (ret != size) {
            LOGE("ret %d != size %d\n", ret, size);
        }
    
        if (!flag)
        {
            m_count += 1;
            m_bytesUsed += i;
        }
        else
        {
            m_count = 0;
            m_bytesUsed = 0; //?????
        }
    
        //fseek(m_file, m_bytesUsed, SEEK_SET);
        //gBytesRead = m_bytesUsed;  //--- ��� 20211222 18:01
        return size;
    }
    /*
    int H264File::readFrame(char *inBuf, int inBufSize, bool *bEndOfFrame)
    {
        if (m_file == NULL)
        {
            return -1;
        }
    
        //if(0 == gi) fseek(m_file, 31, SEEK_SET);
    
        int bytesRead = (int)fread(m_buf, 1, m_bufSize, m_file);
        if (bytesRead == 0)
        {
            //--
            printf("[%s %s] %s: %d\n", __DATE__, __TIME__,  __func__, __LINE__);
            //return -2;
            //--
            fseek(m_file, 0, SEEK_SET);
            //fseek(m_file, 31, SEEK_SET);
            m_count = 0;
            m_bytesUsed = 0;
            bytesRead = (int)fread(m_buf, 1, m_bufSize, m_file);
            if (bytesRead == 0)
            {
                this->Close();
                return -1;
            }
        }
    
        bool bFindStart = false, bFindEnd = false;
    
        int i = 0, startCode = 3;
        *bEndOfFrame = false;
        for (i = 0; i < bytesRead - 5; i++)
        {
            if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 1)
            {
                startCode = 3;
            }
            else if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 0 && m_buf[i + 3] == 1)
            {
                startCode = 4;
            }
            else
            {
                continue;
            }
    
            if (((m_buf[i + startCode] & 0x1F) == 0x5 || (m_buf[i + startCode] & 0x1F) == 0x1) &&
                ((m_buf[i + startCode + 1] & 0x80) == 0x80))
            {
                bFindStart = true;
                i += 4;
                break;
            }
        }
    
        for (; i < bytesRead - 5; i++)
        {
            if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 1)
            {
                startCode = 3;
            }
            else if (m_buf[i] == 0 && m_buf[i + 1] == 0 && m_buf[i + 2] == 0 && m_buf[i + 3] == 1)
            {
                startCode = 4;
            }
            else
            {
                continue;
            }
    
            if (((m_buf[i + startCode] & 0x1F) == 0x7) || ((m_buf[i + startCode] & 0x1F) == 0x8)
                || ((m_buf[i + startCode] & 0x1F) == 0x6) || (((m_buf[i + startCode] & 0x1F) == 0x5
                    || (m_buf[i + startCode] & 0x1F) == 0x1) && ((m_buf[i + startCode + 1] & 0x80) == 0x80)))
            {
                bFindEnd = true;
                break;
            }
        }
    
        bool flag = false;
        if (bFindStart && !bFindEnd && m_count > 0)
        {
            flag = bFindEnd = true;
            i = bytesRead;
            *bEndOfFrame = true;
        }
    
        if (!bFindStart || !bFindEnd)
        {
            this->Close();
            return -1;
        }
    
        int size = (i <= inBufSize ? i : inBufSize);
        memcpy(inBuf, m_buf, size);
    
        if (!flag)
        {
            m_count += 1;
            m_bytesUsed += i;
        }
        else
        {
            m_count = 0;
            m_bytesUsed = 0;
        }
    
        fseek(m_file, m_bytesUsed, SEEK_SET);
        return size;
    }
    */
    //
    
    std::shared_ptr<xop::RtmpPublisher> publisher;
    xop::MediaInfo media_info;
    bool has_sps_pps = false;
    int InitPub() {
        if (NULL == g_event_loop) return -1;
        printf("[%s %s] %s: %s: %d\n", __DATE__, __TIME__, __FILE__, __func__, __LINE__);
       /* H264File h264_file;
        
        if (!h264_file.open(PUSH_FILE)) {
            printf("Open %s failed.\n", PUSH_FILE);
            return -1;
        }*/
    
        /* push stream to local rtmp server */
        xop::MediaInfo media_info;
        //auto publisher 
        publisher    = xop::RtmpPublisher::Create(g_event_loop);
        publisher->SetChunkSize(60000);
    
        std::string status;
        if (publisher->OpenUrl(RTMP_URL, 3000, status) < 0) {
            printf("Open url %s failed, status: %s\n", RTMP_URL, status.c_str());
            return -1;
        }
    
        return 0;
    }
    
    void  procFrame(char* inBuf, int inBufSize, bool* bEndOfFrame) {
    
        //int buf_size = 500000;
        //uint8_t* frame_buf = new uint8_t[buf_size];
    
        LOGE("procframe %d",inBufSize);
        uint8_t* frame_buf = (uint8_t*)inBuf;
    
        bool end_of_frame = *bEndOfFrame;
        
        if (!publisher->IsConnected()) {
            LOGE("return\n");
            return;
        }
        //printf("[%s %s] %s: %s: %d\n", __DATE__, __TIME__, __FILE__, __func__, __LINE__);
        int frameSize = inBufSize;//h264_file.readFrame((char*)frame_buf, buf_size, &end_of_frame);
        if (frameSize > 0) {
            if (!has_sps_pps) {
                if (frame_buf[3] == 0x67 || frame_buf[4] == 0x67) {
                    xop::Nal sps = xop::H264Parser::findNal(frame_buf, frameSize);
                    if (sps.first != nullptr && sps.second != nullptr && *sps.first == 0x67) {
                        media_info.sps_size = (uint32_t)(sps.second - sps.first + 1);
                        media_info.sps.reset(new uint8_t[media_info.sps_size], std::default_delete<uint8_t[]>());
                        memcpy(media_info.sps.get(), sps.first, media_info.sps_size);
    
                        xop::Nal pps = xop::H264Parser::findNal(sps.second, frameSize - (int)(sps.second - frame_buf));
                        if (pps.first != nullptr && pps.second != nullptr && *pps.first == 0x68) {
                            media_info.pps_size = (uint32_t)(pps.second - pps.first + 1);
                            media_info.pps.reset(new uint8_t[media_info.pps_size], std::default_delete<uint8_t[]>());
                            memcpy(media_info.pps.get(), pps.first, media_info.pps_size);
    
                            has_sps_pps = true;
                            publisher->SetMediaInfo(media_info); /* set sps pps */
                            //printf("Start rtmp pusher, rtmp url: %s , http-flv url: %s \n\n", RTMP_URL, HTTP_URL);
                            printf("Start rtmp pusher, rtmp url: %s  \n\n", RTMP_URL);
                        }
                    }
                }
            }
    
            if (has_sps_pps) {
                LOGE("PushVideoFrame %d",frameSize);
                publisher->PushVideoFrame(frame_buf, frameSize); /* send h.264 frame */
            }
        }
        else {
            printf("[%s %s] %s: %s: %d\n", __DATE__, __TIME__, __FILE__, __func__, __LINE__);
            printf("get end!");
            //break;
        }
    
        std::this_thread::sleep_for(std::chrono::milliseconds(40));
    }
    
    
    void TestMyRtmpPublisher() {
        int ret = InitPub();
        if (ret < 0) return;    
        int buf_size = 100000;
        bool end_of_frame = false;
        bool has_sps_pps = false;
        uint8_t* frame_buf = new uint8_t[buf_size];
        H264File h264_file;
        /*
        if (!h264_file.open(PUSH_FILE)) {
            printf("Open %s failed.\n", PUSH_FILE);
            return ;
        }
        h264_file.readfileToGBbuf();
    
        */
    
        
        while (1) {
            LOGE("[%s %s]  %s: %d\n", __DATE__, __TIME__, __func__, __LINE__);
            int frameSize = h264_file.readFrameFromGbuf((char*)frame_buf, buf_size, &end_of_frame);
            //int frameSize = h264_file.readOneFrameFile((char*)frame_buf, buf_size, &end_of_frame);
            
            procFrame((char*)frame_buf, frameSize, &end_of_frame);
    
        
        }
        
    }
    
    
    /*
    int TestRtmpPublisher(xop::EventLoop *event_loop)
    {
        printf("[%s %s] %s: %s: %d\n", __DATE__, __TIME__, __FILE__, __func__, __LINE__);
        H264File h264_file;
        
        if (!h264_file.open(PUSH_FILE)) {
            printf("Open %s failed.\n", PUSH_FILE);
            return -1;
        }
    
        // push stream to local rtmp server 
        xop::MediaInfo media_info;
        auto publisher = xop::RtmpPublisher::Create(event_loop);
        publisher->SetChunkSize(60000);
    
        std::string status;
        if (publisher->OpenUrl(RTMP_URL, 3000, status) < 0) {
            LOGE("Open url %s failed, status: %s\n", RTMP_URL, status.c_str());
            return -1;
        }
    
        int buf_size = 500000;
        bool end_of_frame = false;
        bool has_sps_pps = false;
        uint8_t *frame_buf = new uint8_t[buf_size];
    
        while (publisher->IsConnected()) 
        {
            printf("[%s %s] %s: %s: %d\n", __DATE__, __TIME__, __FILE__, __func__, __LINE__);
            int frameSize = h264_file.readFrame((char*)frame_buf, buf_size, &end_of_frame);
            if (frameSize > 0) {
                if (!has_sps_pps) {
                    if (frame_buf[3] == 0x67 || frame_buf[4] == 0x67) {
                        xop::Nal sps = xop::H264Parser::findNal(frame_buf, frameSize);
                        if (sps.first != nullptr && sps.second != nullptr && *sps.first == 0x67) {
                            media_info.sps_size = (uint32_t)(sps.second - sps.first + 1);
                            media_info.sps.reset(new uint8_t[media_info.sps_size], std::default_delete<uint8_t[]>());
                            memcpy(media_info.sps.get(), sps.first, media_info.sps_size);
    
                            xop::Nal pps = xop::H264Parser::findNal(sps.second, frameSize - (int)(sps.second - frame_buf));
                            if (pps.first != nullptr && pps.second != nullptr && *pps.first == 0x68) {
                                media_info.pps_size = (uint32_t)(pps.second - pps.first + 1);
                                media_info.pps.reset(new uint8_t[media_info.pps_size], std::default_delete<uint8_t[]>());
                                memcpy(media_info.pps.get(), pps.first, media_info.pps_size);
    
                                has_sps_pps = true;
                                publisher->SetMediaInfo(media_info); // set sps pps                           
                                //printf("Start rtmp pusher, rtmp url: %s , http-flv url: %s \n\n", RTMP_URL, HTTP_URL);
                                printf("Start rtmp pusher, rtmp url: %s  \n\n", RTMP_URL);
                            }
                        }
                    }
                }
                
                if (has_sps_pps) {
                    publisher->PushVideoFrame(frame_buf, frameSize); // send h.264 frame 
                }
            }
            else {
                printf("[%s %s] %s: %s: %d\n", __DATE__, __TIME__, __FILE__, __func__, __LINE__);
                printf("push end!");
                //break;
            }
    
            std::this_thread::sleep_for(std::chrono::milliseconds(40));
        }
        
        delete frame_buf;
        return 0;
    }
    */
    #pragma once
    #include <iostream>
    #include <string>
    #include <thread>
    #include <mutex>
    #include <unistd.h>
    using namespace std;
    #define TAG "zj"
    
    #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
    #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
    #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
    #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
    
    //过于简单了
    // readindex he writeindex
    
    class CGBlockRingBuffer
    {
    public:
        CGBlockRingBuffer()
            :buffer(nullptr)
            , bufferSize(0)
            , writeIndex(0)
            , readIndex(0)
            , bytesCanRead(0)
        {
    
        }
    
        void Init(int buffSize = 1024*1024)
        {
            LOGE("block init--%d-->", buffSize);
            buffer = new uint8_t[buffSize];
            if (!buffer) return;
            this->bufferSize = buffSize;
        }
    
        void Write(uint8_t* src, int size)
        {
            LOGE("want write %d ,%d %d, bsize %d \n",size,readIndex,writeIndex, bufferSize);
            if (!src || size == 0) return;
            std::lock_guard<std::mutex> lk(lock);
            if (size >= bufferSize - bytesCanRead) {
                std::this_thread::sleep_for(std::chrono::microseconds(50));
                LOGE("buffer now is full  %d,%d,%d!", size, bufferSize, bytesCanRead);
                return;
            }
    
            int bytesCanWrite = size < bufferSize - bytesCanRead ? size : (bufferSize - bytesCanRead);
    
            //if(bytesCanWrite)  如果可写的小于--- 则丢弃--
            //这个
            if (bytesCanWrite <= bufferSize - writeIndex)
            {
                memcpy(buffer + writeIndex, src, bytesCanWrite);
                writeIndex += bytesCanWrite;
                if (writeIndex == bufferSize)
                {
                    writeIndex = 0;
                }
            }
            else
            {
                int room = bufferSize - writeIndex;
                memcpy(buffer + writeIndex, src, room);
                int left = bytesCanWrite - room;
                memcpy(buffer, src + room, left);
                writeIndex = left;
            }
            bytesCanRead += bytesCanWrite;
            LOGE("real write %d \n", bytesCanWrite);
        }
        //先这样--to thi
        // 如果没有找到的话sleep一会儿---,to thi
        //1、先直接换ring 2、加这个优化 
        int getNotRead(uint8_t* dst, int size) {
            LOGE("getNotRead %d\n", size);
            //printf("dst %d\n", dst);
     
            if (size > bytesCanRead /*- 1024 * 50*/) {
                std::this_thread::sleep_for(std::chrono::microseconds(50));
                LOGE("getNotRead Buffer isn't enough!---->");
                return 0;
            }
            std::lock_guard<std::mutex> lk(lock);
    
    
            int bytesRead = size < bytesCanRead ? size : bytesCanRead;
            if (bytesRead <= bufferSize - readIndex)
            {
                memcpy(dst, buffer + readIndex, bytesRead);
                //readIndex += bytesRead;
                //if (readIndex == bufferSize) readIndex = 0;
            }
            else
            {
                int bytesHead = bufferSize - readIndex;
                memcpy(dst, buffer + readIndex, bytesHead);
                int bytesTail = bytesRead - bytesHead;
                memcpy(dst + bytesHead, buffer, bytesTail);
                //readIndex = bytesTail;
            }
            //bytesCanRead -= bytesRead;
            return bytesRead;
        }
    
        int Read(uint8_t* dst, int size)
        {
            if (5120 == size) {
            
                int i = 0;
                i++;
            }
    
           std::this_thread::sleep_for(std::chrono::microseconds(50));
            //read小于则等待
            //就看这两个的--
            LOGE("want Read %d ,%d %d \n", size, readIndex, writeIndex);
            if (!dst || size == 0) return 0;
            std::lock_guard<std::mutex> lk(lock);
            //必须50k缓冲
            if (size > bytesCanRead/*-1024*10*/) {
                std::this_thread::sleep_for(std::chrono::microseconds(50));
                LOGE("Buffer is empty!---->");
                return 0;
            }
            int bytesRead = size < bytesCanRead ? size : bytesCanRead;
            if (bytesRead <= bufferSize - readIndex)
            {
                memcpy(dst, buffer + readIndex, bytesRead);
                readIndex += bytesRead;
                if (readIndex == bufferSize) readIndex = 0;
            }
            else
            {
                int bytesHead = bufferSize - readIndex;
                memcpy(dst, buffer + readIndex, bytesHead);
                int bytesTail = bytesRead - bytesHead;
                memcpy(dst + bytesHead, buffer, bytesTail);
                readIndex = bytesTail;
            }
            bytesCanRead -= bytesRead;
            LOGE("real Read %d\n", bytesRead);
            return bytesRead;
        }
    
        int getCanRead(){
            return bytesCanRead;
        }
    private:
        uint8_t* buffer;
        int bufferSize;
        int readIndex;
        int  writeIndex;
        int bytesCanRead;
        std::mutex lock;
    };
  • 相关阅读:
    Seven Puzzle Aizu
    Cheese
    Curling 2.0
    Ball
    Property Distribution
    Red and Black
    Lake Counting
    Ants
    剑桥雅思写作高分范文ESSAY20
    剑桥雅思写作高分范文ESSAY19
  • 原文地址:https://www.cnblogs.com/cnchengv/p/15721776.html
Copyright © 2020-2023  润新知