luo 3 years ago
parent
commit
7fa0217cd8
7 changed files with 600 additions and 0 deletions
  1. 31 0
      MediaSource.sln
  2. 183 0
      MediaSource.vcxproj
  3. 30 0
      MediaSource.vcxproj.filters
  4. 11 0
      MediaSource.vcxproj.user
  5. 65 0
      MediaSourceMain.cpp
  6. 234 0
      MediaSourceRtsp.cpp
  7. 46 0
      MediaSourceRtsp.h

+ 31 - 0
MediaSource.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30907.101
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MediaSource", "MediaSource.vcxproj", "{AACB60E5-A48B-4761-AA88-21289CC4E295}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{AACB60E5-A48B-4761-AA88-21289CC4E295}.Debug|x64.ActiveCfg = Debug|x64
+		{AACB60E5-A48B-4761-AA88-21289CC4E295}.Debug|x64.Build.0 = Debug|x64
+		{AACB60E5-A48B-4761-AA88-21289CC4E295}.Debug|x86.ActiveCfg = Debug|Win32
+		{AACB60E5-A48B-4761-AA88-21289CC4E295}.Debug|x86.Build.0 = Debug|Win32
+		{AACB60E5-A48B-4761-AA88-21289CC4E295}.Release|x64.ActiveCfg = Release|x64
+		{AACB60E5-A48B-4761-AA88-21289CC4E295}.Release|x64.Build.0 = Release|x64
+		{AACB60E5-A48B-4761-AA88-21289CC4E295}.Release|x86.ActiveCfg = Release|Win32
+		{AACB60E5-A48B-4761-AA88-21289CC4E295}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {5B3C1813-48D6-4468-9120-5D2C95F539C5}
+	EndGlobalSection
+EndGlobal

+ 183 - 0
MediaSource.vcxproj

@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="MediaSourceMain.cpp" />
+    <ClCompile Include="MediaSourceRtsp.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="MediaSourceRtsp.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{aacb60e5-a48b-4761-aa88-21289cc4e295}</ProjectGuid>
+    <RootNamespace>RtspPushApp</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(ProjectDir)$(PlatformToolset)\$(PlatformTarget)\$(Configuration)\</OutDir>
+    <IntDir>$(PlatformToolset)\$(PlatformTarget)\$(Configuration)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(ProjectDir)$(PlatformToolset)\$(PlatformTarget)\$(Configuration)\</OutDir>
+    <IntDir>$(PlatformToolset)\$(PlatformTarget)\$(Configuration)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(ProjectDir)$(PlatformToolset)\$(PlatformTarget)\$(Configuration)\</OutDir>
+    <IntDir>$(PlatformToolset)\$(PlatformTarget)\$(Configuration)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(ProjectDir)$(PlatformToolset)\$(PlatformTarget)\$(Configuration)\</OutDir>
+    <IntDir>$(PlatformToolset)\$(PlatformTarget)\$(Configuration)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader />
+      <PrecompiledHeaderFile />
+      <PrecompiledHeaderOutputFile />
+      <AdditionalIncludeDirectories>..\cvs\DeviceSDKs\libffmpeg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\cvs\DeviceSDKs\libffmpeg\lib\$(PlatformTarget)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader />
+      <PrecompiledHeaderFile />
+      <PrecompiledHeaderOutputFile />
+      <AdditionalIncludeDirectories>..\cvs\DeviceSDKs\libffmpeg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\cvs\DeviceSDKs\libffmpeg\lib\$(PlatformTarget)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>false</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <AdditionalIncludeDirectories>..\cvs\DeviceSDKs\libffmpeg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PrecompiledHeader />
+      <PrecompiledHeaderFile />
+      <PrecompiledHeaderOutputFile />
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>..\cvs\DeviceSDKs\libffmpeg\lib\$(PlatformTarget)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>false</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <AdditionalIncludeDirectories>..\cvs\DeviceSDKs\libffmpeg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PrecompiledHeader />
+      <PrecompiledHeaderFile />
+      <PrecompiledHeaderOutputFile />
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\cvs\DeviceSDKs\libffmpeg\lib\$(PlatformTarget)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 30 - 0
MediaSource.vcxproj.filters

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="MediaSourceMain.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="MediaSourceRtsp.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="MediaSourceRtsp.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>

+ 11 - 0
MediaSource.vcxproj.user

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerCommandArguments>rtsp://admin:123456@192.168.31.124/stream0 rtsp://192.168.31.181/live/0 tcp</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerCommandArguments>rtsp://admin:123456@192.168.31.124/stream0 rtsp://192.168.31.181/live/0 tcp</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+</Project>

+ 65 - 0
MediaSourceMain.cpp

@@ -0,0 +1,65 @@
+
+#include <windows.h>
+
+#include "MediaSourceRtsp.h"
+
+
+int main(int argc, char** argv) 
+{
+
+	if (argc != 4) {
+
+		printf("Failed\n");
+		printf("RtspPush [src_rtsp] [out_rtsp] [tcp/udp]\n");
+		printf("[src_rtsp] input rtsp\n");
+		printf("[src_rtsp] output rtsp\n");
+		return 0;
+	}
+
+	CMediaSourceRtsp pusher;
+	pusher.m_Input_rtsp = std::string(argv[1]);
+	pusher.m_Output_rtsp = std::string(argv[2]);
+
+	std::string tcporudp = std::string(argv[3]);
+	if ((tcporudp == "TCP") || (tcporudp == "tcp"))
+		pusher.m_TcpOrudp = "tcp";
+	if ((tcporudp == "UDP") || (tcporudp == "udp"))
+		pusher.m_TcpOrudp = "udp";
+
+	if (!pusher.OpenInput(pusher.m_Input_rtsp, pusher.m_TcpOrudp)) {
+		printf("open input_rtsp failed\n");
+		exit(-1);
+	}
+
+	if (!pusher.OpenOutput(pusher.m_Output_rtsp)) {
+		printf("open output_rtsp failed\n");
+		exit(-1);
+	}
+
+	int ret = -1;
+
+	while (true) {
+	
+		std::shared_ptr<AVPacket> packet = nullptr;
+
+		packet = pusher.ReadPacket();
+
+		if (!packet) {
+			OutputDebugStringA("GetAvPacket ERROR\n");
+			printf("GetAvPacket ERROR\n");
+			pusher.ResetConnect();
+			continue;
+		}
+
+		if ((packet) && (packet->stream_index == pusher.m_nVideoStream)) {
+		
+			ret = pusher.WritePacket(packet);
+
+			if (ret < 0) {
+			
+				pusher.CheckOutputNet();
+			}
+		}
+	}
+	return 0;
+}

+ 234 - 0
MediaSourceRtsp.cpp

@@ -0,0 +1,234 @@
+#include <thread>
+
+#include <windows.h>
+
+#include "MediaSourceRtsp.h"
+
+#pragma comment(lib, "avformat.lib")
+#pragma comment(lib, "avcodec.lib")
+#pragma comment(lib, "avdevice.lib")
+#pragma comment(lib, "avutil.lib")
+
+CMediaSourceRtsp::CMediaSourceRtsp()
+{
+	outputContext = nullptr;
+	inputContext = nullptr;
+	m_nStartTime = 0;
+	m_nWriteflag = false;
+	m_timeout = 2;
+	m_NetCount = 0;
+	m_nVideoStream = -1;
+	av_register_all();
+	avformat_network_init();
+	avcodec_register_all();
+	avdevice_register_all();
+}
+
+CMediaSourceRtsp::~CMediaSourceRtsp()
+{
+	CloseInput();
+	CloseOutput();
+
+}
+
+void CMediaSourceRtsp::CloseInput()
+{
+	if (inputContext) {
+		avformat_close_input(&inputContext);
+		inputContext = nullptr;
+	}
+}
+
+void CMediaSourceRtsp::CloseOutput()
+{
+	if (outputContext) {
+		av_write_trailer(outputContext);
+		for (int i = 0; i < outputContext->nb_streams; i++)
+		{
+			if (outputContext->streams[i]->codec)
+				avcodec_close(outputContext->streams[i]->codec);
+		}
+		avformat_close_input(&outputContext);
+		outputContext = nullptr;
+	}
+}
+
+void CMediaSourceRtsp::ActionOpenInput()
+{
+	while (1) {
+		if (OpenInput(m_Input_rtsp, m_TcpOrudp))
+			break;
+		std::this_thread::sleep_for(std::chrono::milliseconds(2000));
+	}
+}
+
+void CMediaSourceRtsp::ActionOpenOutput()
+{
+	while (1) {
+		if (OpenOutput(m_Output_rtsp))
+			break;
+		std::this_thread::sleep_for(std::chrono::milliseconds(5000));
+	}
+}
+
+void CMediaSourceRtsp::CheckOutputNet()
+{
+	m_NetCount++;
+	if (m_NetCount > 500) {
+		if (outputContext) {
+			m_NetCount = 0;
+			m_nWriteflag = false;
+			CloseOutput();
+			ActionOpenOutput();
+		}
+	}
+}
+
+void CMediaSourceRtsp::ResetConnect()
+{
+	if (inputContext) {
+		CloseInput();
+		CloseOutput();
+	}
+	//这里会一直阻塞,知道视频源和输出源正常连接
+	ActionOpenInput();
+	ActionOpenOutput();
+}
+
+bool CMediaSourceRtsp::OpenInput(std::string inputUrl, std::string transport)
+{
+	bool result = false;
+
+	inputContext = avformat_alloc_context();
+	AVDictionary* options = nullptr;
+
+	if (transport == "tcp") {
+
+		av_dict_set(&options, "rtsp_transport", "tcp", 0);
+		av_dict_set(&options, "stimeout", "2000000", 0);
+
+		if (0 > avformat_open_input(&inputContext, inputUrl.c_str(), nullptr, &options)) {
+
+			OutputDebugStringA("failed open input file1");
+			
+			return result;
+		}
+
+	} else {
+
+		av_dict_set(&options, "rtsp_transport", "udp", 0);
+		av_dict_set(&options, "stimeout", "2000000", 0);
+		if (0 > avformat_open_input(&inputContext, inputUrl.c_str(), nullptr, &options)) {
+
+			OutputDebugStringA("failed open input file1");
+			
+			return result;
+		}
+	}
+
+	int ret = avformat_find_stream_info(inputContext, nullptr);
+	if (ret < 0)
+	{
+		OutputDebugStringA("Find input file stream inform failed");
+		return result;
+	}
+	m_nVideoStream = av_find_best_stream(inputContext, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
+	if (-1 == m_nVideoStream) {
+		OutputDebugStringA("failed av_find_best_stream");
+		return result;
+	}
+	return true;
+}
+int  CMediaSourceRtsp::InterruptCb(void* ctx)
+{
+	CMediaSourceRtsp* media_source = (CMediaSourceRtsp*)ctx;
+
+	if (media_source->m_nWriteflag){
+		return 0;
+	}
+	int64_t localTime = av_gettime();
+	
+	//1s = 1000*1000微妙
+	int times = (localTime % (media_source->m_nStartTime))/(1000*1000);
+	if (times > media_source->m_timeout)
+	{
+		return 1;
+	}
+	return 0;
+}
+
+int CMediaSourceRtsp::WritePacket(std::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());
+}
+
+std::shared_ptr<AVPacket> CMediaSourceRtsp::ReadPacket()
+{
+	std::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());
+	int ret = av_read_frame(inputContext, packet.get());
+	if (ret >= 0)
+	{
+		return packet;
+	}
+	else
+	{
+		return nullptr;
+	}
+}
+
+bool CMediaSourceRtsp::OpenOutput(std::string outUrl)
+{
+	bool result = false;
+	int ret = avformat_alloc_output_context2(&outputContext, nullptr, "rtsp", outUrl.c_str());
+	if (ret < 0)
+	{
+		OutputDebugStringA("open output context failed");
+		
+		return result;
+	}
+	//设置超时回调
+	outputContext->interrupt_callback.callback = InterruptCb;    // 设置超时回调
+	outputContext->interrupt_callback.opaque = this;
+
+
+	//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);
+	//	if (ret < 0)
+	//	{
+	//		av_log(NULL, AV_LOG_ERROR, "copy coddec context failed");
+	//		return result;
+	//	}
+	//}
+	AVStream* stream = avformat_new_stream(outputContext, inputContext->streams[m_nVideoStream]->codec->codec);
+	avcodec_copy_context(stream->codec, inputContext->streams[m_nVideoStream]->codec);
+	if (ret < 0)
+	{
+		OutputDebugStringA("copy coddec context failed");
+		return result;
+	}
+
+	//需要留意的是发输出是rtsp流时,是不需要调用avio_open,如果你调用了返回值是<0,所以这里m_pOutfmt_ctx->oformat->flags & AVFMT_NOFILE条件判断
+	if (!(outputContext->oformat->flags & AVFMT_NOFILE)) {
+		if (0 > avio_open(&outputContext->pb, outUrl.c_str(), AVIO_FLAG_WRITE)) {
+			OutputDebugStringA("open avio failed");
+			return result;
+		}
+	}
+
+	m_nStartTime = av_gettime();
+	ret = avformat_write_header(outputContext, nullptr);
+	if (ret < 0)
+	{
+		OutputDebugStringA("format write header failed");
+		
+		return result;
+	}
+	m_nWriteflag = true;
+	return true;
+}

+ 46 - 0
MediaSourceRtsp.h

@@ -0,0 +1,46 @@
+#pragma once
+
+#include <string>
+#include <memory>
+
+extern "C"
+{
+	#include "libavformat/avformat.h"
+	#include "libavcodec/avcodec.h"
+	#include "libavdevice/avdevice.h"
+	#include "libavutil/imgutils.h"  
+	#include "libswscale/swscale.h"
+	#include "libavutil/timestamp.h"
+	#include "libavutil/rational.h"
+	#include "libavutil/time.h"
+}
+
+class CMediaSourceRtsp {
+
+public:
+
+	CMediaSourceRtsp();
+	~CMediaSourceRtsp();
+
+	std::string m_Input_rtsp;
+	std::string m_Output_rtsp;
+	std::string m_TcpOrudp;
+	int m_nVideoStream;
+	bool m_nWriteflag;
+	int64_t m_timeout;//打开输出文件阻塞的超时时间,单位为秒,av_gettime获取的单位是微妙
+	int m_NetCount;
+	int64_t m_nStartTime;//微妙
+	AVFormatContext* outputContext;
+	AVFormatContext* inputContext;
+	void CheckOutputNet();
+	void ResetConnect();
+	void ActionOpenInput();
+	void ActionOpenOutput();
+	bool OpenInput(std::string inputUrl, std::string transport);
+	bool OpenOutput(std::string outUrl);
+	static int InterruptCb(void* ctx);
+	void CloseOutput();
+	void CloseInput();
+	std::shared_ptr<AVPacket> ReadPacket();
+	int WritePacket(std::shared_ptr<AVPacket> packet);
+};