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;
};
原文地址:https://www.cnblogs.com/cnchengv/p/15721776.html