diff --git a/.gitignore b/.gitignore index 0336669..78a39a1 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_32_bit-Release/ client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MSVC2017_64bit-Debug/ client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_64_bit-Debug/ client/qt_gl_render/yuvgl/third/libs/ +client/qt_gl_render/yuvgl/third/ diff --git a/client/qt_gl_render/yuvgl/mainwindow.cpp b/client/qt_gl_render/yuvgl/mainwindow.cpp index ab5c092..c9be8f6 100644 --- a/client/qt_gl_render/yuvgl/mainwindow.cpp +++ b/client/qt_gl_render/yuvgl/mainwindow.cpp @@ -24,8 +24,8 @@ void MainWindow::on_pushButton_clicked(){ mPlayerWidget = new CPlayWidget(nullptr); } if(!m_bCameraOpen){ - ui->widget->SetDataType(CPlayWidget::IMG_TYPE::TYPE_RGB32); - ui->widget->SetImgSize(640,480); + mPlayerWidget->SetDataType(CPlayWidget::IMG_TYPE::TYPE_RGB32); + mPlayerWidget->SetImgSize(640,480); qDebug()<comboBox->currentText().size()<comboBox->currentText(); wchar_t *opencamera = new wchar_t[ui->comboBox->currentText().size()]; @@ -34,11 +34,11 @@ void MainWindow::on_pushButton_clicked(){ if(nullptr == mCamera){ this->mCamera = new Camera(ss); } - this->mCamera->SetObserver(ui->widget); + this->mCamera->SetObserver(mPlayerWidget); qDebug()<comboBox->currentText(); ui->pushButton->setText("关闭摄像头"); m_bCameraOpen = true; - ui->widget->show(); + mPlayerWidget->show(); }else{ m_bCameraOpen = false; ui->pushButton->setText("打开摄像头"); diff --git a/client/qt_gl_render/yuvgl/media/CameraCapture.cpp b/client/qt_gl_render/yuvgl/media/CameraCapture.cpp index c18f2fd..1272247 100644 --- a/client/qt_gl_render/yuvgl/media/CameraCapture.cpp +++ b/client/qt_gl_render/yuvgl/media/CameraCapture.cpp @@ -403,7 +403,6 @@ HRESULT STDMETHODCALLTYPE Camera::SampleGrabberCallback::SampleCB(double Time, I HRESULT STDMETHODCALLTYPE Camera::SampleGrabberCallback::BufferCB(double Time, BYTE * pBuffer, long BufferLen) { -#define DEBUG_CAMERA #ifdef DEBUG_CAMERA static FILE *p = fopen("camera_test.yuv","wb+"); fwrite(pBuffer,BufferLen,1,p); diff --git a/client/qt_gl_render/yuvgl/media/RtmpPuller.cpp b/client/qt_gl_render/yuvgl/media/RtmpPuller.cpp new file mode 100644 index 0000000..356712a --- /dev/null +++ b/client/qt_gl_render/yuvgl/media/RtmpPuller.cpp @@ -0,0 +1,132 @@ +#include "RtmpPuller.h" + + +RtmpPuller::RtmpPuller() + :mFrameIndex(0), mAudioIndex(-1),mVideoIndex(-1) + , mAudioStream(nullptr),mVideoStream(nullptr) +{ + av_register_all(); + //Network + avformat_network_init(); + //Input +} + +int RtmpPuller::ConnectServer(const char *p) +{ + int ret = 0; + if ((ret = avformat_open_input(&mIfmtCtx, p, 0, 0)) < 0) { + printf("Could not open input file."); + return -1; + } + if ((ret = avformat_find_stream_info(mIfmtCtx, 0)) < 0) { + printf("Failed to retrieve input stream information"); + return -1; + } + for (int i = 0; i < mIfmtCtx->nb_streams; i++) { + if (mIfmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + mVideoIndex = i; + } + if (mIfmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { + mAudioIndex = i; + } + } + if(mAudioIndex > -1) + this->mAudioStream = mIfmtCtx->streams[mAudioIndex]; + if(mVideoIndex > -1) + this->mVideoStream = mIfmtCtx->streams[mVideoIndex]; + av_dump_format(mIfmtCtx, 0, p, 0); + mH264bsfc = av_bitstream_filter_init("h264_mp4toannexb"); + mStatus = RUNNING; + if((mAudioIndex == -1 ) &&(mVideoIndex == -1)) + mStatus = NOSOURCE; + return 0; +} + +int ThreadPull(RtmpPuller*p) { + while (p->Status() == RtmpPuller::CAP_STATUS::RUNNING) { + p->PullData(); + } + return 0; +} + +int RtmpPuller::StartPull() +{ + this->mThread = new std::thread(ThreadPull, this); + this->mThread->get_id(); + mStatus = RUNNING; + return 0; +} + +int RtmpPuller::PullData() +{ + static int drop = 0; + AVStream *in_stream; + //Get an AVPacket + int ret = av_read_frame(mIfmtCtx, &pkt); + if (ret < 0) + return -1; + in_stream = mIfmtCtx->streams[pkt.stream_index]; + /* copy packet */ + //Convert PTS/DTS + pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, in_stream->time_base, + (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); + pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, in_stream->time_base, + (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); + pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, in_stream->time_base); + pkt.pos = -1; + //Print to Screen + if (drop < 100) { + drop++; + goto end; + } + if (pkt.stream_index == mVideoIndex) { + printf("Receive %8d video frames from input URL\n", mFrameIndex); + mFrameIndex++; + av_bitstream_filter_filter(mH264bsfc, in_stream->codec, NULL, + &pkt.data, &pkt.size, pkt.data, pkt.size, 0); + if (mObserver.size() > 0) { + for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) { + RtmpPullObserver *p = (RtmpPullObserver *)*itr; + if (p->mObserverType == RtmpPullObserver::Observer_Video) { + p->OnRtmpFrame(pkt.data, pkt.size); + } + } + } + } + if (pkt.stream_index == mAudioIndex) { + if (mObserver.size() > 0) { + for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) { + RtmpPullObserver *p = (RtmpPullObserver *)*itr; + if (p->mObserverType == RtmpPullObserver::Observer_Audio) { + p->OnRtmpFrame(pkt.data, pkt.size); + } + } + } + } +end: + //printf("%02x %02x %02x %02x %02x\r\n", pkt.data[0], pkt.data[1], pkt.data[2], pkt.data[3], pkt.data[4]); + av_free_packet(&pkt); +} + +int RtmpPuller::SetObserver(RtmpPullObserver *p) +{ + if (nullptr == p) + return -1; + mMux.lock(); + for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) { + if (p == *itr) return 0; + } + this->mObserver.push_back(p); + mMux.unlock(); + return 0; +} + +RtmpPuller::CAP_STATUS RtmpPuller::Status() +{ + return this->mStatus; +} + +AVStream * RtmpPuller::AudioStream() +{ + return this->mAudioStream; +} diff --git a/client/qt_gl_render/yuvgl/media/RtmpPuller2.cpp b/client/qt_gl_render/yuvgl/media/RtmpPuller2.cpp new file mode 100644 index 0000000..b97b573 --- /dev/null +++ b/client/qt_gl_render/yuvgl/media/RtmpPuller2.cpp @@ -0,0 +1,251 @@ +#include "RtmpPuller2.h" +#include "Debuger.h" +RtmpPuller2::RtmpPuller2() +{ + + mAccBuffer = new uint8_t[3000]; +} +RtmpPuller2::~RtmpPuller2() +{ +} + +int ThreadPull(RtmpPuller2*p) { + while (p->Status() == RtmpPuller2::CAP_STATUS::RUNNING) { + p->PullData(); + Sleep(10); + } + return 0; +} +// ر +int RtmpPuller2::StopPull() +{ + mStatus = STOP; + this->mThread->join(); + RTMP_Close(mRtmp); + RTMP_Free(mRtmp); + return 0; +} + +int RtmpPuller2::StartPull() +{ + if(this->mStatus == CONNECTED) { + mStatus = RUNNING; + this->mThread = new std::thread(ThreadPull, this); + this->mThread->get_id(); + } + else { + } + return 0; +} + +FILE *fp = nullptr; +int RtmpPuller2::PullData() +{ + RTMPPacket packet = { 0 }; + // Parse rtmp stream to h264 and aac + uint8_t nalu_header[4] = { 0x00, 0x00, 0x00, 0x01 }; + int ret = RTMP_ReadPacket(mRtmp, &packet); + if (ret < 0) + return ret; + + if (nullptr == fp) { + fp = fopen("src.aac", "wb"); + } + if (RTMPPacket_IsReady(&packet)) { + // Process packet, eg: set chunk size, set bw, ... + RTMP_ClientPacket(mRtmp, &packet); + if (packet.m_packetType == RTMP_PACKET_TYPE_VIDEO) { + bool keyframe = 0x17 == packet.m_body[0] ? true : false; + bool sequence = 0x00 == packet.m_body[1]; + printf("keyframe=%s, sequence=%s\n", keyframe ? "true" : "false", sequence ? "true" : "false"); + // SPS/PPS sequence + if (sequence) { + uint32_t offset = 10; + uint32_t sps_num = packet.m_body[offset++] & 0x1f; + for (int i = 0; i < sps_num; i++) { + uint8_t ch0 = packet.m_body[offset]; + uint8_t ch1 = packet.m_body[offset + 1]; + uint32_t sps_len = ((ch0 << 8) | ch1); + offset += 2; + packet.m_body[offset - 1] = 0x01; + packet.m_body[offset - 2] = 0x00; + packet.m_body[offset - 3] = 0x00; + packet.m_body[offset - 4] = 0x00; + + if (mObserver.size() > 0) { + for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) { + RtmpPullObserver *p = (RtmpPullObserver *)*itr; + if (p->mObserverType == RtmpPullObserver::Observer_Video) { + p->OnRtmpFrame(packet.m_body + offset - 4, sps_len + 4); + } + } + } + // Write sps data + //fwrite(nalu_header, sizeof(uint8_t), 4, _file_ptr); + //fwrite(packet.m_body + offset, sizeof(uint8_t), sps_len, _file_ptr); + offset += sps_len; + } + uint32_t pps_num = packet.m_body[offset++] & 0x1f; + for (int i = 0; i < pps_num; i++) { + uint8_t ch0 = packet.m_body[offset]; + uint8_t ch1 = packet.m_body[offset + 1]; + uint32_t pps_len = ((ch0 << 8) | ch1); + offset += 2; + packet.m_body[offset - 1] = 0x01; + packet.m_body[offset - 2] = 0x00; + packet.m_body[offset - 3] = 0x00; + packet.m_body[offset - 4] = 0x00; + if (mObserver.size() > 0) { + for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) { + RtmpPullObserver *p = (RtmpPullObserver *)*itr; + if (p->mObserverType == RtmpPullObserver::Observer_Video) { + p->OnRtmpFrame(packet.m_body + offset - 4, pps_len + 4); + } + } + } + // Write pps data + offset += pps_len; + } + } + // Nalu frames + else { + uint32_t offset = 5; + uint8_t ch0 = packet.m_body[offset]; + uint8_t ch1 = packet.m_body[offset + 1]; + uint8_t ch2 = packet.m_body[offset + 2]; + uint8_t ch3 = packet.m_body[offset + 3]; + uint32_t data_len = ((ch0 << 24) | (ch1 << 16) | (ch2 << 8) | ch3); + offset += 4; + packet.m_body[offset - 1] = 0x01; + packet.m_body[offset - 2] = 0x00; + packet.m_body[offset - 3] = 0x00; + packet.m_body[offset - 4] = 0x00; + + if (mObserver.size() > 0) { + for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) { + RtmpPullObserver *p = (RtmpPullObserver *)*itr; + if (p->mObserverType == RtmpPullObserver::Observer_Video) { + p->OnRtmpFrame(packet.m_body + offset - 4, data_len + 4); + } + } + } + // Write nalu data(already started with '0x00,0x00,0x00,0x01') + //fwrite(nalu_header, sizeof(uint8_t), 4, _file_ptr); + offset += data_len; + } + } + else if (packet.m_packetType == RTMP_PACKET_TYPE_AUDIO) { + bool sequence = 0x00 == packet.m_body[1]; + printf("sequence=%s\n", sequence ? "true" : "false"); + // AAC sequence + if (sequence) { + uint8_t format = (packet.m_body[0] & 0xf0) >> 4; + uint8_t samplerate = (packet.m_body[0] & 0x0c) >> 2; + uint8_t sampledepth = (packet.m_body[0] & 0x02) >> 1; + uint8_t type = packet.m_body[0] & 0x01; + // sequence = packet.m_body[1]; + // AAC(AudioSpecificConfig) + if (format == 10) { + ch0 = packet.m_body[2]; + ch1 = packet.m_body[3]; + config = ((ch0 << 8) | ch1); + object_type = (config & 0xF800) >> 11; + sample_frequency_index = (config & 0x0780) >> 7; + channels = (config & 0x78) >> 3; + frame_length_flag = (config & 0x04) >> 2; + depend_on_core_coder = (config & 0x02) >> 1; + extension_flag = config & 0x01; + } + // Speex(Fix data here, so no need to parse...) + else if (format == 11) { + // 16 KHz, mono, 16bit/sample + type = 0; + sampledepth = 1; + samplerate = 4; + } + } + // Audio frames + else { + // ADTS(7 bytes) + AAC data + uint32_t data_len = packet.m_nBodySize - 2 + 7; + uint8_t adts[7]; + adts[0] = 0xff; + adts[1] = 0xf1; + adts[2] = ((object_type - 1) << 6) | (sample_frequency_index << 2) + | (channels >> 2); + adts[3] = ((channels & 3) << 6) + (data_len >> 11); + adts[4] = (data_len & 0x7FF) >> 3; + adts[5] = ((data_len & 7) << 5) + 0x1F; + adts[6] = 0xfc; + // Write audio frames + fwrite(adts, sizeof(uint8_t), 7, fp); + fwrite(packet.m_body + 2, sizeof(uint8_t), packet.m_nBodySize - 2, fp); + fflush(fp); + memcpy(mAccBuffer, adts, 7); + memcpy(mAccBuffer + 7, packet.m_body + 2, packet.m_nBodySize - 2); + + if (mObserver.size() > 0) { + for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) { + RtmpPullObserver *p = (RtmpPullObserver *)*itr; + if (p->mObserverType == RtmpPullObserver::Observer_Audio) { + p->OnRtmpFrame(mAccBuffer, packet.m_nBodySize - 2 + 7); + } + } + } + } + } + RTMPPacket_Free(&packet); + } + return 0; +} + +int RtmpPuller2::SetObserver(RtmpPuller2::RtmpPullObserver *p) +{ + if (nullptr == p) + return -1; + mMux.lock(); + for (auto itr = this->mObserver.begin(); itr != mObserver.end(); itr++) { + if (p == *itr) return 0; + } + this->mObserver.push_back(p); + mMux.unlock(); + return 0; +} + +RtmpPuller2::CAP_STATUS RtmpPuller2::Status() +{ + return mStatus; +} + + +int RtmpPuller2::ConnectServer(string url) +{ + mRtmp = RTMP_Alloc(); + RTMP_Init(mRtmp); + if (RTMP_SetupURL(mRtmp, (char*)url.c_str()) == FALSE) + { + RTMP_Free(mRtmp); + mStatus = FAIL; + return -1; + } + /*ӷ*/ + if (RTMP_Connect(mRtmp, NULL) == FALSE) + { + RTMP_Free(mRtmp); + mStatus = FAIL; + return -1; + } + /**/ + if (RTMP_ConnectStream(mRtmp, 0) == FALSE) + { + RTMP_Close(mRtmp); + RTMP_Free(mRtmp); + mStatus = FAIL; + return -1; + } + mStatus = CONNECTED; + return 0; +} + + + diff --git a/client/qt_gl_render/yuvgl/media/RtmpPusher.cpp b/client/qt_gl_render/yuvgl/media/RtmpPusher.cpp new file mode 100644 index 0000000..db8bc56 --- /dev/null +++ b/client/qt_gl_render/yuvgl/media/RtmpPusher.cpp @@ -0,0 +1,570 @@ +#include "RtmpPusher.h" + +/** + * ʼwinsock + * + * @ɹ򷵻1 , ʧ򷵻Ӧ + */ +int InitSockets() +{ +#ifdef WIN32 + WORD version; + WSADATA wsaData; + version = MAKEWORD(1, 1); + return (WSAStartup(version, &wsaData) == 0); +#else + return TRUE; +#endif +} + +bool RtmpPusher::IfConnect() +{ + return mIfConnected; +} + +int RtmpPusher::RTMP264_Connect(const char* url) +{ + InitSockets(); + m_pRtmp = RTMP_Alloc(); + RTMP_Init(m_pRtmp); + /*URL*/ + if (RTMP_SetupURL(m_pRtmp, (char*)url) == FALSE) + { + RTMP_Free(m_pRtmp); + return -1; + } + /*ÿд,,ǰʹ,Ч*/ + RTMP_EnableWrite(m_pRtmp); + /*ӷ*/ + if (RTMP_Connect(m_pRtmp, NULL) == FALSE) + { + RTMP_Free(m_pRtmp); + return -1; + } + + /**/ + if (RTMP_ConnectStream(m_pRtmp, 0) == FALSE) + { + RTMP_Close(m_pRtmp); + RTMP_Free(m_pRtmp); + return -1; + } + + this->mUrl = string(url); + this->mIfConnected = true; + return 0; +} +/** + * ͷwinsock + * + * @ɹ򷵻0 , ʧ򷵻Ӧ + */ +inline void CleanupSockets() +{ +#ifdef WIN32 + WSACleanup(); +#endif +} + +void RtmpPusher::RTMP264_Close() +{ + mMux.lock(); + if (m_pRtmp) + { + RTMP_Close(m_pRtmp); + RTMP_Free(m_pRtmp); + m_pRtmp = NULL; + } + mMux.unlock(); + CleanupSockets(); +} +RTMPPacket* gPacket = nullptr; + +int RtmpPusher::SendPacket(unsigned int nPacketType, unsigned char * data, + unsigned int size, unsigned int nTimestamp) +{ + static bool once = true; + /*ڴͳʼ,lenΪ峤*/ + if(nullptr == gPacket) + gPacket = (RTMPPacket *)malloc(640*720*3 + size); + memset(gPacket, 0, RTMP_HEAD_SIZE); + /*ڴ*/ + + gPacket->m_body = (char *)gPacket + RTMP_HEAD_SIZE; + gPacket->m_nBodySize = size; + memcpy(gPacket->m_body, data, size); + + gPacket->m_hasAbsTimestamp = 0; + gPacket->m_packetType = nPacketType; /*˴ΪһƵ,һƵ*/ + gPacket->m_nInfoField2 = m_pRtmp->m_stream_id; + gPacket->m_nChannel = 0x04; + + + gPacket->m_headerType = RTMP_PACKET_SIZE_LARGE; + if (RTMP_PACKET_TYPE_AUDIO == nPacketType && size != 4) + { + gPacket->m_headerType = RTMP_PACKET_SIZE_MEDIUM; + } + + gPacket->m_nTimeStamp = nTimestamp; + /**/ + int nRet = 0; + if (RTMP_IsConnected(m_pRtmp)) + { + nRet = RTMP_SendPacket(m_pRtmp, gPacket, FALSE); /*TRUEΪŽͶ,FALSEDzŽͶ,ֱӷ*/ + } + else { + if (once) { + once = false; + std::cout<<"rtmp Ͽ at "<<__FILE__<<" line "<<__LINE__; + } + } + /*ͷڴ*/ + //free(gPacket); + return nRet; +} + +int RtmpPusher::SendVideoPacket(unsigned int nPacketType, + unsigned char * data, unsigned int size, unsigned int nTimestamp) +{ + + RTMPPacket* packet; + /*ڴͳʼ,lenΪ峤*/ + packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE + size); + memset(packet, 0, RTMP_HEAD_SIZE); + /*ڴ*/ + packet->m_body = (char *)packet + RTMP_HEAD_SIZE; + packet->m_nBodySize = size; + memcpy(packet->m_body, data, size); + packet->m_hasAbsTimestamp = 0; + packet->m_packetType = nPacketType; /*˴ΪһƵ,һƵ*/ + packet->m_nInfoField2 = m_pRtmp->m_stream_id; + packet->m_nChannel = 0x04; + + packet->m_headerType = RTMP_PACKET_SIZE_LARGE; + if (RTMP_PACKET_TYPE_AUDIO == nPacketType && size != 4) + { + packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM; + } + packet->m_nTimeStamp = nTimestamp; + /**/ + int nRet = 0; + if (RTMP_IsConnected(m_pRtmp)) + { + nRet = RTMP_SendPacket(m_pRtmp, packet, TRUE); /*TRUEΪŽͶ,FALSEDzŽͶ,ֱӷ*/ + } + /*ͷڴ*/ + free(packet); + return 0; +} + +RtmpPusher::RtmpPusher() + :mThread(nullptr), + mIfConnected(false) +{ + +} + + +RtmpPusher::~RtmpPusher() +{ + if (m_pRtmp) + { + RTMP_Close(m_pRtmp); + RTMP_Free(m_pRtmp); + m_pRtmp = NULL; + } + CleanupSockets(); +} + +void H264RtmpPuser::OnAudioEncode(const void * frameaddress, uint32_t framelen,uint16_t pts) +{ + uint8_t *pack = (uint8_t*)malloc(framelen); + memcpy(pack, frameaddress, framelen); + + mMux.lock(); + Buffer buf; + buf.buf = (uint8_t *)pack; + buf.len = framelen; + buf.type = PAYLOAD_TYPE_AUDIO; + this->mPack.push(buf); + mMux.unlock(); + this->mAudioPts = pts; +} + +H264RtmpPuser::H264RtmpPuser() +{ + this->metaData.Pps = nullptr; + this->metaData.Sps = nullptr; + this->metaData.nPpsLen = 0; + this->metaData.nSpsLen = 0; + mFirtACC = false; +} + +int H264RtmpPuser::sortAndSendNal(uint8_t * data, int len) +{ + int i = 0; + uint8_t * nalhead = nullptr; + uint8_t * naltail = nullptr; + uint32_t size = 0; + + static int timestamp = 0; + timestamp += 1000 / 25; + if (nullptr == data) { + return -1; + } + while (i < len) + { + // sps pps p frame + if ((data[i] == 0x00) && (data[i + 1] == 0x00) + && ((data[i + 2] == 0x00) && (data[i + 3] == 0x01) || (data[i + 2] == 0x01))) { + if ((nalhead == nullptr) && (i == 0) ) { + if ((data[i + 3] == 0x01) && (data[i + 4] == 0x41)) { //p ֱ֡ӷ + nalhead = data; + naltail = data + (len); + size = naltail - nalhead; + this->SendH264Packet(nalhead, size, 0, timestamp); + return 0; + } + //sps ֡н + if ((data[i + 3] == 0x01) && (data[i + 4] == 0x67)) { // sps or pps or sei + nalhead = data; + i += 1; + } + //sei + if ((data[i + 2] == 0x01) && (data[i + 3] == 0x06)) { + i += 1; + } + } + else { + // i frame + if ((data[i + 2] == 0x01) && (data[i + 3] == 0x65)) { + naltail = data + i; + size = naltail - nalhead; + this->SendH264Packet(nalhead, size, 0, timestamp); + nalhead = data + i; + naltail = data + (len); + size = naltail - nalhead; + this->SendH264Packet(nalhead, size, 0, timestamp); + return 0; + } + //pps + if ((data[i + 3] == 0x01) && (data[i + 4] == 0x68)) { // sps or pps or sei + naltail = data + i; + size = naltail - nalhead; + this->SendH264Packet(nalhead, size, 0, timestamp); + nalhead = data + i; + i += 3; + }//sps + if ((data[i + 3] == 0x01) && (data[i + 4] == 0x67)) { // sps or pps or sei + nalhead = data + i; + i += 3; + } + //sei + if ((data[i + 3] == 0x01) && (data[i + 4] == 0x06)) { // sps or pps or sei + naltail = data + i; + size = naltail - nalhead; + this->SendH264Packet(nalhead, size, 0, timestamp); + nalhead = data + i; + i += 3; + } + // sps pps or sei + } + // 00 00 00 00 01 + } + i++; + } + return 0; +} + + +// Ƶͬϸṹhttps://blog.csdn.net/liwf616/article/details/51596373 +int H264RtmpPuser::SendVideoSpsPps(unsigned char * pps, + int pps_len, unsigned char * sps, + int sps_len,unsigned int nTimeStamp) +{ + RTMPPacket * packet = NULL;//rtmpṹ + unsigned char * body = NULL; + int i; + packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE + 1024); + //RTMPPacket_Reset(packet);//packet״̬ + memset(packet, 0, RTMP_HEAD_SIZE + 1024); + packet->m_body = (char *)packet + RTMP_HEAD_SIZE; + body = (unsigned char *)packet->m_body; + i = 0; + // FrameType == 1CodecID == 7 + body[i++] = 0x17; + //AVCPacketType + body[i++] = 0x00; + + //CompositionTime + body[i++] = 0x00; + body[i++] = 0x00; + body[i++] = 0x00; + + /*AVCDecoderConfigurationRecord*/ + body[i++] = 0x01; + body[i++] = sps[1]; + body[i++] = sps[2]; + body[i++] = sps[3]; + body[i++] = 0xff; + + /*sps*/ + body[i++] = 0xe1; + body[i++] = (sps_len >> 8) & 0xff; + body[i++] = sps_len & 0xff; + memcpy(&body[i], sps, sps_len); + i += sps_len; + + /*pps*/ + body[i++] = 0x01; + body[i++] = (pps_len >> 8) & 0xff; + body[i++] = (pps_len) & 0xff; + memcpy(&body[i], pps, pps_len); + i += pps_len; + + packet->m_packetType = RTMP_PACKET_TYPE_VIDEO; + packet->m_nBodySize = i; + packet->m_nChannel = 0x04; + packet->m_nTimeStamp = nTimeStamp; + packet->m_hasAbsTimestamp = 0; + packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM; + packet->m_nInfoField2 = m_pRtmp->m_stream_id; + + /*÷ͽӿ*/ + int nRet = RTMP_SendPacket(m_pRtmp, packet, TRUE); + free(packet); //ͷڴ + return nRet; +} + +int H264RtmpPuser::SendAudioData(unsigned char * dat, + unsigned int size, unsigned int nTimeStamp) +{ + return 0; +} + +int H264RtmpPuser::SendH264Packet(unsigned char * data, + unsigned int size, int bIsKeyFrame, unsigned int nTimeStamp) +{ + if(data == NULL){ + return false; + } + unsigned int nal_type = 0; + // С֡ӦPPSSPS + if ((data[0] != 0x00) || (data[1] != 0x00) + || ((data[2] != 0x00)&&data[2]!= 0x01)) { + return false; + } + //Debuger::Debug(L"%02x %02x %02x %02x %02x %02d\r\n", + // data[0],data[1],data[2],data[3],data[4],size); + if (data[2] == 0x01) { + nal_type = data[3]; + } + if (data[3] == 0x01) { + nal_type = data[4]; + } + switch (nal_type) + { + case 0x67: //just update sps and pps + if (NULL == metaData.Sps) + metaData.Sps = (unsigned char *)malloc(size - 4); + h264_decode_sps(data + 4, size - 4, metaData.nWidth, metaData.nHeight, metaData.nFrameRate); + metaData.nSpsLen = size - 4; + memcpy(this->metaData.Sps, data + 4, size - 4); + break; + case 0x68: //just update sps and pps + this->metaData.nPpsLen = size - 4; + if (NULL == metaData.Pps) metaData.Pps = (unsigned char *)malloc(size - 4); + memcpy(this->metaData.Pps, data + 4, size - 4); + break; + case 0x41: //p frame + this->sendDataPackH264(data + 4, size - 4, 0, nTimeStamp); + break; + case 0x65: //i frame + this->sendDataPackH264(data + 3, size - 3, 1, nTimeStamp); + break; + case 0x06: + size = size; + //this->sendDataPack(data + 4, size - 4, 0, nTimeStamp); + break; + default: + break; + } + +} +unsigned char *gBody = nullptr; +int H264RtmpPuser::sendDataPackH264(unsigned char * data, + unsigned int size, int bIsKeyFrame, unsigned int nTimeStamp) +{ + if (gBody == nullptr) { + gBody = new unsigned char[640*720*3 + 9]; + } + if (size < 0) { + gBody = gBody; + } + memset(gBody, 0, size + 9); + int i = 0; + if (1 == bIsKeyFrame) { + gBody[i++] = 0x17;// 1:Iframe 7:AVC + gBody[i++] = 0x01;// AVC NALU + gBody[i++] = 0x00; + gBody[i++] = 0x00; + gBody[i++] = 0x00; + + // NALU size + gBody[i++] = size >> 24 & 0xff; + gBody[i++] = size >> 16 & 0xff; + gBody[i++] = size >> 8 & 0xff; + gBody[i++] = size & 0xff; + // NALU data + memcpy(&gBody[i], data, size); + if(metaData.Sps != nullptr) + SendVideoSpsPps(metaData.Pps, metaData.nPpsLen, metaData.Sps, + metaData.nSpsLen, nTimeStamp); + } + else { + gBody[i++] = 0x27;// 2:Pframe 7:AVC + gBody[i++] = 0x01;// AVC NALU + gBody[i++] = 0x00; + gBody[i++] = 0x00; + gBody[i++] = 0x00; + // NALU size + gBody[i++] = size >> 24 & 0xff; + gBody[i++] = size >> 16 & 0xff; + gBody[i++] = size >> 8 & 0xff; + gBody[i++] = size & 0xff; + // NALU data + + memcpy(&gBody[i], data, size); + } + int bRet = SendPacket(RTMP_PACKET_TYPE_VIDEO, gBody, i + size, nTimeStamp); + return bRet; +} + + +int H264RtmpPuser::SendAudioSync(int audioType, + int sampleIndex, int channel, unsigned int nTimeStamp) +{ + RTMPPacket * packet = NULL;//rtmpṹ + unsigned char * body = NULL; + int i; + + packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE + 1024); + //RTMPPacket_Reset(packet);//packet״̬ + memset(packet, 0, RTMP_HEAD_SIZE + 1024); + packet->m_body = (char *)packet + RTMP_HEAD_SIZE; + body = (unsigned char *)packet->m_body; + + body[0] = 0xaf; + body[1] = 0x00; + + uint16_t audioSpecConf = 0; + audioSpecConf |= ((2 << 11) & 0xf800); //2: AACLC + audioSpecConf |= ((4 << 7) & 0x0780); //4: 44khz + audioSpecConf |= ((2 << 3) & 0x78); //4: 2:stero + audioSpecConf |= 0 & 0x07; //4: 0 padding + body[2] = (audioSpecConf >> 8) & 0xff; + body[3] = audioSpecConf & 0xff; + + + packet->m_packetType = RTMP_PACKET_TYPE_AUDIO; + packet->m_nBodySize = 4; + packet->m_nChannel = 0x04; + packet->m_nTimeStamp = nTimeStamp; + packet->m_hasAbsTimestamp = 0; + packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM; + packet->m_nInfoField2 = m_pRtmp->m_stream_id; + + /*÷ͽӿ*/ + int nRet = RTMP_SendPacket(m_pRtmp, packet, TRUE); + free(packet); //ͷڴ + return nRet; +} + + +int H264RtmpPuser::sendDataPackAAC(unsigned char * data, + unsigned int size, unsigned int nTimeStamp) +{ + unsigned char *gBody = nullptr; + static int timestamp = 0; + timestamp += 20; + if (!mFirtACC) { + SendAudioSync(2,4,4, timestamp); + mFirtACC = 1; + } + gBody = (unsigned char*)malloc(size + 2); + gBody[0] = 0xAF; + gBody[1] = 0x01; //aac raw data + memcpy(gBody + 2, data + 7, size - 7); + int bRet = SendPacket(RTMP_PACKET_TYPE_AUDIO, gBody, + size - 7 + 2, timestamp); + free(gBody); + return 0; +} + +void H264RtmpPuser::OnGetCodeFrame(uint8_t * data, int len) +{ + static int timetamp = 0; + timetamp += this->mTick; + uint8_t *pack = (uint8_t*)malloc(len); + memcpy(pack, data, len); + mMux.lock(); + Buffer buf; + buf.buf = pack; + buf.len = len; + buf.type = PAYLOAD_TYPE_VIDEO; + this->mPack.push(buf); + mMux.unlock(); +} + +void H264RtmpPuser::ProcessSend() +{ + while (this->mIfStart) { + int len = mPack.size(); + if (!mPack.empty()) { + mMux.lock(); + Buffer buf = mPack.front(); + mPack.pop(); + mMux.unlock(); + //Ƶ֡ + if (buf.type == PAYLOAD_TYPE_VIDEO) { + this->sortAndSendNal(buf.buf, buf.len); + + }// Ƶ֡ + if (buf.type == PAYLOAD_TYPE_AUDIO) { + this->sendDataPackAAC(buf.buf, buf.len, this->mAudioPts); + } + free(buf.buf); + } + msleep(10); + } +} + +int ThreadEncode(H264RtmpPuser * p) +{ + Debuger::Debug(L"thread started\r\n"); + if (nullptr == p) + return -1; + p->ProcessSend(); + return 0; +} + +int H264RtmpPuser::StartPush() +{ + mIfStart = true; + this->mThread = new std::thread(ThreadEncode,this); + mThreadId = this->mThread->get_id(); + return 0; +} + +int H264RtmpPuser::StopPush() +{ + mIfConnected = false; + mIfStart = false; + if(mThread != nullptr) + this->mThread->join(); + this->RTMP264_Close(); + return 0; +} + + diff --git a/client/qt_gl_render/yuvgl/media/RtmpPusher.h b/client/qt_gl_render/yuvgl/media/RtmpPusher.h index b320ed0..cf3356c 100644 --- a/client/qt_gl_render/yuvgl/media/RtmpPusher.h +++ b/client/qt_gl_render/yuvgl/media/RtmpPusher.h @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef WIN32 #include diff --git a/client/qt_gl_render/yuvgl/yuvgl.pro b/client/qt_gl_render/yuvgl/yuvgl.pro index 50f8bdd..0b43eed 100644 --- a/client/qt_gl_render/yuvgl/yuvgl.pro +++ b/client/qt_gl_render/yuvgl/yuvgl.pro @@ -32,6 +32,9 @@ SOURCES += \ cplaywidget.cpp \ media/AACAudioCoder.cpp \ media/CameraCapture.cpp \ + media/RtmpPuller.cpp \ + media/RtmpPuller2.cpp \ + media/RtmpPusher.cpp \ media/imgutil.cpp \ utils/Base64.cpp \ utils/Debuger.cpp \ diff --git a/client/qt_gl_render/yuvgl/yuvgl.pro.user b/client/qt_gl_render/yuvgl/yuvgl.pro.user new file mode 100644 index 0000000..1d1ade5 --- /dev/null +++ b/client/qt_gl_render/yuvgl/yuvgl.pro.user @@ -0,0 +1,1291 @@ + + + + + + EnvironmentId + {bccf4b57-4470-414a-a840-fdad9939972c} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.0 MinGW 32-bit + Desktop Qt 5.14.0 MinGW 32-bit + qt.qt5.5140.win32_mingw73_kit + 0 + 0 + 0 + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:D:/project/multimedia/client/qt_gl_render/yuvgl/yuvgl.pro + D:/project/multimedia/client/qt_gl_render/yuvgl/yuvgl.pro + + false + + false + true + true + false + false + true + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Qt 5.14.0 (msvc2017) + Qt 5.14.0 (msvc2017) + {e7f4d0a4-ebba-4430-a5f7-020932213e78} + 0 + 0 + 0 + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Qt_5_14_0_msvc2017_e7f4d0-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Qt_5_14_0_msvc2017_e7f4d0-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Qt_5_14_0_msvc2017_e7f4d0-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:D:/project/multimedia/client/qt_gl_render/yuvgl/yuvgl.pro + D:/project/multimedia/client/qt_gl_render/yuvgl/yuvgl.pro + + false + + false + true + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.Target.2 + + Qt 5.14.0 (msvc2017) + Qt 5.14.0 (msvc2017) + {64b425c2-38f7-4c05-8b08-ba417625d345} + 0 + 0 + 0 + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Qt_5_14_0_msvc2017_64b425-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Qt_5_14_0_msvc2017_64b425-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Qt_5_14_0_msvc2017_64b425-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.Target.3 + + Desktop Qt 5.14.0 MinGW 64-bit + Desktop Qt 5.14.0 MinGW 64-bit + qt.qt5.5140.win64_mingw73_kit + 0 + 0 + 0 + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:D:/project/multimedia/client/qt_gl_render/yuvgl/yuvgl.pro + D:/project/multimedia/client/qt_gl_render/yuvgl/yuvgl.pro + + false + + false + true + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.Target.4 + + Desktop Qt 5.14.0 MSVC2017 64bit + Desktop Qt 5.14.0 MSVC2017 64bit + qt.qt5.5140.win64_msvc2017_64_kit + 0 + 0 + 0 + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MSVC2017_64bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MSVC2017_64bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + D:/project/multimedia/client/qt_gl_render/build-yuvgl-Desktop_Qt_5_14_0_MSVC2017_64bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:D:/project/multimedia/client/qt_gl_render/yuvgl/yuvgl.pro + D:/project/multimedia/client/qt_gl_render/yuvgl/yuvgl.pro + + false + + false + true + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 5 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/device/mpp/sample/hisi_rtsp_demo-master/rtsp_lib/rtsp.log b/device/mpp/sample/hisi_rtsp_demo-master/rtsp_lib/rtsp.log new file mode 100644 index 0000000..61483fc --- /dev/null +++ b/device/mpp/sample/hisi_rtsp_demo-master/rtsp_lib/rtsp.log @@ -0,0 +1,97 @@ +OPTIONS rtsp://192.168.6.68 RTSP/1.0 +CSeq: 2 +User-Agent: LibVLC/2.1.5 (LIVE555 Streaming Media v2014.05.27) + +RTSP/1.0 200 OK +CSeq: 2 +Public: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER +Date: Fri, Dec 25 2015 14:08:41 GMT + +DESCRIBE rtsp://192.168.6.68 RTSP/1.0 +CSeq: 3 +User-Agent: LibVLC/2.1.5 (LIVE555 Streaming Media v2014.05.27) +Accept: application/sdp + +RTSP/1.0 200 OK +CSeq: 3 +Content-Type: application/sdp +Content-Base: rtsp://192.168.6.68/ +Content-Length: 679 + +v=0 +o=- 1451052521156494 1451052521156494 IN IP4 192.168.6.68 +s=Media Presentation +e=NONE +b=AS:5100 +t=0 0 +a=control:rtsp://192.168.6.68/ +m=video 0 RTP/AVP 96 +c=IN IP4 0.0.0.0 +b=AS:5000 +a=recvonly +a=x-dimensions:1280,960 +a=control:rtsp://192.168.6.68/trackID=1 +a=rtpmap:96 H264/90000 +a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z2QAIK2EAQwgCGEAQwgCGEAQwgCEK1AoA803AQEBAg==,aO48sA== +m=audio 0 RTP/AVP 0 +c=IN IP4 0.0.0.0 +b=AS:50 +a=recvonly +a=control:rtsp://192.168.6.68/trackID=2 +a=rtpmap:0 PCMU/8000 +a=Media_header:MEDIAINFO=494D4B48010100000400010010710110401F000000FA000000000000000000000000000000000000; +a=appversion:1.0 +SETUP rtsp://192.168.6.68/trackID=1 RTSP/1.0 +CSeq: 4 +User-Agent: LibVLC/2.1.5 (LIVE555 Streaming Media v2014.05.27) +Transport: RTP/AVP;unicast;client_port=56296-56297 + +RTSP/1.0 200 OK +CSeq: 4 +Session: 283812775;timeout=60 +Transport: RTP/AVP;unicast;client_port=56296-56297;server_port=8236-8237;ssrc=2d02fa0f;mode="play" +Date: Fri, Dec 25 2015 14:08:41 GMT + +SETUP rtsp://192.168.6.68/trackID=2 RTSP/1.0 +CSeq: 5 +User-Agent: LibVLC/2.1.5 (LIVE555 Streaming Media v2014.05.27) +Transport: RTP/AVP;unicast;client_port=56298-56299 +Session: 283812775 + +RTSP/1.0 200 OK +CSeq: 5 +Session: 283812775;timeout=60 +Transport: RTP/AVP;unicast;client_port=56298-56299;server_port=8234-8235;ssrc=1266baad;mode="play" +Date: Fri, Dec 25 2015 14:08:41 GMT + +PLAY rtsp://192.168.6.68/ RTSP/1.0 +CSeq: 6 +User-Agent: LibVLC/2.1.5 (LIVE555 Streaming Media v2014.05.27) +Session: 283812775 +Range: npt=0.000- + +RTSP/1.0 200 OK +CSeq: 6 +Session: 283812775 +RTP-Info: url=rtsp://192.168.6.68/trackID=1;seq=16387;rtptime=1724325370,url=rtsp://192.168.6.68/trackID=2;seq=30619;rtptime=153273528 +Date: Fri, Dec 25 2015 14:08:41 GMT + +GET_PARAMETER rtsp://192.168.6.68/ RTSP/1.0 +CSeq: 7 +User-Agent: LibVLC/2.1.5 (LIVE555 Streaming Media v2014.05.27) +Session: 283812775 + +RTSP/1.0 200 OK +CSeq: 7 +Date: Fri, Dec 25 2015 14:08:41 GMT + +TEARDOWN rtsp://192.168.6.68/ RTSP/1.0 +CSeq: 8 +User-Agent: LibVLC/2.1.5 (LIVE555 Streaming Media v2014.05.27) +Session: 283812775 + +RTSP/1.0 200 OK +CSeq: 8 +Session: 283812775 +Date: Fri, Dec 25 2015 14:08:49 GMT + diff --git a/device/mpp/sample/venc/a.exe b/device/mpp/sample/venc/a.exe new file mode 100644 index 0000000..f480a33 Binary files /dev/null and b/device/mpp/sample/venc/a.exe differ