diff --git a/CMakeLists.txt b/CMakeLists.txt index 574707d86a77b06cee8e523cf691a8ca388bcb3e..eedbcd95e9624c1c1d6383e577403ecb1ab32541 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,7 @@ add_subdirectory( "source/App/EncoderApp" ) add_subdirectory( "source/App/SEIRemovalApp" ) add_subdirectory( "source/App/Parcat" ) add_subdirectory( "source/App/StreamMergeApp" ) +add_subdirectory( "source/App/BitstreamExtractorApp" ) if( EXTENSION_360_VIDEO ) add_subdirectory( "source/App/utils/360ConvertApp" ) endif() diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e760fc59d3211145415d953c59ff55d97a6a6d7 --- /dev/null +++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp @@ -0,0 +1,265 @@ +/* The copyright in this software is being made available under the BSD + * License, included below. This software may be subject to other third party + * and contributor rights, including patent rights, and no such rights are + * granted under this license. + * + * Copyright (c) 2010-2020, ITU/ISO/IEC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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. + */ + +#include <list> +#include <vector> +#include <stdio.h> +#include <fcntl.h> + +#include "CommonLib/CommonDef.h" +#include "BitstreamExtractorApp.h" +#include "DecoderLib/AnnexBread.h" +#include "DecoderLib/NALread.h" +#include "EncoderLib/NALwrite.h" +#include "EncoderLib/VLCWriter.h" +#include "EncoderLib/AnnexBwrite.h" + +BitstreamExtractorApp::BitstreamExtractorApp() +{ +} + +void BitstreamExtractorApp::xPrintVPSInfo (VPS *vps) +{ + msg (VERBOSE, "VPS Info: \n"); + msg (VERBOSE, " VPS ID : %d\n", vps->getVPSId()); + msg (VERBOSE, " Max layers : %d\n", vps->getMaxLayers()); + msg (VERBOSE, " Max sub-layers : %d\n", vps->getMaxSubLayers()); + msg (VERBOSE, " Number of OLS : %d\n", vps->getNumOutputLayerSets()); + for (int olsIdx=0; olsIdx < vps->getNumOutputLayerSets(); olsIdx++) + { + vps->deriveTargetOutputLayerSet(olsIdx); + msg (VERBOSE, " OLS # %d\n", olsIdx); + msg (VERBOSE, " Output layers: "); + for( int i = 0; i < vps->m_targetOutputLayerIdSet.size(); i++ ) + { + msg (VERBOSE, "%d ", vps->m_targetOutputLayerIdSet[i]); + } + msg (VERBOSE, "\n"); + + msg (VERBOSE, " Target layers: "); + for( int i = 0; i < vps->m_targetLayerIdSet.size(); i++ ) + { + msg (VERBOSE, "%d ", vps->m_targetLayerIdSet[i]); + } + msg (VERBOSE, "\n"); + } +} + +void BitstreamExtractorApp::xWriteVPS(VPS *vps, std::ostream& out, int layerId, int temporalId) +{ + // create a new NAL unit for output + OutputNALUnit naluOut (NAL_UNIT_VPS, layerId, temporalId); + CHECK( naluOut.m_temporalId, "The value of TemporalId of VPS NAL units shall be equal to 0" ); + + // write the VPS to the newly created NAL unit buffer + m_hlSyntaxWriter.setBitstream( &naluOut.m_Bitstream ); + m_hlSyntaxWriter.codeVPS( vps ); + + // create a dummy AU + AccessUnit tmpAu; + // convert to EBSP (this adds emulation prevention!) and add into NAL unit + tmpAu.push_back(new NALUnitEBSP(naluOut)); + + // write the dummy AU + // note: The first NAL unit in an access unit will be written with a 4-byte start code + // Parameter sets are also coded with a 4-byte start code, so writing the dummy + // AU works without chaning the start code length. + // This cannot be done for VLC NAL units! + writeAnnexB (out, tmpAu); +} + +void BitstreamExtractorApp::xWriteSPS(SPS *sps, std::ostream& out, int layerId, int temporalId) +{ + // create a new NAL unit for output + OutputNALUnit naluOut (NAL_UNIT_SPS, layerId, temporalId); + CHECK( naluOut.m_temporalId, "The value of TemporalId of SPS NAL units shall be equal to 0" ); + + // write the SPS to the newly created NAL unit buffer + m_hlSyntaxWriter.setBitstream( &naluOut.m_Bitstream ); + m_hlSyntaxWriter.codeSPS( sps ); + + // create a dummy AU + AccessUnit tmpAu; + // convert to EBSP (this adds emulation prevention!) and add into NAL unit + tmpAu.push_back(new NALUnitEBSP(naluOut)); + + // write the dummy AU + // note: The first NAL unit in an access unit will be written with a 4-byte start code + // Parameter sets are also coded with a 4-byte start code, so writing the dummy + // AU works without chaning the start code length. + // This cannot be done for VLC NAL units! + writeAnnexB (out, tmpAu); +} + +void BitstreamExtractorApp::xWritePPS(PPS *pps, std::ostream& out, int layerId, int temporalId) +{ + // create a new NAL unit for output + OutputNALUnit naluOut (NAL_UNIT_PPS, layerId, temporalId); + + // write the PPS to the newly created NAL unit buffer + m_hlSyntaxWriter.setBitstream( &naluOut.m_Bitstream ); + m_hlSyntaxWriter.codePPS( pps ); + + // create a dummy AU + AccessUnit tmpAu; + // convert to EBSP (this adds emulation prevention!) and add into NAL unit + tmpAu.push_back(new NALUnitEBSP(naluOut)); + + // write the dummy AU + // note: The first NAL unit in an access unit will be written with a 4-byte start code + // Parameter sets are also coded with a 4-byte start code, so writing the dummy + // AU works without chaning the start code length. + // This cannot be done for VLC NAL units! + writeAnnexB (out, tmpAu); +} + + +uint32_t BitstreamExtractorApp::decode() +{ + std::ifstream bitstreamFileIn(m_bitstreamFileNameIn.c_str(), std::ifstream::in | std::ifstream::binary); + if (!bitstreamFileIn) + { + EXIT( "failed to open bitstream file " << m_bitstreamFileNameIn.c_str() << " for reading" ) ; + } + + std::ofstream bitstreamFileOut(m_bitstreamFileNameOut.c_str(), std::ifstream::out | std::ifstream::binary); + + InputByteStream bytestream(bitstreamFileIn); + + bitstreamFileIn.clear(); + bitstreamFileIn.seekg( 0, std::ios::beg ); + + int unitCnt = 0; + + while (!!bitstreamFileIn) + { + AnnexBStats stats = AnnexBStats(); + + InputNALUnit nalu; + byteStreamNALUnit(bytestream, nalu.getBitstream().getFifo(), stats); + + // call actual decoding function + if (nalu.getBitstream().getFifo().empty()) + { + /* this can happen if the following occur: + * - empty input file + * - two back-to-back start_code_prefixes + * - start_code_prefix immediately followed by EOF + */ + msg(WARNING, "Warning: Attempt to decode an empty NAL unit" ); + } + else + { + read(nalu); + + bool writeInpuNalUnitToStream = true; + + // filte temporal layers + writeInpuNalUnitToStream &= ( m_maxTemporalLayer < 0 ) || ( nalu.m_temporalId <= m_maxTemporalLayer ); + + if( nalu.m_nalUnitType == NAL_UNIT_VPS ) + { + VPS* vps = new VPS(); + m_hlSynaxReader.setBitstream( &nalu.getBitstream() ); + m_hlSynaxReader.parseVPS( vps ); + m_parameterSetManager.storeVPS( vps, nalu.getBitstream().getFifo() ); + xPrintVPSInfo(vps); + + // example: just write the parsed VPS back to the stream + // *** add modifications here *** + // only write, if not dropped earlier + if (writeInpuNalUnitToStream) + { + xWriteVPS(vps, bitstreamFileOut, nalu.m_nuhLayerId, nalu.m_temporalId); + writeInpuNalUnitToStream = false; + } + } + + if( nalu.m_nalUnitType == NAL_UNIT_SPS ) + { + SPS* sps = new SPS(); + m_hlSynaxReader.setBitstream( &nalu.getBitstream() ); + m_hlSynaxReader.parseSPS( sps ); + m_parameterSetManager.storeSPS( sps, nalu.getBitstream().getFifo() ); + + msg (VERBOSE, "SPS Info: SPS ID = %d\n", sps->getSPSId()); + // example: just write the parsed SPS back to the stream + // *** add modifications here *** + // only write, if not dropped earlier + if (writeInpuNalUnitToStream) + { + xWriteSPS(sps, bitstreamFileOut, nalu.m_nuhLayerId, nalu.m_temporalId); + writeInpuNalUnitToStream = false; + } + } + + if( nalu.m_nalUnitType == NAL_UNIT_PPS ) + { + PPS* pps = new PPS(); + m_hlSynaxReader.setBitstream( &nalu.getBitstream() ); + m_hlSynaxReader.parsePPS( pps ); + m_parameterSetManager.storePPS( pps, nalu.getBitstream().getFifo() ); + msg (VERBOSE, "PPS Info: PPS ID = %d\n", pps->getPPSId()); + + // example: just write the parsed PPS back to the stream + // *** add modifications here *** + // only write, if not dropped earlier + if (writeInpuNalUnitToStream) + { + xWritePPS(pps, bitstreamFileOut, nalu.m_nuhLayerId, nalu.m_temporalId); + writeInpuNalUnitToStream = false; + } + } + + unitCnt++; + + if( writeInpuNalUnitToStream ) + { + int numZeros = stats.m_numLeadingZero8BitsBytes + stats.m_numZeroByteBytes + stats.m_numStartCodePrefixBytes -1; + // write start code + char ch = 0; + for( int i = 0 ; i < numZeros; i++ ) + { + bitstreamFileOut.write( &ch, 1 ); + } + ch = 1; + bitstreamFileOut.write( &ch, 1 ); + // write input NAL unit + bitstreamFileOut.write( (const char*)nalu.getBitstream().getFifo().data(), nalu.getBitstream().getFifo().size() ); + } + } + } + + return 0; +} + diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h new file mode 100644 index 0000000000000000000000000000000000000000..c753c90330122515e53da672c73c03bac20381e0 --- /dev/null +++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h @@ -0,0 +1,74 @@ +/* The copyright in this software is being made available under the BSD + * License, included below. This software may be subject to other third party + * and contributor rights, including patent rights, and no such rights are + * granted under this license. + * + * Copyright (c) 2010-2020, ITU/ISO/IEC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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. + */ + +#ifndef __BITSTREAMEXTRACTORAPP__ +#define __BITSTREAMEXTRACTORAPP__ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include <stdio.h> +#include <fstream> +#include <iostream> + +#include "CommonLib/CommonDef.h" +#include "BitstreamExtractorAppCfg.h" +#include "CommonLib/ParameterSetManager.h" +#include "DecoderLib/NALread.h" +#include "VLCReader.h" +#include "VLCWriter.h" + +class BitstreamExtractorApp : public BitstreamExtractorAppCfg +{ + +public: + BitstreamExtractorApp(); + virtual ~BitstreamExtractorApp () {} + + uint32_t decode (); ///< main decoding function + +protected: + void xPrintVPSInfo (VPS *vps); + + void xWriteVPS(VPS *vps, std::ostream& out, int layerId, int temporalId); + void xWriteSPS(SPS *sps, std::ostream& out, int layerId, int temporalId); + void xWritePPS(PPS *pps, std::ostream& out, int layerId, int temporalId); + + ParameterSetManager m_parameterSetManager; + HLSyntaxReader m_hlSynaxReader; + HLSWriter m_hlSyntaxWriter; +}; + +#endif // __BITSTREAMEXTRACTORAPP__ + diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f0329958730638a756fefcdb95b8448c1b07c60a --- /dev/null +++ b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp @@ -0,0 +1,166 @@ +/* The copyright in this software is being made available under the BSD + * License, included below. This software may be subject to other third party + * and contributor rights, including patent rights, and no such rights are + * granted under this license. + * + * Copyright (c) 2010-2020, ITU/ISO/IEC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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. + */ + + +#include <cstdio> +#include <cstring> +#include <string> +#include "CommonLib/CommonDef.h" +#include "BitstreamExtractorApp.h" +#include "Utilities/program_options_lite.h" +#if ENABLE_TRACING +#include "CommonLib/dtrace_next.h" +#endif + +using namespace std; +namespace po = df::program_options_lite; + + +// ==================================================================================================================== +// Public member functions +// ==================================================================================================================== + +// argc number of arguments +// argv array of arguments + bool BitstreamExtractorAppCfg::parseCfg( int argc, char* argv[] ) +{ +#if ENABLE_TRACING + bool printTracingChannelsList; + std::string tracingFile; + std::string tracingRule; +#endif + + bool printHelp = false; + bool warnUnknownParameter = false; + int verbosity; + + po::Options opts; + opts.addOptions() + + ("help", printHelp, false, "This help text") + ("BitstreamFileIn,b", m_bitstreamFileNameIn, string(""), "Bitstream input file name") + ("BitstreamFileOut,o", m_bitstreamFileNameOut, string(""), "bitstream output file name") + ("MaxTemporalLayer,t", m_maxTemporalLayer, -1, "Maximum Temporal Layer to be decoded. -1 to decode all layers") + ("TargetOutputLayerSet,p", m_targetOlsIdx, -1, "Target output layer set index") + ("SubPicId,p", m_subPicId, -1, "Target subpic ID") + +#if ENABLE_TRACING + ("TraceChannelsList", printTracingChannelsList, false, "List all available tracing channels" ) + ("TraceRule", tracingRule, string( "" ), "Tracing rule (ex: \"D_CABAC:poc==8\" or \"D_REC_CB_LUMA:poc==8\")" ) + ("TraceFile", tracingFile, string( "" ), "Tracing file" ) +#endif + + ("Verbosity,v", verbosity, (int)VERBOSE, "Specifies the level of the verboseness") + ("WarnUnknowParameter,w", warnUnknownParameter, false, "Warn for unknown configuration parameters instead of failing") + ; + + po::setDefaults(opts); + po::ErrorReporter err; + const list<const char*>& argv_unhandled = po::scanArgv(opts, argc, (const char**) argv, err); + + for (list<const char*>::const_iterator it = argv_unhandled.begin(); it != argv_unhandled.end(); it++) + { + std::cerr << "Unhandled argument ignored: "<< *it << std::endl; + } + + if (argc == 1 || printHelp) + { + po::doHelp(cout, opts); + return false; + } + +#if ENABLE_TRACING + g_trace_ctx = tracing_init( tracingFile, tracingRule ); + if( printTracingChannelsList && g_trace_ctx ) + { + std::string channelsList; + g_trace_ctx->getChannelsList( channelsList ); + msg( INFO, "\nAvailable tracing channels:\n\n%s\n", channelsList.c_str() ); + } + DTRACE_UPDATE( g_trace_ctx, std::make_pair( "final", 1 ) ); +#endif + + g_verbosity = MsgLevel( verbosity ); + + if (err.is_errored) + { + if (!warnUnknownParameter) + { + /* errors have already been reported to stderr */ + return false; + } + } + + if (m_targetOlsIdx != -1) + { + std::cerr << "Extraction by target output layer set index is not implemented yet"; + return false; + } + + if (m_subPicId != -1) + { + std::cerr << "Extraction by subpicture ID is not implemented yet"; + return false; + } + + if (m_bitstreamFileNameIn.empty()) + { + std::cerr << "No input file specified, aborting" << std::endl; + return false; + } + if (m_bitstreamFileNameOut.empty()) + { + std::cerr << "No output file specified, aborting" << std::endl; + return false; + } + + + return true; +} + +BitstreamExtractorAppCfg::BitstreamExtractorAppCfg() +: m_bitstreamFileNameIn() +, m_bitstreamFileNameOut() +, m_maxTemporalLayer( -1 ) +, m_targetOlsIdx( -1 ) +, m_subPicId( -1 ) +{ +} + +BitstreamExtractorAppCfg::~BitstreamExtractorAppCfg() +{ +#if ENABLE_TRACING + tracing_uninit( g_trace_ctx ); +#endif +} + diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.h b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.h new file mode 100644 index 0000000000000000000000000000000000000000..adc182862a3e366f7ee1f3c6345b1d4fe92b0f73 --- /dev/null +++ b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.h @@ -0,0 +1,65 @@ +/* The copyright in this software is being made available under the BSD + * License, included below. This software may be subject to other third party + * and contributor rights, including patent rights, and no such rights are + * granted under this license. + * + * Copyright (c) 2010-2020, ITU/ISO/IEC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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. + */ + + +#ifndef __BITSTREAMEXTRACTORAPPCFG__ +#define __BITSTREAMEXTRACTORAPPCFG__ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "CommonLib/CommonDef.h" +#include <vector> + +// Bitstream Extractor configuration class +class BitstreamExtractorAppCfg +{ +protected: + std::string m_bitstreamFileNameIn; // output bitstream file name + std::string m_bitstreamFileNameOut; // input bitstream file name + int m_maxTemporalLayer; + int m_targetOlsIdx; + int m_subPicId; + +public: + BitstreamExtractorAppCfg(); + virtual ~BitstreamExtractorAppCfg(); + + bool parseCfg ( int argc, char* argv[] ); // initialize option class from configuration +}; + + +#endif // __BITSTREAMEXTRACTORAPPCFG__ + + diff --git a/source/App/BitstreamExtractorApp/CMakeLists.txt b/source/App/BitstreamExtractorApp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a299cf5cca769c71f83b9c683bcfae461625ee79 --- /dev/null +++ b/source/App/BitstreamExtractorApp/CMakeLists.txt @@ -0,0 +1,84 @@ +# executable +set( EXE_NAME BitstreamExtractorApp ) + +# get source files +file( GLOB SRC_FILES "*.cpp" ) + +# get include files +file( GLOB INC_FILES "*.h" ) + +# get additional libs for gcc on Ubuntu systems +if( CMAKE_SYSTEM_NAME STREQUAL "Linux" ) + if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" ) + if( USE_ADDRESS_SANITIZER ) + set( ADDITIONAL_LIBS asan ) + endif() + endif() +endif() + +# NATVIS files for Visual Studio +if( MSVC ) + file( GLOB NATVIS_FILES "../../VisualStudio/*.natvis" ) +endif() + +# add executable +add_executable( ${EXE_NAME} ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +if( SET_ENABLE_TRACING ) + if( ENABLE_TRACING ) + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_TRACING=1 ) + else() + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_TRACING=0 ) + endif() +endif() + +if( OpenMP_FOUND ) + if( SET_ENABLE_SPLIT_PARALLELISM ) + if( ENABLE_SPLIT_PARALLELISM ) + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 ) + else() + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 ) + endif() + endif() + if( SET_ENABLE_WPP_PARALLELISM ) + if( ENABLE_WPP_PARALLELISM ) + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 ) + else() + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 ) + endif() + endif() +else() + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 ) + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 ) +endif() + +if( CMAKE_COMPILER_IS_GNUCC AND BUILD_STATIC ) + set( ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -static -static-libgcc -static-libstdc++ ) + target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 ) +endif() + +target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} ) + +# lldb custom data formatters +if( XCODE ) + add_dependencies( ${EXE_NAME} Install${PROJECT_NAME}LldbFiles ) +endif() + +if( CMAKE_SYSTEM_NAME STREQUAL "Linux" ) + add_custom_command( TARGET ${EXE_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy + $<$<CONFIG:Debug>:${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}/BitstreamExtractorApp> + $<$<CONFIG:Release>:${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}/BitstreamExtractorApp> + $<$<CONFIG:RelWithDebInfo>:${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO}/BitstreamExtractorApp> + $<$<CONFIG:MinSizeRel>:${CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL}/BitstreamExtractorApp> + $<$<CONFIG:Debug>:${CMAKE_SOURCE_DIR}/bin/BitstreamExtractorAppStaticd> + $<$<CONFIG:Release>:${CMAKE_SOURCE_DIR}/bin/BitstreamExtractorAppStatic> + $<$<CONFIG:RelWithDebInfo>:${CMAKE_SOURCE_DIR}/bin/BitstreamExtractorAppStaticp> + $<$<CONFIG:MinSizeRel>:${CMAKE_SOURCE_DIR}/bin/BitstreamExtractorAppStaticm> ) +endif() + +# example: place header files in different folders +source_group( "Natvis Files" FILES ${NATVIS_FILES} ) + +# set the folder where to place the projects +set_target_properties( ${EXE_NAME} PROPERTIES FOLDER app LINKER_LANGUAGE CXX ) diff --git a/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp b/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e57f05d414d2133702f2cf367d50a37d4b88857d --- /dev/null +++ b/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp @@ -0,0 +1,112 @@ +/* The copyright in this software is being made available under the BSD + * License, included below. This software may be subject to other third party + * and contributor rights, including patent rights, and no such rights are + * granted under this license. + * + * Copyright (c) 2010-2020, ITU/ISO/IEC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include "CommonLib/CommonDef.h" +#include "BitstreamExtractorApp.h" +#include "program_options_lite.h" + +// ==================================================================================================================== +// Main function +// ==================================================================================================================== + +int main(int argc, char* argv[]) +{ + int returnCode = EXIT_SUCCESS; + + // print information + fprintf( stdout, "\n" ); + fprintf( stdout, "VVCSoftware: VTM Bitstream Extractor Version %s ", VTM_VERSION ); + fprintf( stdout, NVM_ONOS ); + fprintf( stdout, NVM_COMPILEDBY ); + fprintf( stdout, NVM_BITS ); +#if ENABLE_SIMD_OPT + std::string SIMD; + df::program_options_lite::Options optsSimd; + optsSimd.addOptions()( "SIMD", SIMD, std::string( "" ), "" ); + df::program_options_lite::SilentReporter err; + df::program_options_lite::scanArgv( optsSimd, argc, ( const char** ) argv, err ); + fprintf( stdout, "[SIMD=%s] ", read_x86_extension( SIMD ) ); +#endif +#if ENABLE_TRACING + fprintf( stdout, "[ENABLE_TRACING] " ); +#endif + fprintf( stdout, "\n" ); + + BitstreamExtractorApp *extractorApp = new BitstreamExtractorApp; + // parse configuration + if(!extractorApp->parseCfg( argc, argv )) + { + returnCode = EXIT_FAILURE; + return returnCode; + } + + // starting time + double timeDifference; + clock_t startTime = clock(); + + // call decoding function +#ifndef _DEBUG + try + { +#endif // !_DEBUG + if( 0 != extractorApp->decode() ) + { + printf( "\n\n***ERROR*** A decoding mismatch occured: signalled md5sum does not match\n" ); + returnCode = EXIT_FAILURE; + } +#ifndef _DEBUG + } + catch( Exception &e ) + { + std::cerr << e.what() << std::endl; + returnCode = EXIT_FAILURE; + } + catch( ... ) + { + std::cerr << "Unspecified error occurred" << std::endl; + returnCode = EXIT_FAILURE; + } +#endif + + // ending time + timeDifference = (double)(clock()-startTime) / CLOCKS_PER_SEC; + printf("\n Total Time: %12.3f sec.\n", timeDifference); + + delete extractorApp; + + return returnCode; +} +