diff --git a/.travis.yml b/.travis.yml index 08f7ca96..e1e8ad5d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,8 @@ env: + global: + - AVTRANSCODER_BUILD=${TRAVIS_BUILD_DIR}/build + - AVTRANSCODER_INSTALL=${TRAVIS_BUILD_DIR}/install + - J='-j3' matrix: - DEPENDENCY_MODE=libav - DEPENDENCY_MODE=ffmpeg @@ -18,19 +22,27 @@ before_script: - date -u - uname -a - - chmod +x tools/travis.linux.install.deps.sh - - chmod +x tools/travis.osx.install.deps.sh - + - cd ${TRAVIS_BUILD_DIR} + + # install coverage tools + - ./tools/travis.gcc.install.coverage.sh + + # install avtranscoder dependencies - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./tools/travis.linux.install.deps.sh; fi - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./tools/travis.osx.install.deps.sh; fi script: # Build - - mkdir build - - cd build - - cmake .. -DCMAKE_INSTALL_PREFIX=`pwd`/dist - - make install + - mkdir -p ${AVTRANSCODER_BUILD} + - cd ${AVTRANSCODER_BUILD} + - cmake .. -DCMAKE_INSTALL_PREFIX=${AVTRANSCODER_INSTALL} -DCMAKE_BUILD_TYPE=Release -DAVTRANSCODER_PYTHON_VERSION_OF_BINDING=2.7 -DAVTRANSCODER_COVERAGE=True + - make $J install + # Launch tests - - cd .. - - chmod +x tools/travis.python.nosetests.sh - - if [ "${TRAVIS_OS_NAME}" = "linux" && "${DEPENDENCY_MODE}" = "ffmpeg" ]; then ./tools/travis.python.nosetests.sh; fi + - if [ "${DEPENDENCY_MODE}" = "ffmpeg" ]; then ./../tools/travis.python.nosetests.sh; fi + +after_success: + - cd ${TRAVIS_BUILD_DIR} + + # generate coverage for coveralls + - if [ "${CC}" = "gcc" ]; then ./tools/travis.gcc.generate.coverage.sh; fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 851b02de..aecf6b5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(AvTranscoder) # Set AvTranscoder versions set(AVTRANSCODER_VERSION_MAJOR "0") set(AVTRANSCODER_VERSION_MINOR "5") -set(AVTRANSCODER_VERSION_MICRO "5") +set(AVTRANSCODER_VERSION_MICRO "6") set(AVTRANSCODER_VERSION ${AVTRANSCODER_VERSION_MAJOR}.${AVTRANSCODER_VERSION_MINOR}.${AVTRANSCODER_VERSION_MICRO}) # Define AvTranscoder versions @@ -28,6 +28,10 @@ else() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC -O3") endif() +# CPP flag to create code coverage report +if(AVTRANSCODER_COVERAGE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") +endif() add_subdirectory(src) diff --git a/INSTALL.md b/INSTALL.md index 36701279..08858fb3 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -45,6 +45,10 @@ cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install ``` cmake .. -DCMAKE_BUILD_TYPE=Release/Debug ``` +###### To build python binding with a specific python version +``` +cmake .. -DAVTRANSCODER_PYTHON_VERSION_OF_BINDING=2.7 +``` #### Mac OSX using homebrew @@ -52,11 +56,18 @@ cmake .. -DCMAKE_BUILD_TYPE=Release/Debug http://brew.sh/ ###### Install avTranscoder +Last stable version: ``` brew tap cbenhagen/video brew install avtranscoder ``` +From develop branch: +``` +brew tap cbenhagen/video +brew install avtranscoder --devel +``` + ###### Use homebrew to install only dependencies ``` brew deps avtranscoder diff --git a/README.md b/README.md index dca1ec86..aa6bc5cd 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ C++ API for Libav / FFmpeg Based on Libav/FFmpeg libraries to support various video and audio formats, avTranscoder provides the high level API to re-wrap or transcode media easily. +[![Build Status](https://travis-ci.org/avTranscoder/avTranscoder.svg?branch=master)](https://travis-ci.org/avTranscoder/avTranscoder) +[![Coverage Status](https://coveralls.io/repos/avTranscoder/avTranscoder/badge.svg)](https://coveralls.io/r/avTranscoder/avTranscoder) +Coverity Scan Build Status + #### What you need to know * C++ library * Java and Python bindings generated with SWIG @@ -47,20 +51,6 @@ avProfileType=avProfileTypeAudio codec=codecName ``` -#### Continuous Integration - -###### Drone.io -[![Build Status](https://drone.io/github.com/avTranscoder/avTranscoder/status.png)](https://drone.io/github.com/avTranscoder/avTranscoder/latest) - -###### Travis -[![Build Status](https://travis-ci.org/avTranscoder/avTranscoder.svg?branch=master)](https://travis-ci.org/avTranscoder/avTranscoder) - -###### Coverity Scan - - Coverity Scan Build Status - - #### Tests ###### nosetests diff --git a/app/pyThumbnail/pythumbnail.py b/app/pyThumbnail/pythumbnail.py index 7a844a00..afd9148d 100644 --- a/app/pyThumbnail/pythumbnail.py +++ b/app/pyThumbnail/pythumbnail.py @@ -12,7 +12,7 @@ parser.add_argument('inputFileName', help='It could be any media file with at least one video stream (video, image...). Support file without extension.') # options parser.add_argument("-o", "--outputFile", dest="outputFileName", default="thumbnail.jpg", help="Set the output filename (thumbnail.jpg by default). Must be with jpg extension!") -parser.add_argument("-t", "--time", dest="time", type=int, default=0, help="Set time (in seconds) of where to seek in the video stream to generate the thumbnail (0 by default).") +parser.add_argument("-t", "--time", dest="time", type=float, default=0, help="Set time (in seconds) of where to seek in the video stream to generate the thumbnail (0 by default).") parser.add_argument("-f", "--frame", dest="frame", type=int, default=0, help="Set time (in frames) of where to seek in the video stream to generate the thumbnail (0 by default). Warning: priority to frame if user indicates both frame and time!") parser.add_argument("-w", "--width", dest="width", type=int, default=0, help="Override the width of the thumbnail (same as input by default).") parser.add_argument("-he", "--height", dest="height", type=int, default=0, help="Override the height of the thumbnail (same as input by default).") diff --git a/ressource/v_dnxhd175x.prf b/ressource/v_dnxhd175x.prf new file mode 100644 index 00000000..06a4cbc6 --- /dev/null +++ b/ressource/v_dnxhd175x.prf @@ -0,0 +1,10 @@ +avProfileName=dnxhd175x +avProfileLongName=DNxHD 175Mbps 10bits 1920x1080 25fps +avProfileType=avProfileTypeVideo +codec=dnxhd +width=1920 +height=1080 +pix_fmt=yuv422p10le +b=175M +g=1 +r=25 diff --git a/ressource/v_dnxhd36.prf b/ressource/v_dnxhd36.prf new file mode 100644 index 00000000..63e96ea8 --- /dev/null +++ b/ressource/v_dnxhd36.prf @@ -0,0 +1,10 @@ +avProfileName=dnxhd36 +avProfileLongName=DNxHD 36Mbps 8bits 1920x1080 25fps +avProfileType=avProfileTypeVideo +codec=dnxhd +width=1920 +height=1080 +pix_fmt=yuv422p +b=36M +g=1 +r=25 diff --git a/src/AvTranscoder/decoder/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index 44c0f6e2..c6ffc93c 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -70,7 +70,7 @@ bool AudioGenerator::decodeNextFrame( Frame& frameBuffer ) bool AudioGenerator::decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ) { - return false; + return decodeNextFrame( frameBuffer ); } } diff --git a/src/AvTranscoder/file/FormatContext.cpp b/src/AvTranscoder/file/FormatContext.cpp index b90a37d8..bd8de3f9 100644 --- a/src/AvTranscoder/file/FormatContext.cpp +++ b/src/AvTranscoder/file/FormatContext.cpp @@ -6,12 +6,13 @@ namespace avtranscoder { -FormatContext::FormatContext( const std::string& filename, int req_flags ) +FormatContext::FormatContext( const std::string& filename, int req_flags, AVDictionary** options ) : _avFormatContext( NULL ) + , _flags( req_flags ) , _options() , _isOpen( false ) { - int ret = avformat_open_input( &_avFormatContext, filename.c_str(), NULL, NULL ); + int ret = avformat_open_input( &_avFormatContext, filename.c_str(), NULL, options ); if( ret < 0 ) { std::string msg = "unable to open file "; @@ -21,11 +22,16 @@ FormatContext::FormatContext( const std::string& filename, int req_flags ) throw std::ios_base::failure( msg ); } _isOpen = true; + loadOptions( _options, _avFormatContext, req_flags ); + // when demuxing, priv_data of AVFormatContext is set by avformat_open_input() + if( _avFormatContext->iformat->priv_class ) + loadOptions( _options, _avFormatContext->priv_data, req_flags ); } FormatContext::FormatContext( int req_flags ) : _avFormatContext( NULL ) + , _flags( req_flags ) , _options() , _isOpen( false ) { @@ -85,6 +91,9 @@ void FormatContext::writeHeader( AVDictionary** options ) { throw std::runtime_error( "could not write header: " + getDescriptionFromErrorCode( ret ) ); } + // when muxing, priv_data of AVFormatContext is set by avformat_write_header() + if( _avFormatContext->oformat->priv_class ) + loadOptions( _options, _avFormatContext->priv_data, _flags ); } void FormatContext::writeFrame( AVPacket& packet, bool interleaved ) @@ -133,6 +142,17 @@ AVStream& FormatContext::addAVStream( const AVCodec& avCodec ) return *stream; } +void FormatContext::seek( uint64_t position, const int flag ) +{ + if( (int)getStartTime() != AV_NOPTS_VALUE ) + position += getStartTime(); + + if( av_seek_frame( _avFormatContext, -1, position, flag ) < 0 ) + { + LOG_ERROR( "Error when seek at " << position << " (in AV_TIME_BASE units) in file" ) + } +} + std::vector