#ifndef PCH_H #define PCH_H extern "C" { #include "libavutil/opt.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/imgutils.h" #include "libavutil/mathematics.h" #include "libavutil/samplefmt.h" #include "libavutil/time.h" #include "libavutil/fifo.h" #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavformat/avio.h" // #include "libavfilter/avfiltergraph.h" #include "libavfilter/avfilter.h" #include "libavfilter/buffersink.h" #include "libavfilter/buffersrc.h" #include "libswscale/swscale.h" #include "libswresample/swresample.h" } #endifpch.h
// CGaveFile.cpp : 定义控制台应用程序的入口点。 // /* Copyright [c] 2018-2028 By www.chungen90.com Allrights Reserved This file give a simple example of how to get stream from buffer. Any questions, you can join QQ group for help, QQ Group number:127903734 or 766718184. */ //#include "stdafx.h" #include "pch.h" #include <string> #include <memory> #include <thread> #include <iostream> #include <WinSock2.h> using namespace std; #pragma comment(lib, "Ws2_32.lib") class UdpSocket { public: UdpSocket() { } public: SOCKET RecvSocket; }; AVFormatContext *inputContext = nullptr; AVFormatContext * outputContext; int64_t lastReadPacktTime ; UdpSocket udpSocket; static int interrupt_cb(void *ctx) { int timeout = 10; if(av_gettime() - lastReadPacktTime > timeout *1000 *1000) { return -1; } return 0; } static int readUdpSocket(void *opaque, uint8_t *buf, int buf_size) { UdpSocket *udpSocket = (UdpSocket *)opaque; char cRecvBuff[2000]; //定义接收缓冲区 SOCKADDR_IN sin,saClient; int nSize = sizeof(saClient); int readSize = buf_size < sizeof(cRecvBuff) ? buf_size :sizeof(cRecvBuff); auto iResult = recvfrom(udpSocket->RecvSocket, (char *)cRecvBuff, readSize, 0, (SOCKADDR *) & saClient, &nSize); if (iResult == SOCKET_ERROR) { wprintf(L"recvfrom failed with error %d\n", WSAGetLastError()); iResult = 0; } else { if( iResult > 0) { memcpy(buf,cRecvBuff ,iResult ); } } if( iResult > 0) { return iResult; } return iResult; } int OpenInput() { lastReadPacktTime = av_gettime(); int size = 32 * 1024; uint8_t * iobuffer = (uint8_t *)av_malloc(size); AVIOContext *avio = avio_alloc_context(iobuffer, size, 0, &udpSocket, readUdpSocket, NULL, NULL); inputContext = avformat_alloc_context(); inputContext->pb = avio; inputContext->start_time_realtime = av_gettime(); int ret = avformat_open_input(&inputContext, nullptr, nullptr, nullptr); if(ret < 0) { av_log(NULL, AV_LOG_ERROR, "Input file open input failed\n"); return ret; } ret = avformat_find_stream_info(inputContext,nullptr); if(ret < 0) { av_log(NULL, AV_LOG_ERROR, "Find input file stream inform failed\n"); } else { av_log(NULL, AV_LOG_FATAL, "Open input file success\n"); } return ret; } shared_ptr<AVPacket> ReadPacketFromSource() { shared_ptr<AVPacket> packet(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_packet_free(&p); av_freep(&p);}); av_init_packet(packet.get()); lastReadPacktTime = av_gettime(); int ret = av_read_frame(inputContext, packet.get()); if(ret >= 0) { return packet; } else { return nullptr; } } void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb) { if (pkt->pts != AV_NOPTS_VALUE) pkt->pts = av_rescale_q(pkt->pts, src_tb, dst_tb); if (pkt->dts != AV_NOPTS_VALUE) pkt->dts = av_rescale_q(pkt->dts, src_tb, dst_tb); if (pkt->duration > 0) pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb); } int WritePacket(shared_ptr<AVPacket> packet) { auto inputStream = inputContext->streams[packet->stream_index]; auto outputStream = outputContext->streams[packet->stream_index]; av_packet_rescale_ts(packet.get(),inputStream->time_base,outputStream->time_base); return av_interleaved_write_frame(outputContext, packet.get()); } int OpenOutput(string outUrl) { int ret = avformat_alloc_output_context2(&outputContext, nullptr, "flv", outUrl.c_str()); if(ret < 0) { av_log(NULL, AV_LOG_ERROR, "open output context failed\n"); goto Error; } ret = avio_open2(&outputContext->pb, outUrl.c_str(), AVIO_FLAG_WRITE,nullptr, nullptr); if(ret < 0) { av_log(NULL, AV_LOG_ERROR, "open avio failed"); goto Error; } for(int i = 0; i < inputContext->nb_streams; i++) { AVStream * stream = avformat_new_stream(outputContext, inputContext->streams[i]->codec->codec); ret = avcodec_copy_context(stream->codec, inputContext->streams[i]->codec); stream->codec->codec_tag = 0; if(ret < 0) { av_log(NULL, AV_LOG_ERROR, "copy coddec context failed"); goto Error; } } ret = avformat_write_header(outputContext, nullptr); if(ret < 0) { av_log(NULL, AV_LOG_ERROR, "format write header failed"); goto Error; } av_log(NULL, AV_LOG_FATAL, " Open output file success %s\n",outUrl.c_str()); return ret ; Error: if(outputContext) { for(int i = 0; i < outputContext->nb_streams; i++) { avcodec_close(outputContext->streams[i]->codec); } avformat_close_input(&outputContext); } return ret ; } void CloseInput() { if(inputContext != nullptr) { avformat_close_input(&inputContext); } } void CloseOutput() { if(outputContext != nullptr) { for(int i = 0 ; i < outputContext->nb_streams; i++) { AVCodecContext *codecContext = outputContext->streams[i]->codec; avcodec_close(codecContext); } avformat_close_input(&outputContext); } } void Init() { av_register_all(); avfilter_register_all(); avformat_network_init(); av_log_set_level(AV_LOG_ERROR); } int InitUdpSocket(string ip,int port) { WSADATA wsaData; SOCKET sockListener; sockaddr_in RecvAddr; auto iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != NO_ERROR) { wprintf(L"WSAStartup failed with error %d\n", iResult); return -1; } udpSocket.RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (udpSocket.RecvSocket == INVALID_SOCKET) { wprintf(L"socket failed with error %d\n", WSAGetLastError()); return -1; } //----------------------------------------------- // Bind the socket to any address and the specified port. RecvAddr.sin_family = AF_INET; RecvAddr.sin_port = htons(port); RecvAddr.sin_addr.s_addr = inet_addr(ip.c_str()); int nNetTimeout = 10000; auto ret1 = setsockopt(udpSocket.RecvSocket,SOL_SOCKET,SO_RCVTIMEO,( char *)&nNetTimeout, sizeof(struct timeval)); iResult = ::bind(udpSocket.RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr)); if (iResult != 0) { wprintf(L"bind failed with error %d\n", WSAGetLastError()); return -1; } return 0; } int main(int argc, char* argv[]) { Init(); string ip = "127.0.0.1"; int port = 1234; int ret = InitUdpSocket(ip,port); if(ret <0 ) { cout <<"Init Udp Socket failed"<<endl; goto Error; } ret = OpenInput(); if(ret >= 0) { ret = OpenOutput("rtmp://192.168.169.139/live/stream0"); } if(ret <0) goto Error; while(true) { auto packet = ReadPacketFromSource(); if(packet) { ret = WritePacket(packet); if(ret >= 0) { cout<<"WritePacket Success!"<<endl; } else { cout<<"WritePacket failed!"<<endl; } } else { break; } } Error: CloseInput(); CloseOutput(); while(true) { this_thread::sleep_for(chrono::seconds(100)); } return 0; }main.cpp