转化的
rtspjni的后要弄上
1218 ok
#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; }
做成jni易于调用的
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]; uint8_t* frame_buf = (uint8_t*)inBuf; bool end_of_frame = *bEndOfFrame; if (!publisher->IsConnected()) { printf("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) { 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)); } void TestMyRtmpPublisher() { int ret = InitPub(); if (ret < 0) return; int buf_size = 500000; 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 ; } while (1) { //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); procFrame((char*)frame_buf, frameSize, &end_of_frame); } }
#define GBUFF_SIZE 10*1024 * 1024 #define ONEREAD_MAXSIZE 1024*1024 char gbuf[GBUFF_SIZE] = { 0 }; int gbufDatasize = 0; int gBytesRead = 0; int H264File::readfileToGBbuf() { fseek(m_file, 0, SEEK_SET); //fseek(m_file, 31, SEEK_SET); int bytesRead = (int)fread(gbuf, 1, GBUFF_SIZE, m_file); gbufDatasize = bytesRead; fclose(m_file); return 0; } int H264File::readFrameFromGbuf(char* inBuf, int inBufSize, bool* bEndOfFrame) { if (gBytesRead >= gbufDatasize) { gBytesRead = 0; } int oneReadSize = ONEREAD_MAXSIZE; if (gbufDatasize - gBytesRead - ONEREAD_MAXSIZE < 0&& gbufDatasize - gBytesRead - ONEREAD_MAXSIZE>0) oneReadSize = gbufDatasize - gBytesRead; //int bytesRead = (int)fread(m_buf, 1, m_bufSize, m_file); memcpy(m_buf,gbuf, oneReadSize); int bytesRead = oneReadSize; /* if (bytesRead == 0) { //-- printf("[%s %s] %s: %s: %d\n", __DATE__, __TIME__, __FILE__, __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; gBytesRead += i; } else { m_count = 0; m_bytesUsed = 0; gBytesRead = 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]; uint8_t* frame_buf = (uint8_t*)inBuf; bool end_of_frame = *bEndOfFrame; if (!publisher->IsConnected()) { printf("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) { 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)); } void TestMyRtmpPublisher() { int ret = InitPub(); if (ret < 0) return; int buf_size = 500000; 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) { //printf("[%s %s] %s: %s: %d\n", __DATE__, __TIME__, __FILE__, __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); gi++ ; } }