提交 80c109bf 编写于 作者: S SwordTwelve

add EasyIPCamera_File module

read muti h264 file to output rtsp streams,it makes IPC become so easy!
上级 d7a4214b
......@@ -5,6 +5,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EasyIPCamera_RTSP", "EasyIP
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EasyIPCamera_Win", "EasyIPCamera_Win\EasyIPCamera_Win.vcxproj", "{58B88D78-5ACB-4C70-A25C-3BBD7B85C5AA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EasyIPCamera_File", "EasyIPCamera_File\EasyIPCamera_File.vcxproj", "{D91D8F4A-C731-4543-B0F6-86ACDAB3ED39}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
......@@ -19,6 +21,10 @@ Global
{58B88D78-5ACB-4C70-A25C-3BBD7B85C5AA}.Debug|Win32.Build.0 = Debug|Win32
{58B88D78-5ACB-4C70-A25C-3BBD7B85C5AA}.Release|Win32.ActiveCfg = Release|Win32
{58B88D78-5ACB-4C70-A25C-3BBD7B85C5AA}.Release|Win32.Build.0 = Release|Win32
{D91D8F4A-C731-4543-B0F6-86ACDAB3ED39}.Debug|Win32.ActiveCfg = Debug|Win32
{D91D8F4A-C731-4543-B0F6-86ACDAB3ED39}.Debug|Win32.Build.0 = Debug|Win32
{D91D8F4A-C731-4543-B0F6-86ACDAB3ED39}.Release|Win32.ActiveCfg = Release|Win32
{D91D8F4A-C731-4543-B0F6-86ACDAB3ED39}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" 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>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D91D8F4A-C731-4543-B0F6-86ACDAB3ED39}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>EasyIPCamera_File</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</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>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../Include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>../Lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>ws2_32.lib;wsock32.lib;winmm.lib;libEasyIPCamera.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../Include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>../Lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>ws2_32.lib;wsock32.lib;winmm.lib;libEasyIPCamera.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="getopt.c" />
<ClCompile Include="GetVPSSPSPPS.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="trace.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="getopt.h" />
<ClInclude Include="GetVPSSPSPPS.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<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="getopt.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="trace.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="GetVPSSPSPPS.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="getopt.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="trace.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="GetVPSSPSPPS.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
#include "GetVPSSPSPPS.h"
//输入的pbuf必须包含start code(00 00 00 01)
int GetH265VPSandSPSandPPS(char *pbuf, int bufsize, char *_vps, int *_vpslen, char *_sps, int *_spslen, char *_pps, int *_ppslen)
{
char vps[512]={0}, sps[512] = {0}, pps[128] = {0};
int vpslen=0, spslen=0, ppslen=0, i=0, iStartPos=0, ret=-1;
int iFoundVPS=0, iFoundSPS=0, iFoundPPS=0, iFoundSEI=0;
if (NULL == pbuf || bufsize<4) return -1;
for (i=0; i<bufsize; i++)
{
if ( (unsigned char)pbuf[i] == 0x00 && (unsigned char)pbuf[i+1] == 0x00 &&
(unsigned char)pbuf[i+2] == 0x00 && (unsigned char)pbuf[i+3] == 0x01 )
{
printf("0x%X\n", (unsigned char)pbuf[i+4]);
switch ((unsigned char)pbuf[i+4])
{
case 0x40: //VPS
{
iFoundVPS = 1;
iStartPos = i+4;
}
break;
case 0x42: //SPS
{
if (iFoundVPS == 0x01 && i>4)
{
vpslen = i-4-iStartPos;
if (vpslen>256) return -1; //vps长度超出范围
memset(vps, 0x00, sizeof(vps));
memcpy(vps, pbuf+iStartPos, vpslen);
}
iStartPos = i+4;
iFoundSPS = 1;
}
break;
case 0x44: //PPS
{
if (iFoundSPS == 0x01 && i>4)
{
spslen = i-4-iStartPos;
if (spslen>256) return -1;
memset(sps, 0x0, sizeof(sps));
memcpy(sps, pbuf+iStartPos, spslen);
}
iStartPos = i+4;
iFoundPPS = 1;
}
break;
case 0x4E: //SEI
case 0x50:
{
if (iFoundPPS == 0x01 && i>4)
{
ppslen = i-4-iStartPos;
if (ppslen>256) return -1;
memset(pps, 0x0, sizeof(pps));
memcpy(pps, pbuf+iStartPos, ppslen);
}
iStartPos = i+4;
iFoundSEI = 1;
}
break;
default:
break;
}
}
if (iFoundSEI == 0x01) break;
}
if (iFoundVPS == 0x01)
{
if (vpslen < 1)
{
if (bufsize < sizeof(vps))
{
vpslen = bufsize-4;
memset(vps, 0x00, sizeof(vps));
memcpy(vps, pbuf+4, vpslen);
}
}
if (vpslen > 0)
{
if (NULL != _vps) memcpy(_vps, vps, vpslen);
if (NULL != _vpslen) *_vpslen = vpslen;
}
ret = 0;
}
if (iFoundSPS == 0x01)
{
if (spslen < 1)
{
if (bufsize < sizeof(sps))
{
spslen = bufsize-4;
memset(sps, 0x00, sizeof(sps));
memcpy(sps, pbuf+4, spslen);
}
}
if (spslen > 0)
{
if (NULL != _sps) memcpy(_sps, sps, spslen);
if (NULL != _spslen) *_spslen = spslen;
}
ret = 0;
}
if (iFoundPPS == 0x01)
{
if (ppslen < 1)
{
if (bufsize < sizeof(pps))
{
ppslen = bufsize-4;
memset(pps, 0x00, sizeof(pps));
memcpy(pps, pbuf+4, ppslen); //pps
}
}
if (ppslen > 0)
{
if (NULL != _pps) memcpy(_pps, pps, ppslen);
if (NULL != _ppslen) *_ppslen = ppslen;
}
ret = 0;
}
return ret;
}
//int GetVPSandSPSandPPS(char *pbuf, int bufsize, char *_vps, int *_vpslen, char *_sps, int *_spslen, char *_pps, int *_ppslen)
int GetH264SPSandPPS(char *pbuf, int bufsize, char *_sps, int *_spslen, char *_pps, int *_ppslen)
{
char sps[512] = {0,}, pps[128] = {0,};
int spslen=0, ppslen=0, i=0, iStartPos=0, ret=-1;
int iFoundSPS=0, iFoundPPS=0, iFoundIDR=0;
if (NULL == pbuf || bufsize<4) return -1;
for (i=0; i<bufsize; i++)
{
if ( (unsigned char)pbuf[i] == 0x00 && (unsigned char)pbuf[i+1] == 0x00 &&
(unsigned char)pbuf[i+2] == 0x00 && (unsigned char)pbuf[i+3] == 0x01 )
{
unsigned char naltype = ((unsigned char)pbuf[i+4] & 0x1F);
if (naltype == 7) //sps
{
iFoundSPS = 1;
iStartPos = i+4;
}
else if (naltype == 8) //pps
{
//copy sps
if (iFoundSPS == 0x01 && i>4)
{
spslen = i-4;
if (spslen>256) return -1; //sps长度超出范围
memset(sps, 0x00, sizeof(sps));
memcpy(sps, pbuf+4, spslen);
}
iFoundPPS = 1;
}
else if (naltype == 5) //idr
{
iFoundIDR = 1;
ppslen = i-spslen-4-4;
if (ppslen>0 && ppslen+ppslen<sizeof(pps))
{
memset(pps, 0x00, sizeof(pps));
memcpy(pps, pbuf+spslen+8, ppslen); //pps
}
break;
}
}
else
{
}
}
if (iFoundSPS == 0x01)
{
if (spslen < 1)
{
if (bufsize < sizeof(sps))
{
spslen = bufsize-4;
memset(sps, 0x00, sizeof(sps));
memcpy(sps, pbuf+4, spslen);
}
}
if (spslen > 0)
{
if (NULL != _sps) memcpy(_sps, sps, spslen);
if (NULL != _spslen) *_spslen = spslen;
}
ret = 0;
}
if (iFoundPPS == 0x01)
{
if (ppslen < 1)
{
if (bufsize < sizeof(pps))
{
ppslen = bufsize-4;
memset(pps, 0x00, sizeof(pps));
memcpy(pps, pbuf+4, ppslen); //pps
}
}
if (ppslen > 0)
{
if (NULL != _pps) memcpy(_pps, pps, ppslen);
if (NULL != _ppslen) *_ppslen = ppslen;
}
ret = 0;
}
return ret;
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int GetH265VPSandSPSandPPS(char *pbuf, int bufsize, char *_vps, int *_vpslen, char *_sps, int *_spslen, char *_pps, int *_ppslen);
int GetH264SPSandPPS(char *pbuf, int bufsize, char *_sps, int *_spslen, char *_pps, int *_ppslen);
#
# There exist several targets which are by default empty and which can be
# used for execution of your targets. These targets are usually executed
# before and after some main targets. They are:
#
# .build-pre: called before 'build' target
# .build-post: called after 'build' target
# .clean-pre: called before 'clean' target
# .clean-post: called after 'clean' target
# .clobber-pre: called before 'clobber' target
# .clobber-post: called after 'clobber' target
# .all-pre: called before 'all' target
# .all-post: called after 'all' target
# .help-pre: called before 'help' target
# .help-post: called after 'help' target
#
# Targets beginning with '.' are not intended to be called on their own.
#
# Main targets can be executed directly, and they are:
#
# build build a specific configuration
# clean remove built files from a configuration
# clobber remove all built files
# all build all configurations
# help print help mesage
#
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
# .help-impl are implemented in nbproject/makefile-impl.mk.
#
# Available make variables:
#
# CND_BASEDIR base directory for relative paths
# CND_DISTDIR default top distribution directory (build artifacts)
# CND_BUILDDIR default top build directory (object files, ...)
# CONF name of current configuration
# CND_PLATFORM_${CONF} platform name (current configuration)
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
#
# NOCDDL
# Environment
MKDIR=mkdir
CP=cp
CCADMIN=CCadmin
# build
build: .build-post
.build-pre:
# Add your pre 'build' code here...
.build-post: .build-impl
# Add your post 'build' code here...
# clean
clean: .clean-post
.clean-pre:
# Add your pre 'clean' code here...
.clean-post: .clean-impl
# Add your post 'clean' code here...
# clobber
clobber: .clobber-post
.clobber-pre:
# Add your pre 'clobber' code here...
.clobber-post: .clobber-impl
# Add your post 'clobber' code here...
# all
all: .all-post
.all-pre:
# Add your pre 'all' code here...
.all-post: .all-impl
# Add your post 'all' code here...
# build tests
build-tests: .build-tests-post
.build-tests-pre:
# Add your pre 'build-tests' code here...
.build-tests-post: .build-tests-impl
# Add your post 'build-tests' code here...
# run tests
test: .test-post
.test-pre: build-tests
# Add your pre 'test' code here...
.test-post: .test-impl
# Add your post 'test' code here...
# help
help: .help-post
.help-pre:
# Add your pre 'help' code here...
.help-post: .help-impl
# Add your post 'help' code here...
# include project implementation makefile
include nbproject/Makefile-impl.mk
# include project make variables
include nbproject/Makefile-variables.mk
/*
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* Portions of this software are based upon public domain software
* originally written at the National Center for Supercomputing Applications,
* University of Illinois, Urbana-Champaign.
*/
#ifdef _WIN32
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#define OPTERRCOLON (1)
#define OPTERRNF (2)
#define OPTERRARG (3)
char *optarg;
int optreset = 0;
int optind = 1;
int opterr = 1;
int optopt;
static int
optiserr(int argc, char * const *argv, int oint, const char *optstr,
int optchr, int err)
{
if(opterr)
{
fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
switch(err)
{
case OPTERRCOLON:
fprintf(stderr, ": in flags\n");
break;
case OPTERRNF:
fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
break;
case OPTERRARG:
fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
break;
default:
fprintf(stderr, "unknown\n");
break;
}
}
optopt = argv[oint][optchr];
return('?');
}
int
getopt(int argc, char* const *argv, const char *optstr)
{
static int optchr = 0;
static int dash = 0; /* have already seen the - */
char *cp;
if (optreset)
optreset = optchr = dash = 0;
if(optind >= argc)
return(EOF);
if(!dash && (argv[optind][0] != '-'))
return(EOF);
if(!dash && (argv[optind][0] == '-') && !argv[optind][1])
{
/*
* use to specify stdin. Need to let pgm process this and
* the following args
*/
return(EOF);
}
if((argv[optind][0] == '-') && (argv[optind][1] == '-'))
{
/* -- indicates end of args */
optind++;
return(EOF);
}
if(!dash)
{
assert((argv[optind][0] == '-') && argv[optind][1]);
dash = 1;
optchr = 1;
}
/* Check if the guy tries to do a -: kind of flag */
assert(dash);
if(argv[optind][optchr] == ':')
{
dash = 0;
optind++;
return(optiserr(argc, argv, optind-1, optstr, optchr, OPTERRCOLON));
}
if(!(cp = strchr(optstr, argv[optind][optchr])))
{
int errind = optind;
int errchr = optchr;
if(!argv[optind][optchr+1])
{
dash = 0;
optind++;
}
else
optchr++;
return(optiserr(argc, argv, errind, optstr, errchr, OPTERRNF));
}
if(cp[1] == ':')
{
dash = 0;
optind++;
if(optind == argc)
return(optiserr(argc, argv, optind-1, optstr, optchr, OPTERRARG));
optarg = argv[optind++];
return(*cp);
}
else
{
if(!argv[optind][optchr+1])
{
dash = 0;
optind++;
}
else
optchr++;
return(*cp);
}
assert(0);
return(0);
}
#endif /* WIN32 */
/*
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* Portions of this software are based upon public domain software
* originally written at the National Center for Supercomputing Applications,
* University of Illinois, Urbana-Champaign.
*/
#ifndef GETOPT_H
#define GETOPT_H
#ifdef __cplusplus
extern "C" {
#endif
//#ifdef __Win32__
extern char *optarg;
extern int optreset;
extern int optind;
extern int opterr;
extern int optopt;
int getopt(int argc, char* const *argv, const char *optstr);
//#endif /* WIN32 */
#ifdef __cplusplus
}
#endif
#endif /* GETOPT_H */
/*
Copyright (c) 2013-2014 EasyDarwin.ORG. All rights reserved.
Github: https://github.com/EasyDarwin
WEChat: EasyDarwin
Website: http://www.EasyDarwin.org
*/
#ifdef _WIN32
#include <process.h>
#include "getopt.h"
#include <windows.h>
//#include<winsock2.h>
#else //for linux
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define CALLBACK
#define Sleep(x) usleep(x*1000)
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "EasyIPCameraAPI.h"
#include "GetVPSSPSPPS.h"
#ifdef _WIN32
#define KEY_EASYIPCAMERA "6D72754B7A4969576B5A754176744659707935424A65704659584E35535642445957316C636D4666526D6C735A53356C65475658444661672F365867523246326157346D516D466962334E68514449774D545A4659584E355247467964326C75564756686257566863336B3D"
#elif def _ARM
#define KEY_EASYIPCAMERA "6D72754B7A502B2B72624941344B6859703163667065356C59584E356158426A5957316C636D4666636E527A6346634D5671442F7065424859585A7062695A4359574A76633246414D6A41784E6B566863336C4559584A33615735555A5746745A57467A65513D3D"
#else //x86 linux
#define KEY_EASYIPCAMERA "6D72754B7A4A4F576B596F41344B6859703163667065356C59584E356158426A5957316C636D4666636E527A6346634D5671442F7065424859585A7062695A4359574A76633246414D6A41784E6B566863336C4559584A33615735555A5746745A57467A65513D3D"
#endif
#define MAX_CHANNELS 16
char* ProgName; //Program Name
char* ConfigIP = "127.0.0.1"; //Default EasyDarwin Address 183.220.236.189
char* ConfigPort= "8554"; //Default EasyDarwin Port121.40.50.44
char* ConfigName= "channel"; //Default RTSP Push StreamName
char* H264FileName = "./channel0.h264";
int OutputCount = 8; //输出流路数
HANDLE g_FileCapThread[MAX_CHANNELS] ;
FILE * fES[MAX_CHANNELS];
typedef struct tagSOURCE_CHANNEL_T
{
int id;
char name[36];
int pushStream;
EASY_MEDIA_INFO_T mediaInfo;
void* anyHandle;
bool bThreadLiving ;
char source_uri[128];
char username[16];
char password[16];
}SOURCE_CHANNEL_T;
//Globle Func for thread callback
unsigned int _stdcall CaptureFileThread(void* lParam);
//1.获取主机ip
bool GetLocalIP(char* ip)
{
if ( !ip )
{
return false;
}
#ifdef _WIN32
//1.初始化wsa
HOSTENT* host;
WSADATA wsaData;
int ret=WSAStartup(MAKEWORD(2,2),&wsaData);
if (ret!=0)
{
return false;
}
#else
struct hostent *host;
#endif
//2.获取主机名
char hostname[256];
ret=gethostname(hostname,sizeof(hostname));
if (ret==-1)
{
return false;
}
host=gethostbyname(hostname);
if (host==0)
{
return false;
}
//4.转化为char*并拷贝返回
strcpy(ip,inet_ntoa(*(in_addr*)*host->h_addr_list));
#ifdef _WIN32
WSACleanup( );
#endif
return true;
}
int GetAvaliblePort(int nPort)
{
#ifdef _WIN32
//1.初始化wsa
HOSTENT* host;
WSADATA wsaData;
int ret=WSAStartup(MAKEWORD(2,2),&wsaData);
if (ret!=0)
{
return -1;
}
#endif
int port = nPort;
int fd = 0;
sockaddr_in addr;
fd = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
#ifdef _WIN32
addr.sin_addr.S_un.S_addr = INADDR_ANY;
#else
inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr);
#endif
while(bind(fd, (sockaddr *)(&addr), sizeof(sockaddr_in)) < 0)
{
printf("port %d has been used.\n", port);
port++;
#ifdef _WIN32
closesocket(fd);
#else
close(fd);
#endif
fd = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
#ifdef _WIN32
addr.sin_addr.S_un.S_addr = INADDR_ANY;
#else
inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr);
#endif
Sleep(1);
}
#ifdef _WIN32
closesocket(fd);
WSACleanup( );
#else
close(fd);
#endif
return port;
}
//IPCameraSdk Callback
Easy_I32 __EasyIPCamera_Callback(Easy_I32 channelId, EASY_IPCAMERA_STATE_T channelState, EASY_MEDIA_INFO_T *_mediaInfo, void *userPtr)
{
SOURCE_CHANNEL_T *pChannel = (SOURCE_CHANNEL_T *)userPtr;
if (channelId < 0) return -1;
if (channelState == EASY_IPCAMERA_STATE_REQUEST_MEDIA_INFO)
{
if (NULL != pChannel[channelId].anyHandle)
{
printf("[channel %d] Get media info...\n", channelId);
memcpy(_mediaInfo, &pChannel[channelId].mediaInfo, sizeof(EASY_MEDIA_INFO_T));
}
}
else if (channelState == EASY_IPCAMERA_STATE_REQUEST_PLAY_STREAM)
{
printf("[channel %d] PlayStream...\n", channelId);
pChannel[channelId].pushStream = 0x01;
}
else if (channelState == EASY_IPCAMERA_STATE_REQUEST_STOP_STREAM)
{
printf("channel[%d] StopStream...\n", channelId);
pChannel[channelId].pushStream = 0x00;
}
return 0;
}
void PrintUsage()
{
printf("Usage:\n");
printf("------------------------------------------------------\n");
printf("%s [-c <outputChannels> -p <port> -n <streamName>]\n", ProgName);
printf("Help Mode: %s -h \n", ProgName );
printf("For example: %s -c 8 -p 8554 -n channel \n", ProgName);
printf("------------------------------------------------------\n");
}
//主函数--------------------------------------------
int main(int argc, char * argv[])
{
int isActivated = 0 ;
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
#endif
#ifdef _WIN32
extern char* optarg;
#endif
int ch;
char szIP[16] = {0};
for(int i=0; i<16; i++)
{
fES[i] = NULL;
}
ProgName = argv[0];
PrintUsage();
while ((ch = getopt(argc,argv, "hc:p:n:")) != EOF)
{
switch(ch)
{
case 'h':
PrintUsage();
return 0;
break;
case 'c':
OutputCount=atoi(optarg);
break;
// case 'f':
// H264FileName = optarg;
// break;
// case 'd':
// ConfigIP =optarg;
// break;
case 'p':
ConfigPort =optarg;
break;
case 'n':
ConfigName =optarg;
break;
case '?':
return 0;
break;
default:
break;
}
}
int activate_ret = EasyIPCamera_Activate(KEY_EASYIPCAMERA);
if (activate_ret < 0)
{
printf("激活libEasyIPCamera失败: %d\n", activate_ret);
printf("Press Enter exit...\n");
getchar();
exit(1);
}
bool bSuc = GetLocalIP(szIP);
if (!bSuc)
{
printf("获取本机IP失败!\n");
printf("Press Enter exit...\n");
getchar();
return 0;
}
int nServerPort = GetAvaliblePort(atoi(ConfigPort));
SOURCE_CHANNEL_T* channels = new SOURCE_CHANNEL_T[OutputCount];
memset(&channels[0], 0x00, sizeof(SOURCE_CHANNEL_T) * OutputCount);
char rtsp_url[128];
char sFileName[256] = {0,};
for (int i=0; i<OutputCount; i++)
{
channels[i].id = i;
sprintf(channels[i].name, "%s%d", ConfigName, i);
sprintf(rtsp_url, "rtsp://%s:%d/%s", szIP, nServerPort, channels[i].name);
strcpy(channels[i].source_uri, rtsp_url);
strcpy(channels[i].username, "admin");
strcpy(channels[i].password, "admin");
memset(&channels[i].mediaInfo, 0x00, sizeof(EASY_MEDIA_INFO_T));
channels[i].mediaInfo.u32VideoCodec = EASY_SDK_VIDEO_CODEC_H264;
channels[i].mediaInfo.u32VideoFps = 25;
//打开h264文件
sprintf(sFileName, "./%s%d.h264", ConfigName, i);
fES[i] = fopen(sFileName, "rb");
if (NULL == fES[i] )
{
printf("打开文件: %s 失败\n", sFileName);
//printf("Press Enter exit...\n");
continue;
}
else
{
channels[i].anyHandle = fES[i];
g_FileCapThread[i] = (HANDLE)_beginthreadex(NULL, 0, CaptureFileThread, (void*)&channels[i],0,0);
channels[i].bThreadLiving = true;
printf("rtspserver output stream url: %s........................\n", rtsp_url);
}
}
LIVE_CHANNEL_INFO_T* liveChannels = new LIVE_CHANNEL_INFO_T[OutputCount];
memset(&liveChannels[0], 0x00, sizeof(LIVE_CHANNEL_INFO_T)*OutputCount);
for (int i=0; i<OutputCount; i++)
{
liveChannels[i].id = channels[i].id;
strcpy(liveChannels[i].name, channels[i].name);
}
EasyIPCamera_Startup(nServerPort, AUTHENTICATION_TYPE_BASIC,"", (unsigned char*)"", (unsigned char*)"", __EasyIPCamera_Callback, (void *)&channels[0], &liveChannels[0], OutputCount);
//EasyIPCamera_Startup(554, NULL, NULL, __EasyIPCamera_Callback, (void *)&channel[0], &liveChannel[0], MAX_CHANNEL_NUM);
// for(int i=0; i<OutputCount; i++)
// {
// sprintf(sFileName, "./%s%d.h264", ConfigName, i);
// fES[i] = fopen(sFileName, "rb");
// if (NULL == fES[i] )
// {
//
// printf("打开文件: %s 失败\n", sFileName);
//printf("Press Enter exit...\n");
// continue;
// }
// else
// {
// channels[i].anyHandle = fES[i];
// g_FileCapThread[i] = (HANDLE)_beginthreadex(NULL, 0, CaptureFileThread, (void*)&channels[i],0,0);
// channels[i].bThreadLiving = true;
// }
// }
printf("Press Enter exit...\n");
getchar();
for(int nI=0; nI<OutputCount; nI++)
{
channels[nI].bThreadLiving = false;
g_FileCapThread[nI] = 0;
}
Sleep(200);
//关闭rtsp server
EasyIPCamera_Shutdown();
for (int nCId = 0; nCId<OutputCount; nCId++)
{
if (NULL != channels[nCId].anyHandle)
{
fclose((FILE*)channels[nCId].anyHandle);
}
}
delete[] channels;
delete[] liveChannels;
return 0;
}
//文件读取线程
unsigned int _stdcall CaptureFileThread(void* lParam)
{
SOURCE_CHANNEL_T* pChannelInfo = (SOURCE_CHANNEL_T*)lParam;
if (!pChannelInfo)
{
return -1;
}
int nChannelId = pChannelInfo->id;
EASY_MEDIA_INFO_T mediainfo;
int buf_size = 1024*512;
char *pbuf = (char *) malloc(buf_size);
int position = 0;
int iFrameNo = 0;
int timestamp = 0;
FILE* fES = (FILE*)pChannelInfo->anyHandle;
// 线程读取文件处理推送 [3/21/2017 dingshuai]
while (pChannelInfo&&pChannelInfo->bThreadLiving)
{
int nReadBytes = fread(pbuf+position, 1, 1, fES);
if (nReadBytes < 1)
{
if (feof(fES))
{
position = 0;
fseek(fES, 0, SEEK_SET);
continue;
}
break;
}
position ++;
if (position > 5)
{
unsigned char naltype = ( (unsigned char)pbuf[position-1] & 0x1F);
if ( (unsigned char)pbuf[position-5]== 0x00 &&
(unsigned char)pbuf[position-4]== 0x00 &&
(unsigned char)pbuf[position-3] == 0x00 &&
(unsigned char)pbuf[position-2] == 0x01 &&
(naltype == 0x07 || naltype == 0x01 ) )
{
int framesize = position - 5;
naltype = (unsigned char)pbuf[4] & 0x1F;
char sps[512] = {0};
char pps[128] = {0};
int spslen = 0, ppslen = 0;
if (naltype == 0x07)//I frame
{
GetH264SPSandPPS(pbuf, framesize, (char*)pChannelInfo->mediaInfo.u8Sps,
(int*)&pChannelInfo->mediaInfo.u32SpsLength, (char*)pChannelInfo->mediaInfo.u8Pps, (int*)&pChannelInfo->mediaInfo.u32PpsLength);
}
if (pChannelInfo->pushStream)
{
EASY_AV_Frame frame;
memset(&frame, 0x00, sizeof(EASY_AV_Frame));
int iOffset = 0;
for (int i=0; i<framesize; i++)
{
unsigned char naltype = ( (unsigned char)pbuf[i+4] & 0x1F);
if ( (unsigned char)pbuf[i+0] == 0x00 && (unsigned char)pbuf[i+1] == 0x00 &&
(unsigned char)pbuf[i+2] == 0x00 && (unsigned char)pbuf[i+3] == 0x01 &&
(naltype==0x05 || naltype==0x01))
//((unsigned char)pBuf[i+4] == 0x65) || ((unsigned char)pBuf[i+4] == 0x61) )
{
iOffset = i;
break;
}
}
frame.pBuffer = (Easy_U8*)(pbuf+iOffset+4);
frame.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;
frame.u32AVFrameLen = framesize-iOffset-4;
frame.u32TimestampSec = 0; //注: 如果实际为ipc编码的流,则此处填写编码时间
frame.u32TimestampUsec = 0; //注: 如果实际为ipc编码的流,则此处填写编码时间
EasyIPCamera_PushFrame(nChannelId, &frame);
}
#ifndef _WIN32
usleep(40*1000);
#else
Sleep(40);
#endif
memmove(pbuf, pbuf+position-5, 5);
position = 5;
iFrameNo ++;
//if (iFrameNo > 100000) break;
//break;
}
}
}
free(pbuf);
return 0;
}
#include "trace.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <windows.h>
void _TRACE(char* szFormat, ...)
{
#ifdef _DEBUG
char buff[1024] = {0,};
va_list args;
va_start(args,szFormat);
#ifdef _WIN32
_vsnprintf(buff, 1023, szFormat,args);
#else
vsnprintf(buff, 1023, szFormat,args);
#endif
va_end(args);
#ifdef _WIN32
OutputDebugString(buff);
#endif
printf("%s", buff);
#endif
}
void _TRACE_LOG(char *szFormat, ...)
{
char buff[1024] = {0,};
va_list args;
va_start(args,szFormat);
#ifdef _WIN32
_vsnprintf(buff, 1023, szFormat,args);
#else
vsnprintf(buff, 1023, szFormat,args);
#endif
va_end(args);
#ifdef _WIN32
OutputDebugString(buff);
#endif
printf("%s", buff);
}
void _TRACE_ERR(char *szFormat, ...)
{
char buff[1024] = {0,};
va_list args;
va_start(args,szFormat);
#ifdef _WIN32
_vsnprintf(buff, 1023, szFormat,args);
#else
vsnprintf(buff, 1023, szFormat,args);
#endif
va_end(args);
#ifdef _WIN32
OutputDebugString(buff);
#endif
printf("%s", buff);
}
#ifndef __TRACE_H__
#define __TRACE_H__
void _TRACE(char *szFormat, ...);
void _TRACE_LOG(char *szFormat, ...);
void _TRACE_ERR(char *szFormat, ...);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册