diff --git a/.gitignore b/.gitignore index 2b20054b..427a1344 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ CMakeFiles Makefile cmake_install.cmake install_manifest.txt + +# Python +*.pyc + diff --git a/app/avProcessor/avProcessor.cpp b/app/avProcessor/avProcessor.cpp index 2236caa6..2c367dcb 100644 --- a/app/avProcessor/avProcessor.cpp +++ b/app/avProcessor/avProcessor.cpp @@ -9,18 +9,6 @@ #include #include -static const size_t dummyWidth = 1920; -static const size_t dummyHeight = 1080; -static const std::string dummyPixelFormat = "yuv420p"; -static const std::string dummyVideoCodec = "mpeg2video"; - -static const size_t dummySampleRate = 48000; -static const size_t dummyChannels = 1; -static const std::string dummySampleFormat = "s16"; -static const std::string dummyAudioCodec = "pcm_s16le"; - -static bool useVideoGenerator = false; - void parseConfigFile(const std::string& configFilename, avtranscoder::Transcoder& transcoder) { std::ifstream configFile(configFilename.c_str(), std::ifstream::in); @@ -41,37 +29,23 @@ void parseConfigFile(const std::string& configFilename, avtranscoder::Transcoder std::stringstream ss(streamId); size_t streamIndex = 0; char separator; - int subStreamIndex = -1; + std::vector channelIndexArray; ss >> streamIndex; ss >> separator; if(separator == '.') + { + int subStreamIndex = -1; ss >> subStreamIndex; + channelIndexArray.push_back(subStreamIndex); + } - // dummy stream, need a ICodec (audio or video) + // generated stream if(!filename.length()) - { - if(useVideoGenerator) - { - // video - avtranscoder::VideoCodec inputCodec(avtranscoder::eCodecTypeEncoder, dummyVideoCodec); - avtranscoder::VideoFrameDesc imageDesc(dummyWidth, dummyHeight, dummyPixelFormat); - inputCodec.setImageParameters(imageDesc); - - transcoder.add(filename, streamIndex, subStreamIndex, transcodeProfile, inputCodec); - } - else - { - // audio - avtranscoder::AudioCodec inputCodec(avtranscoder::eCodecTypeEncoder, dummyAudioCodec); - avtranscoder::AudioFrameDesc audioDesc(dummySampleRate, dummyChannels, dummySampleFormat); - inputCodec.setAudioParameters(audioDesc); - - transcoder.add(filename, streamIndex, subStreamIndex, transcodeProfile, inputCodec); - } - } + transcoder.addGenerateStream(transcodeProfile); else { - transcoder.add(filename, streamIndex, subStreamIndex, transcodeProfile); + avtranscoder::InputStreamDesc inputDesc(filename, streamIndex, channelIndexArray); + transcoder.addStream(inputDesc, transcodeProfile); } } } @@ -93,8 +67,6 @@ int main(int argc, char** argv) help += "\tNo subStreamId: will process of channels of the stream\n"; help += "\tNo profileName: will rewrap the stream\n"; help += "Command line options\n"; - help += "\t--generate-black: stream which not referred to an input, will generate an output video stream with black " - "images (by default generate audio stream with silence)\n"; help += "\t--verbose: set log level to AV_LOG_DEBUG\n"; help += "\t--logFile: put log in 'avtranscoder.log' file\n"; help += "\t--help: display this help\n"; @@ -116,10 +88,6 @@ int main(int argc, char** argv) std::cout << help << std::endl; return 0; } - else if(arguments.at(argument) == "--generate-black") - { - useVideoGenerator = true; - } else if(arguments.at(argument) == "--verbose") { avtranscoder::Logger::setLogLevel(AV_LOG_DEBUG); diff --git a/app/pyProcessor/pyprocessor.py b/app/pyProcessor/pyprocessor.py index e9eaca96..fcbf2c34 100644 --- a/app/pyProcessor/pyprocessor.py +++ b/app/pyProcessor/pyprocessor.py @@ -19,7 +19,8 @@ def parseConfigFile( inputConfigFile, transcoder ): streamIndex = int(streamIndexes) subStreamIndex = -1 - transcoder.add( filename, streamIndex, subStreamIndex, profileName ) + inputDesc = av.InputStreamDesc(filename, streamIndex, subStreamIndex) + transcoder.addStream(inputDesc, profileName) # Create command-line interface @@ -35,7 +36,7 @@ def parseConfigFile( inputConfigFile, transcoder ): args = parser.parse_args() # setup avtranscoder -logger = av.Logger().setLogLevel(av.AV_LOG_QUIET) +av.Logger().setLogLevel(av.AV_LOG_QUIET) av.preloadCodecsAndFormats() # create Transcoder diff --git a/app/pyRewrap/pyrewrap.py b/app/pyRewrap/pyrewrap.py index 101e1d3f..fb3584ac 100644 --- a/app/pyRewrap/pyrewrap.py +++ b/app/pyRewrap/pyrewrap.py @@ -70,7 +70,8 @@ # create transcoder transcoder = av.Transcoder( outputFile ) -transcoder.add( args.inputFileName ) +for streamIndex in range(0, inputFile.getProperties().getNbStreams()): + transcoder.addStream(av.InputStreamDesc(args.inputFileName, streamIndex)) # launch process progress = av.ConsoleProgress() diff --git a/app/pyThumbnail/pythumbnail.py b/app/pyThumbnail/pythumbnail.py index 63121660..36cd6924 100644 --- a/app/pyThumbnail/pythumbnail.py +++ b/app/pyThumbnail/pythumbnail.py @@ -97,7 +97,7 @@ # create transcoder transcoder = av.Transcoder( outputFile ) -transcoder.add( outputStream ) +transcoder.addStream( outputStream ) # launch process outputFile.beginWrap() diff --git a/src/AvTranscoder/data/decoded/AudioFrame.cpp b/src/AvTranscoder/data/decoded/AudioFrame.cpp index 00f9aaaf..baffbbee 100644 --- a/src/AvTranscoder/data/decoded/AudioFrame.cpp +++ b/src/AvTranscoder/data/decoded/AudioFrame.cpp @@ -50,6 +50,13 @@ AudioFrame::AudioFrame(const Frame& otherFrame) { } +std::string AudioFrame::getChannelLayoutDesc() const +{ + char buf[512]; + av_get_channel_layout_string(buf, sizeof(buf), getNbChannels(), getChannelLayout()); + return std::string(buf); +} + size_t AudioFrame::getSize() const { if(getSampleFormat() == AV_SAMPLE_FMT_NONE) diff --git a/src/AvTranscoder/data/decoded/AudioFrame.hpp b/src/AvTranscoder/data/decoded/AudioFrame.hpp index 132d8224..ea644498 100644 --- a/src/AvTranscoder/data/decoded/AudioFrame.hpp +++ b/src/AvTranscoder/data/decoded/AudioFrame.hpp @@ -45,6 +45,7 @@ class AvExport AudioFrame : public Frame size_t getSampleRate() const { return av_frame_get_sample_rate(_frame); } size_t getNbChannels() const { return av_frame_get_channels(_frame); } size_t getChannelLayout() const { return av_frame_get_channel_layout(_frame); } + std::string getChannelLayoutDesc() const; ///< Get a description of a channel layout (example: '5.1'). AVSampleFormat getSampleFormat() const { return static_cast(_frame->format); } size_t getNbSamplesPerChannel() const { return _frame->nb_samples; } AudioFrameDesc desc() const { return AudioFrameDesc(getSampleRate(), getNbChannels(), getSampleFormat()); } diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 38c6e0d4..99d6a8a6 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -116,19 +116,21 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer) return decodeNextFrame; } -bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex) +bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray) { - AudioFrame& audioBuffer = static_cast(frameBuffer); - - // decode all data of the next frame - AudioFrame allDataOfNextFrame(audioBuffer); - if(!decodeNextFrame(allDataOfNextFrame)) - return false; - AVCodecContext& avCodecContext = _inputStream->getAudioCodec().getAVCodecContext(); const size_t srcNbChannels = avCodecContext.channels; const size_t bytePerSample = av_get_bytes_per_sample((AVSampleFormat)frameBuffer.getAVFrame().format); + // if all channels of the stream are extracted + if(srcNbChannels == channelIndexArray.size()) + return decodeNextFrame(frameBuffer); + + // else decode all data in an intermediate buffer + AudioFrame allDataOfNextFrame(frameBuffer); + if(!decodeNextFrame(allDataOfNextFrame)) + return false; + const int dstNbChannels = 1; const int noAlignment = 0; const size_t decodedSize = av_samples_get_buffer_size(NULL, dstNbChannels, frameBuffer.getAVFrame().nb_samples, @@ -136,37 +138,54 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex if(decodedSize == 0) return false; - // check if the expected channel exists - if(channelIndex > srcNbChannels - 1) + // check if each expected channel exists + for(std::vector::const_iterator channelIndex = channelIndexArray.begin(); + channelIndex != channelIndexArray.end(); ++channelIndex) { - std::stringstream msg; - msg << "The channel at index "; - msg << channelIndex; - msg << " doesn't exist (srcNbChannels = "; - msg << srcNbChannels; - msg << ")."; - throw std::runtime_error(msg.str()); + if((*channelIndex) > srcNbChannels - 1) + { + std::stringstream msg; + msg << "The channel at index "; + msg << (*channelIndex); + msg << " doesn't exist (srcNbChannels = "; + msg << srcNbChannels; + msg << ")."; + throw std::runtime_error(msg.str()); + } } // copy frame properties of decoded frame + AudioFrame& audioBuffer = static_cast(frameBuffer); audioBuffer.copyProperties(allDataOfNextFrame); - av_frame_set_channels(&audioBuffer.getAVFrame(), 1); - av_frame_set_channel_layout(&audioBuffer.getAVFrame(), AV_CH_LAYOUT_MONO); + av_frame_set_channels(&audioBuffer.getAVFrame(), channelIndexArray.size()); + av_frame_set_channel_layout(&audioBuffer.getAVFrame(), av_get_default_channel_layout(channelIndexArray.size())); audioBuffer.setNbSamplesPerChannel(allDataOfNextFrame.getNbSamplesPerChannel()); // @todo manage cases with data of frame not only on data[0] (use _frame.linesize) unsigned char* src = allDataOfNextFrame.getData()[0]; unsigned char* dst = audioBuffer.getData()[0]; - // offset - src += channelIndex * bytePerSample; - - // extract one channel - for(int sample = 0; sample < allDataOfNextFrame.getAVFrame().nb_samples; ++sample) + // extract one or more channels + for(size_t sample = 0; sample < allDataOfNextFrame.getNbSamplesPerChannel(); ++sample) { - memcpy(dst, src, bytePerSample); - dst += bytePerSample; - src += bytePerSample * srcNbChannels; + // offset in source buffer + src += channelIndexArray.at(0) * bytePerSample; + + for(size_t i = 0; i < channelIndexArray.size(); ++i) + { + memcpy(dst, src, bytePerSample); + dst += bytePerSample; + + // shift to the corresponding sample in the next channel of the current layout + if(i < channelIndexArray.size() - 1) + src += (channelIndexArray.at(i + 1) - channelIndexArray.at(i)) * bytePerSample; + // else shift to the next layout + else + { + src += (srcNbChannels - channelIndexArray.at(i)) * bytePerSample; + break; + } + } } return true; diff --git a/src/AvTranscoder/decoder/AudioDecoder.hpp b/src/AvTranscoder/decoder/AudioDecoder.hpp index a2a6f2b8..b5e5ac57 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.hpp +++ b/src/AvTranscoder/decoder/AudioDecoder.hpp @@ -17,7 +17,7 @@ class AvExport AudioDecoder : public IDecoder void setupDecoder(const ProfileLoader::Profile& profile = ProfileLoader::Profile()); bool decodeNextFrame(Frame& frameBuffer); - bool decodeNextFrame(Frame& frameBuffer, const size_t channelIndex); + bool decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray); void flushDecoder(); diff --git a/src/AvTranscoder/decoder/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index 297ee009..f13b880f 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -34,7 +34,8 @@ bool AudioGenerator::decodeNextFrame(Frame& frameBuffer) if(frameBuffer.getAVFrame().channel_layout == 0) { const size_t channelLayout = av_get_default_channel_layout(frameBuffer.getAVFrame().channels); - LOG_WARN("Channel layout en the audio frame is not set. Set it to '" << channelLayout << "' to be able to copy silence data.") + LOG_WARN("Channel layout en the audio frame is not set. Set it to '" << channelLayout + << "' to be able to copy silence data.") av_frame_set_channel_layout(&frameBuffer.getAVFrame(), channelLayout); } @@ -71,7 +72,7 @@ bool AudioGenerator::decodeNextFrame(Frame& frameBuffer) return true; } -bool AudioGenerator::decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex) +bool AudioGenerator::decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray) { return decodeNextFrame(frameBuffer); } diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index e12b2eba..ba80ab69 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -19,13 +19,13 @@ class AvExport AudioGenerator : public IDecoder ~AudioGenerator(); bool decodeNextFrame(Frame& frameBuffer); - bool decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex); + bool decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray); void setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; } private: - Frame* _inputFrame; ///< Has link (no ownership) - AudioFrame* _silent; ///< The generated silent (has ownership) + Frame* _inputFrame; ///< Has link (no ownership) + AudioFrame* _silent; ///< The generated silent (has ownership) const AudioFrameDesc _frameDesc; ///< The description of the silence (sampleRate, channels...) }; } diff --git a/src/AvTranscoder/decoder/IDecoder.hpp b/src/AvTranscoder/decoder/IDecoder.hpp index a373a9be..ca28bf15 100644 --- a/src/AvTranscoder/decoder/IDecoder.hpp +++ b/src/AvTranscoder/decoder/IDecoder.hpp @@ -33,10 +33,10 @@ class AvExport IDecoder /** * @brief Decode substream of next frame * @param frameBuffer: the frame decoded - * @param channelIndex: index of channel to extract + * @param channelIndexArray: list of channels to extract * @return status of decoding */ - virtual bool decodeNextFrame(Frame& frameBuffer, const size_t channelIndex) = 0; + virtual bool decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray) = 0; /** * @brief Set the next frame of the input stream (which bypass the work of decoding) diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index bb6002c3..125faf77 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -114,7 +114,7 @@ bool VideoDecoder::decodeNextFrame(Frame& frameBuffer) return decodeNextFrame; } -bool VideoDecoder::decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex) +bool VideoDecoder::decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray) { return false; } diff --git a/src/AvTranscoder/decoder/VideoDecoder.hpp b/src/AvTranscoder/decoder/VideoDecoder.hpp index 69b8419d..3065f484 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.hpp +++ b/src/AvTranscoder/decoder/VideoDecoder.hpp @@ -17,7 +17,7 @@ class AvExport VideoDecoder : public IDecoder void setupDecoder(const ProfileLoader::Profile& profile = ProfileLoader::Profile()); bool decodeNextFrame(Frame& frameBuffer); - bool decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex); + bool decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray); void flushDecoder(); diff --git a/src/AvTranscoder/decoder/VideoGenerator.cpp b/src/AvTranscoder/decoder/VideoGenerator.cpp index 0d35df0e..bdaf645f 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.cpp +++ b/src/AvTranscoder/decoder/VideoGenerator.cpp @@ -72,7 +72,7 @@ bool VideoGenerator::decodeNextFrame(Frame& frameBuffer) return true; } -bool VideoGenerator::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex) +bool VideoGenerator::decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray) { return false; } diff --git a/src/AvTranscoder/decoder/VideoGenerator.hpp b/src/AvTranscoder/decoder/VideoGenerator.hpp index b6a7a556..c9053047 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.hpp +++ b/src/AvTranscoder/decoder/VideoGenerator.hpp @@ -19,13 +19,13 @@ class AvExport VideoGenerator : public IDecoder ~VideoGenerator(); bool decodeNextFrame(Frame& frameBuffer); - bool decodeNextFrame(Frame& frameBuffer, const size_t channelIndex); + bool decodeNextFrame(Frame& frameBuffer, const std::vector channelIndexArray); void setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; } private: - Frame* _inputFrame; ///< A frame given from outside (has link, no ownership) - VideoFrame* _blackImage; ///< The generated black image (has ownership) + Frame* _inputFrame; ///< A frame given from outside (has link, no ownership) + VideoFrame* _blackImage; ///< The generated black image (has ownership) const VideoFrameDesc _frameDesc; ///< The description of the black image (width, height...) }; } diff --git a/src/AvTranscoder/encoder/AudioEncoder.cpp b/src/AvTranscoder/encoder/AudioEncoder.cpp index 0e615466..66fa14e1 100644 --- a/src/AvTranscoder/encoder/AudioEncoder.cpp +++ b/src/AvTranscoder/encoder/AudioEncoder.cpp @@ -139,5 +139,4 @@ bool AudioEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData) return true; #endif } - } diff --git a/src/AvTranscoder/encoder/VideoEncoder.cpp b/src/AvTranscoder/encoder/VideoEncoder.cpp index a4dd7424..fef4ab37 100644 --- a/src/AvTranscoder/encoder/VideoEncoder.cpp +++ b/src/AvTranscoder/encoder/VideoEncoder.cpp @@ -152,5 +152,4 @@ bool VideoEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData) return true; #endif } - } diff --git a/src/AvTranscoder/file/FormatContext.cpp b/src/AvTranscoder/file/FormatContext.cpp index cab0b3d7..efc56bfe 100644 --- a/src/AvTranscoder/file/FormatContext.cpp +++ b/src/AvTranscoder/file/FormatContext.cpp @@ -144,7 +144,7 @@ AVStream& FormatContext::addAVStream(const AVCodec& avCodec) bool FormatContext::seek(const uint64_t position, const int flag) { - LOG_INFO("Seek in '" << _avFormatContext->filename << "' at " << position << " with flag '"<< flag << "'") + LOG_INFO("Seek in '" << _avFormatContext->filename << "' at " << position << " with flag '" << flag << "'") const int err = av_seek_frame(_avFormatContext, -1, position, flag); if(err < 0) { diff --git a/src/AvTranscoder/file/FormatContext.hpp b/src/AvTranscoder/file/FormatContext.hpp index 3257ce2a..7e8cce88 100644 --- a/src/AvTranscoder/file/FormatContext.hpp +++ b/src/AvTranscoder/file/FormatContext.hpp @@ -78,7 +78,8 @@ class AvExport FormatContext * @param position: can be in AV_TIME_BASE units, in frames... depending on the flag value * @param flag: seeking mode (AVSEEK_FLAG_xxx) * @return seek status - * @warn seeking on a raw bitstreams (without any container) could produce an error (because of a lack of timing information) + * @warn seeking on a raw bitstreams (without any container) could produce an error (because of a lack of timing + * information) * @see flushDecoder */ bool seek(const uint64_t position, const int flag); diff --git a/src/AvTranscoder/file/InputFile.cpp b/src/AvTranscoder/file/InputFile.cpp index f2210354..2dbaf379 100644 --- a/src/AvTranscoder/file/InputFile.cpp +++ b/src/AvTranscoder/file/InputFile.cpp @@ -61,7 +61,8 @@ bool InputFile::readNextPacket(CodedData& data, const size_t streamIndex) const int ret = av_read_frame(&_formatContext.getAVFormatContext(), &data.getAVPacket()); if(ret < 0) // error or end of file { - LOG_INFO("Stop reading the next frame of file '" << _filename << "', stream " << streamIndex << " (" << getDescriptionFromErrorCode(ret) << ")") + LOG_INFO("Stop reading the next frame of file '" << _filename << "', stream " << streamIndex << " (" + << getDescriptionFromErrorCode(ret) << ")") return false; } diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index 5a415050..ab838c37 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -319,12 +319,14 @@ void OutputFile::setupRemainingWrappingOptions() void OutputFile::setOutputStream(AVStream& avStream, const ICodec& codec) { // depending on the format, place global headers in extradata instead of every keyframe - if (_formatContext.getAVOutputFormat().flags & AVFMT_GLOBALHEADER) { + if(_formatContext.getAVOutputFormat().flags & AVFMT_GLOBALHEADER) + { avStream.codec->flags |= CODEC_FLAG_GLOBAL_HEADER; } // if the codec is experimental, allow it - if(codec.getAVCodec().capabilities & CODEC_CAP_EXPERIMENTAL) { + if(codec.getAVCodec().capabilities & CODEC_CAP_EXPERIMENTAL) + { LOG_WARN("This codec is considered experimental by libav/ffmpeg:" << codec.getCodecName()); avStream.codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; } @@ -337,5 +339,4 @@ void OutputFile::setOutputStream(AVStream& avStream, const ICodec& codec) memset(((uint8_t*)avStream.codec->extradata) + srcExtradataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE); avStream.codec->extradata_size = codec.getAVCodecContext().extradata_size; } - } diff --git a/src/AvTranscoder/properties/AudioProperties.cpp b/src/AvTranscoder/properties/AudioProperties.cpp index d17cb7a0..5fbb9daf 100644 --- a/src/AvTranscoder/properties/AudioProperties.cpp +++ b/src/AvTranscoder/properties/AudioProperties.cpp @@ -72,7 +72,7 @@ std::string AudioProperties::getChannelLayout() const if(!_codecContext) throw std::runtime_error("unknown codec context"); - char buf1[1024]; + char buf1[512]; av_get_channel_layout_string(buf1, sizeof(buf1), -1, _codecContext->channel_layout); return std::string(buf1); } diff --git a/src/AvTranscoder/properties/AudioProperties.hpp b/src/AvTranscoder/properties/AudioProperties.hpp index 1c8c1834..a82f2462 100644 --- a/src/AvTranscoder/properties/AudioProperties.hpp +++ b/src/AvTranscoder/properties/AudioProperties.hpp @@ -15,14 +15,14 @@ class AvExport AudioProperties : public StreamProperties std::string getSampleFormatName() const; std::string getSampleFormatLongName() const; - std::string getChannelLayout() const; - std::string getChannelName() const; - std::string getChannelDescription() const; + std::string getChannelLayout() const; ///< Get a description of a channel layout (example: '5.1'). + std::string getChannelName() const; ///< Get the name of a given channel (example: 'LFE'). + std::string getChannelDescription() const; ///< Get the description of a given channel (example: 'low frequency'). size_t getBitRate() const; ///< in bits/s, 0 if unknown size_t getSampleRate() const; size_t getNbChannels() const; - size_t getNbSamples() const; + size_t getNbSamples() const; ///< All the channels are included. size_t getTicksPerFrame() const; diff --git a/src/AvTranscoder/properties/FileProperties.cpp b/src/AvTranscoder/properties/FileProperties.cpp index 4fcfd6f6..8d78d23c 100644 --- a/src/AvTranscoder/properties/FileProperties.cpp +++ b/src/AvTranscoder/properties/FileProperties.cpp @@ -31,7 +31,7 @@ FileProperties::FileProperties(const FormatContext& formatContext) void FileProperties::extractStreamProperties(IProgress& progress, const EAnalyseLevel level) { // Returns at the beginning of the stream before any deep analysis - if(level > eAnalyseLevelHeader && ! isRawFormat()) + if(level > eAnalyseLevelHeader && !isRawFormat()) const_cast(_formatContext)->seek(0, AVSEEK_FLAG_BACKWARD); // clear properties @@ -123,7 +123,7 @@ void FileProperties::extractStreamProperties(IProgress& progress, const EAnalyse } // Returns at the beginning of the stream after any deep analysis - if(level > eAnalyseLevelHeader && ! isRawFormat()) + if(level > eAnalyseLevelHeader && !isRawFormat()) const_cast(_formatContext)->seek(0, AVSEEK_FLAG_BACKWARD); } @@ -203,7 +203,7 @@ size_t FileProperties::getBitRate() const size_t FileProperties::getFileSize() const { std::ifstream in(getFilename().c_str(), std::ios::binary | std::ios::ate); - return in.tellg(); + return in.tellg(); } size_t FileProperties::getPacketSize() const diff --git a/src/AvTranscoder/properties/FileProperties.hpp b/src/AvTranscoder/properties/FileProperties.hpp index 4bb9b96f..f873e3f8 100644 --- a/src/AvTranscoder/properties/FileProperties.hpp +++ b/src/AvTranscoder/properties/FileProperties.hpp @@ -40,14 +40,15 @@ class AvExport FileProperties std::string getFilename() const; std::string getFormatName() const; ///< A comma separated list of short names for the format, or empty if unknown. - std::string getFormatLongName() const; ///< Descriptive name for the format, meant to be more human-readable than name, or empty if unknown. + std::string getFormatLongName() + const; ///< Descriptive name for the format, meant to be more human-readable than name, or empty if unknown. bool isRawFormat() const; ///< Is there a container, or a raw bitstreams without access to timing information. std::string getFormatMimeType() const; ///< Comma-separated list of mime types, or empty if unknown. size_t getProgramsCount() const; double getStartTime() const; - float getDuration() const; ///< in seconds, 0 if not available - size_t getBitRate() const; ///< total stream bitrate in bit/s, 0 if not available (result of a computation by ffmpeg) + float getDuration() const; ///< in seconds, 0 if not available + size_t getBitRate() const; ///< total stream bitrate in bit/s, 0 if not available (result of a computation by ffmpeg) size_t getFileSize() const; ///< in bytes size_t getPacketSize() const; diff --git a/src/AvTranscoder/properties/StreamProperties.cpp b/src/AvTranscoder/properties/StreamProperties.cpp index 1c4238bd..6f6fcf02 100644 --- a/src/AvTranscoder/properties/StreamProperties.cpp +++ b/src/AvTranscoder/properties/StreamProperties.cpp @@ -67,7 +67,8 @@ float StreamProperties::getDuration() const const size_t duration = _formatContext->streams[_streamIndex]->duration; if(duration == (size_t)AV_NOPTS_VALUE) { - LOG_WARN("The duration of the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.") + LOG_WARN("The duration of the stream '" << _streamIndex << "' of file '" << _formatContext->filename + << "' is unknown.") return 0; } return av_q2d(timeBase) * duration; diff --git a/src/AvTranscoder/properties/VideoProperties.cpp b/src/AvTranscoder/properties/VideoProperties.cpp index a171b4ae..533742df 100644 --- a/src/AvTranscoder/properties/VideoProperties.cpp +++ b/src/AvTranscoder/properties/VideoProperties.cpp @@ -339,7 +339,7 @@ size_t VideoProperties::getBitRate() const if(!_codecContext->width || !_codecContext->height) throw std::runtime_error("cannot compute bit rate: invalid frame size"); - // discard no frame type when decode + // discard no frame type when decode _codecContext->skip_frame = AVDISCARD_NONE; Frame frame; @@ -421,7 +421,8 @@ size_t VideoProperties::getNbFrames() const size_t nbFrames = _formatContext->streams[_streamIndex]->nb_frames; if(nbFrames == 0) { - LOG_WARN("The number of frames in the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.") + LOG_WARN("The number of frames in the stream '" << _streamIndex << "' of file '" << _formatContext->filename + << "' is unknown.") const float duration = getDuration(); if(duration != 0) { @@ -667,7 +668,7 @@ PropertyVector& VideoProperties::fillVector(PropertyVector& data) const { gop << _gopStructure.at(frameIndex).first; gop << "("; - gop << _gopStructure.at(frameIndex).second;; + gop << _gopStructure.at(frameIndex).second; gop << ")"; gop << " "; } diff --git a/src/AvTranscoder/properties/VideoProperties.hpp b/src/AvTranscoder/properties/VideoProperties.hpp index 6867dec2..ed9d59ec 100644 --- a/src/AvTranscoder/properties/VideoProperties.hpp +++ b/src/AvTranscoder/properties/VideoProperties.hpp @@ -137,8 +137,8 @@ class AvExport VideoProperties : public StreamProperties bool _isInterlaced; bool _isTopFieldFirst; size_t _gopSize; - std::vector > _gopStructure; ///< picture type, encoded frame size in bytes - //@} + std::vector > _gopStructure; ///< picture type, encoded frame size in bytes + //@} /** * @brief GOP timecode of the first frame diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index c950571e..3e40fd16 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -73,7 +73,11 @@ Frame* IReader::readFrameAt(const size_t frame) // decode bool decodingStatus = false; if(_channelIndex != -1) - decodingStatus = _currentDecoder->decodeNextFrame(*_srcFrame, _channelIndex); + { + std::vector channelIndexArray; + channelIndexArray.push_back(_channelIndex); + decodingStatus = _currentDecoder->decodeNextFrame(*_srcFrame, channelIndexArray); + } else decodingStatus = _currentDecoder->decodeNextFrame(*_srcFrame); // if decoding failed diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 696e38d5..e73e3068 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -79,9 +79,9 @@ class AvExport IReader int _channelIndex; private: - int _currentFrame; ///< The current decoded frame. - bool _inputFileAllocated; ///< Does the InputFile is held by the class or not (depends on the constructor called) - bool _continueWithGenerator; ///< If there is no more data to decode, complete with generated data + int _currentFrame; ///< The current decoded frame. + bool _inputFileAllocated; ///< Does the InputFile is held by the class or not (depends on the constructor called) + bool _continueWithGenerator; ///< If there is no more data to decode, complete with generated data }; } diff --git a/src/AvTranscoder/transcoder/InputStreamDesc.cpp b/src/AvTranscoder/transcoder/InputStreamDesc.cpp new file mode 100644 index 00000000..921425cc --- /dev/null +++ b/src/AvTranscoder/transcoder/InputStreamDesc.cpp @@ -0,0 +1,23 @@ +#include "InputStreamDesc.hpp" + +namespace avtranscoder +{ + +std::ostream& operator<<(std::ostream& flux, const InputStreamDesc& inputStreamDesc) +{ + flux << "input stream description: " << std::endl; + flux << "- filename: " << inputStreamDesc._filename << std::endl; + flux << "- stream index: " << inputStreamDesc._streamIndex << std::endl; + if(inputStreamDesc.demultiplexing()) + { + flux << "- channels index: "; + for(size_t c = 0; c < inputStreamDesc._channelIndexArray.size(); ++c) + { + flux << inputStreamDesc._channelIndexArray.at(c) << ", "; + } + flux << std::endl; + } + return flux; +} + +} diff --git a/src/AvTranscoder/transcoder/InputStreamDesc.hpp b/src/AvTranscoder/transcoder/InputStreamDesc.hpp new file mode 100644 index 00000000..f9013880 --- /dev/null +++ b/src/AvTranscoder/transcoder/InputStreamDesc.hpp @@ -0,0 +1,64 @@ +#ifndef _AV_TRANSCODER_INPUT_STREAM_DESC_HPP_ +#define _AV_TRANSCODER_INPUT_STREAM_DESC_HPP_ + +#include + +#include +#include + +namespace avtranscoder +{ + +/** + * @brief Structure to describe the source data to extract. + */ +struct InputStreamDesc +{ + + InputStreamDesc() + : _filename() + , _streamIndex(0) + , _channelIndexArray() + { + } + + InputStreamDesc(const std::string& filename, const size_t streamIndex, const std::vector& channelIndexArray) + : _filename(filename) + , _streamIndex(streamIndex) + , _channelIndexArray(channelIndexArray) + { + } + + InputStreamDesc(const std::string& filename, const size_t streamIndex, const size_t channelIndex) + : _filename(filename) + , _streamIndex(streamIndex) + , _channelIndexArray() + { + _channelIndexArray.push_back(channelIndex); + } + + InputStreamDesc(const std::string& filename, const size_t streamIndex) + : _filename(filename) + , _streamIndex(streamIndex) + , _channelIndexArray() + { + } + + /** + * @return If a demultiplexing step will be done to extract the expected data. + */ + bool demultiplexing() const { return !_channelIndexArray.empty(); } + +public: + std::string _filename; ///< Source file path. + size_t _streamIndex; ///< Source stream to extract. + std::vector _channelIndexArray; ///< List of source channels to extract from the stream +}; + +#ifndef SWIG +AvExport std::ostream& operator<<(std::ostream& flux, const InputStreamDesc& inputStreamDesc); +#endif + +} + +#endif diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index b4777a4d..a6878bc3 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -1,4 +1,3 @@ - #include "StreamTranscoder.hpp" #include @@ -31,7 +30,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu , _outputEncoder(NULL) , _transform(NULL) , _filterGraph(NULL) - , _subStreamIndex(-1) + , _inputStreamDesc() , _offset(offset) , _needToSwitchToGenerator(false) { @@ -121,8 +120,8 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu setOffset(offset); } -StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outputFile, const ProfileLoader::Profile& profile, - const int subStreamIndex, const float offset) +StreamTranscoder::StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInputStream& inputStream, IOutputFile& outputFile, + const ProfileLoader::Profile& profile, const float offset) : _inputStream(&inputStream) , _outputStream(NULL) , _sourceBuffer(NULL) @@ -133,7 +132,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu , _outputEncoder(NULL) , _transform(NULL) , _filterGraph(NULL) - , _subStreamIndex(subStreamIndex) + , _inputStreamDesc(inputStreamDesc) , _offset(offset) , _needToSwitchToGenerator(false) { @@ -191,11 +190,8 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu AudioFrameDesc outputFrameDesc(_inputStream->getAudioCodec().getAudioFrameDesc()); outputFrameDesc.setParameters(profile); - if(subStreamIndex > -1) - { - // @todo manage downmix ? - outputFrameDesc._nbChannels = 1; - } + if(_inputStreamDesc.demultiplexing()) + outputFrameDesc._nbChannels = _inputStreamDesc._channelIndexArray.size(); outputAudio->setupAudioEncoder(outputFrameDesc, profile); // output stream @@ -203,8 +199,8 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu // buffers to process AudioFrameDesc inputFrameDesc(_inputStream->getAudioCodec().getAudioFrameDesc()); - if(subStreamIndex > -1) - inputFrameDesc._nbChannels = 1; + if(_inputStreamDesc.demultiplexing()) + inputFrameDesc._nbChannels = _inputStreamDesc._channelIndexArray.size(); _sourceBuffer = new AudioFrame(inputFrameDesc); _frameBuffer = new AudioFrame(outputAudio->getAudioCodec().getAudioFrameDesc()); @@ -226,7 +222,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu setOffset(offset); } -StreamTranscoder::StreamTranscoder(const ICodec& inputCodec, IOutputFile& outputFile, const ProfileLoader::Profile& profile) +StreamTranscoder::StreamTranscoder(IOutputFile& outputFile, const ProfileLoader::Profile& profile) : _inputStream(NULL) , _outputStream(NULL) , _sourceBuffer(NULL) @@ -237,13 +233,17 @@ StreamTranscoder::StreamTranscoder(const ICodec& inputCodec, IOutputFile& output , _outputEncoder(NULL) , _transform(NULL) , _filterGraph(NULL) - , _subStreamIndex(-1) + , _inputStreamDesc() , _offset(0) , _needToSwitchToGenerator(false) { if(profile.find(constants::avProfileType)->second == constants::avProfileTypeVideo) { - const VideoCodec& inputVideoCodec = static_cast(inputCodec); + VideoCodec inputVideoCodec(eCodecTypeEncoder, profile.find(constants::avProfileCodec)->second); + VideoFrameDesc inputFrameDesc; + inputFrameDesc.setParameters(profile); + inputVideoCodec.setImageParameters(inputFrameDesc); + // generator decoder _generator = new VideoGenerator(inputVideoCodec.getVideoFrameDesc()); _currentDecoder = _generator; @@ -252,7 +252,6 @@ StreamTranscoder::StreamTranscoder(const ICodec& inputCodec, IOutputFile& output _filterGraph = new FilterGraph(inputVideoCodec); // buffers to process - VideoFrameDesc inputFrameDesc = inputVideoCodec.getVideoFrameDesc(); VideoFrameDesc outputFrameDesc = inputFrameDesc; outputFrameDesc.setParameters(profile); _sourceBuffer = new VideoFrame(inputFrameDesc); @@ -271,7 +270,11 @@ StreamTranscoder::StreamTranscoder(const ICodec& inputCodec, IOutputFile& output } else if(profile.find(constants::avProfileType)->second == constants::avProfileTypeAudio) { - const AudioCodec& inputAudioCodec = static_cast(inputCodec); + AudioCodec inputAudioCodec(eCodecTypeEncoder, profile.find(constants::avProfileCodec)->second); + AudioFrameDesc inputFrameDesc; + inputFrameDesc.setParameters(profile); + inputAudioCodec.setAudioParameters(inputFrameDesc); + // generator decoder _generator = new AudioGenerator(inputAudioCodec.getAudioFrameDesc()); _currentDecoder = _generator; @@ -280,7 +283,6 @@ StreamTranscoder::StreamTranscoder(const ICodec& inputCodec, IOutputFile& output _filterGraph = new FilterGraph(inputAudioCodec); // buffers to process - AudioFrameDesc inputFrameDesc = inputAudioCodec.getAudioFrameDesc(); AudioFrameDesc outputFrameDesc = inputFrameDesc; outputFrameDesc.setParameters(profile); _sourceBuffer = new AudioFrame(inputFrameDesc); @@ -407,7 +409,7 @@ bool StreamTranscoder::processFrame() if(getProcessCase() == eProcessCaseRewrap) return processRewrap(); - return processTranscode(_subStreamIndex); + return processTranscode(); } bool StreamTranscoder::processRewrap() @@ -450,7 +452,7 @@ bool StreamTranscoder::processRewrap() return true; } -bool StreamTranscoder::processTranscode(const int subStreamIndex) +bool StreamTranscoder::processTranscode() { assert(_outputStream != NULL); assert(_currentDecoder != NULL); @@ -463,10 +465,10 @@ bool StreamTranscoder::processTranscode(const int subStreamIndex) LOG_DEBUG("Decode next frame") bool decodingStatus = false; - if(subStreamIndex < 0) - decodingStatus = _currentDecoder->decodeNextFrame(*_sourceBuffer); + if(_inputStreamDesc.demultiplexing()) + decodingStatus = _currentDecoder->decodeNextFrame(*_sourceBuffer, _inputStreamDesc._channelIndexArray); else - decodingStatus = _currentDecoder->decodeNextFrame(*_sourceBuffer, subStreamIndex); + decodingStatus = _currentDecoder->decodeNextFrame(*_sourceBuffer); CodedData data; if(decodingStatus) @@ -557,10 +559,9 @@ void StreamTranscoder::needToSwitchToGenerator(const bool needToSwitch) if(needToSwitch && !canSwitchToGenerator()) { std::stringstream os; - LOG_WARN("The stream " << _inputStream->getStreamIndex() << " has a duration of " << getDuration() - << "s. It needs to switch to a generator during the process, but it cannot. " - << "No generator will be used for this stream.") - return; + os << "The stream at index " << _inputStream->getStreamIndex() << " has a duration of " << getDuration() << "s."; + os << " It needs to switch to a generator during the process, but it cannot. "; + throw std::runtime_error(os.str()); } _needToSwitchToGenerator = needToSwitch; } diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.hpp b/src/AvTranscoder/transcoder/StreamTranscoder.hpp index 92c0fdb8..bfc1fad3 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.hpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.hpp @@ -3,6 +3,8 @@ #include +#include + #include #include @@ -26,22 +28,20 @@ class AvExport StreamTranscoder public: /** - * @brief rewrap stream - * @note offset feature when rewrap a stream is not supported + * @brief Rewrap the given stream. **/ StreamTranscoder(IInputStream& inputStream, IOutputFile& outputFile, const float offset = 0); /** - * @brief transcode stream + * @brief Transcode the given stream. **/ - StreamTranscoder(IInputStream& inputStream, IOutputFile& outputFile, const ProfileLoader::Profile& profile, - const int subStreamIndex = -1, const float offset = 0); + StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInputStream& inputStream, IOutputFile& outputFile, + const ProfileLoader::Profile& profile, const float offset = 0); /** - * @brief encode from a generated stream - * @note offset feature has no sense here + * @brief Encode a generated stream **/ - StreamTranscoder(const ICodec& inputCodec, IOutputFile& outputFile, const ProfileLoader::Profile& profile); + StreamTranscoder(IOutputFile& outputFile, const ProfileLoader::Profile& profile); ~StreamTranscoder(); @@ -119,7 +119,7 @@ class AvExport StreamTranscoder private: bool processRewrap(); - bool processTranscode(const int subStreamIndex = -1); ///< By default transcode all channels + bool processTranscode(); private: IInputStream* _inputStream; ///< Input stream to read next packet (has link, no ownership) @@ -137,7 +137,7 @@ class AvExport StreamTranscoder FilterGraph* _filterGraph; ///< Filter graph (has ownership) - int _subStreamIndex; ///< Index of channel that is processed from the input stream (<0 if no demultiplexing). + const InputStreamDesc _inputStreamDesc; ///< Description of the data to extract from the input stream. float _offset; ///< Offset, in seconds, at the beginning of the StreamTranscoder. diff --git a/src/AvTranscoder/transcoder/Transcoder.cpp b/src/AvTranscoder/transcoder/Transcoder.cpp index 5082a84a..f07ef225 100644 --- a/src/AvTranscoder/transcoder/Transcoder.cpp +++ b/src/AvTranscoder/transcoder/Transcoder.cpp @@ -35,187 +35,57 @@ Transcoder::~Transcoder() } } -void Transcoder::add(const std::string& filename) -{ - const int streamIndex = -1; - const float offset = 0; - const InputFile* referenceFile = addInputFile(filename, streamIndex, offset); - const std::vector& inputStreams = referenceFile->getProperties().getStreamProperties(); - for(size_t index = 0; index < inputStreams.size(); ++index) - { - const AVMediaType streamType = referenceFile->getProperties().getStreamPropertiesWithIndex(index).getStreamType(); - // skip the stream if it is not video nor audio - if(streamType == AVMEDIA_TYPE_VIDEO || streamType == AVMEDIA_TYPE_AUDIO) - addRewrapStream(filename, index, offset); - } -} - -void Transcoder::add(const std::string& filename, const size_t streamIndex, const std::string& profileName, - const float offset) -{ - // Re-wrap - if(profileName.length() == 0) - { - // Check filename - if(filename.length() == 0) - throw std::runtime_error("Can't re-wrap a stream without filename indicated"); - - addRewrapStream(filename, streamIndex, offset); - } - // Transcode - else - { - const ProfileLoader::Profile& transcodeProfile = _profileLoader.getProfile(profileName); - add(filename, streamIndex, transcodeProfile, offset); - } -} - -void Transcoder::add(const std::string& filename, const size_t streamIndex, const std::string& profileName, ICodec& codec, - const float offset) -{ - // Re-wrap - if(profileName.length() == 0) - { - // Check filename - if(filename.length() == 0) - throw std::runtime_error("Can't re-wrap a stream without filename indicated"); - - addRewrapStream(filename, streamIndex, offset); - } - // Transcode - else - { - const ProfileLoader::Profile& transcodeProfile = _profileLoader.getProfile(profileName); - add(filename, streamIndex, transcodeProfile, codec, offset); - } -} - -void Transcoder::add(const std::string& filename, const size_t streamIndex, const ProfileLoader::Profile& profile, - const float offset) +void Transcoder::addStream(const InputStreamDesc& inputStreamDesc, const std::string& profileName, const float offset) { // Check filename - if(!filename.length()) - throw std::runtime_error("Can't transcode a stream without filename indicated"); - - addTranscodeStream(filename, streamIndex, -1, profile, offset); -} - -void Transcoder::add(const std::string& filename, const size_t streamIndex, const ProfileLoader::Profile& profile, - ICodec& codec, const float offset) -{ - // Generator - if(!filename.length()) - { - addDummyStream(profile, codec); - } - // Transcode - else - { - addTranscodeStream(filename, streamIndex, -1, profile, offset); - } -} - -void Transcoder::add(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const std::string& profileName, const float offset) -{ - // No subStream selected - if(subStreamIndex < 0) - { - add(filename, streamIndex, profileName, offset); - return; - } + if(inputStreamDesc._filename.length() == 0) + throw std::runtime_error("Can't process a stream without a filename indicated."); if(profileName.length() == 0) { // Re-wrap - if(subStreamIndex < 0) - { - addRewrapStream(filename, streamIndex, offset); - } + if(!inputStreamDesc.demultiplexing()) + addRewrapStream(inputStreamDesc, offset); // Transcode (transparent for the user) else - { - addTranscodeStream(filename, streamIndex, subStreamIndex, offset); - } + addTranscodeStream(inputStreamDesc, offset); } // Transcode else { - const ProfileLoader::Profile& transcodeProfile = _profileLoader.getProfile(profileName); - add(filename, streamIndex, subStreamIndex, transcodeProfile, offset); + const ProfileLoader::Profile& encodingProfile = _profileLoader.getProfile(profileName); + addStream(inputStreamDesc, encodingProfile, offset); } } -void Transcoder::add(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const std::string& profileName, ICodec& codec, const float offset) +void Transcoder::addStream(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile, const float offset) { - // No subStream selected - if(subStreamIndex < 0) - { - add(filename, streamIndex, profileName, codec); - return; - } + // Check filename + if(!inputStreamDesc._filename.length()) + throw std::runtime_error("Can't transcode a stream without a filename indicated."); - // Re-wrap - if(profileName.length() == 0) - { - // Re-wrap - if(subStreamIndex < 0) - { - addRewrapStream(filename, streamIndex, offset); - } - // Transcode (transparent for the user) - else - { - addTranscodeStream(filename, streamIndex, subStreamIndex, offset); - } - } - // Transcode - else - { - const ProfileLoader::Profile& transcodeProfile = _profileLoader.getProfile(profileName); - add(filename, streamIndex, subStreamIndex, transcodeProfile, codec, offset); - } + addTranscodeStream(inputStreamDesc, profile, offset); } -void Transcoder::add(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const ProfileLoader::Profile& profile, const float offset) +void Transcoder::addGenerateStream(const std::string& encodingProfileName) { - // No subStream selected - if(subStreamIndex < 0) - { - add(filename, streamIndex, profile, offset); - return; - } - - // Check filename - if(!filename.length()) - throw std::runtime_error("Can't transcode a stream without filename indicated"); - - addTranscodeStream(filename, streamIndex, subStreamIndex, profile, offset); + const ProfileLoader::Profile& encodingProfile = _profileLoader.getProfile(encodingProfileName); + addGenerateStream(encodingProfile); } -void Transcoder::add(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const ProfileLoader::Profile& profile, ICodec& codec, const float offset) +void Transcoder::addGenerateStream(const ProfileLoader::Profile& encodingProfile) { - // No subStream selected - if(subStreamIndex < 0) - { - add(filename, streamIndex, profile); - return; - } + // Add profile + if(!_profileLoader.hasProfile(encodingProfile)) + _profileLoader.loadProfile(encodingProfile); - // Generator - if(!filename.length()) - { - addDummyStream(profile, codec); - return; - } + LOG_INFO("Add generated stream with encodingProfile=" << encodingProfile.at(constants::avProfileIdentificatorHuman)) - addTranscodeStream(filename, streamIndex, subStreamIndex, profile, offset); + _streamTranscodersAllocated.push_back(new StreamTranscoder(_outputFile, encodingProfile)); + _streamTranscoders.push_back(_streamTranscodersAllocated.back()); } -void Transcoder::add(StreamTranscoder& stream) +void Transcoder::addStream(StreamTranscoder& stream) { _streamTranscoders.push_back(&stream); } @@ -322,52 +192,57 @@ void Transcoder::setProcessMethod(const EProcessMethod eProcessMethod, const siz _outputDuration = outputDuration; } -void Transcoder::addRewrapStream(const std::string& filename, const size_t streamIndex, const float offset) +void Transcoder::addRewrapStream(const InputStreamDesc& inputStreamDesc, const float offset) { - LOG_INFO("Add rewrap stream from file '" << filename << "' / index=" << streamIndex << " / offset=" << offset << "s") + LOG_INFO("Add rewrap stream from " << inputStreamDesc << " with offset=" << offset << "s") - InputFile* referenceFile = addInputFile(filename, streamIndex, offset); + InputFile* referenceFile = addInputFile(inputStreamDesc._filename, inputStreamDesc._streamIndex, offset); - _streamTranscodersAllocated.push_back(new StreamTranscoder(referenceFile->getStream(streamIndex), _outputFile, offset)); + _streamTranscodersAllocated.push_back( + new StreamTranscoder(referenceFile->getStream(inputStreamDesc._streamIndex), _outputFile, offset)); _streamTranscoders.push_back(_streamTranscodersAllocated.back()); } -void Transcoder::addTranscodeStream(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const float offset) +void Transcoder::addTranscodeStream(const InputStreamDesc& inputStreamDesc, const float offset) { // Get profile from input file - InputFile inputFile(filename); - ProfileLoader::Profile profile = getProfileFromFile(inputFile, streamIndex); + InputFile inputFile(inputStreamDesc._filename); + ProfileLoader::Profile profile = getProfileFromFile(inputFile, inputStreamDesc._streamIndex); - // override channels parameter to manage demultiplexing - ProfileLoader::Profile::iterator it = profile.find(constants::avProfileChannel); - if(it != profile.end()) - it->second = "1"; + // override number of channels parameters to manage demultiplexing + if(inputStreamDesc.demultiplexing()) + { + // number of channels + std::stringstream ss; + ss << inputStreamDesc._channelIndexArray.size(); + profile[constants::avProfileChannel] = ss.str(); + } - addTranscodeStream(filename, streamIndex, subStreamIndex, profile, offset); + addTranscodeStream(inputStreamDesc, profile, offset); } -void Transcoder::addTranscodeStream(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const ProfileLoader::Profile& profile, const float offset) +void Transcoder::addTranscodeStream(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile, + const float offset) { // Add profile if(!_profileLoader.hasProfile(profile)) _profileLoader.loadProfile(profile); - LOG_INFO("Add transcode stream from file '" - << filename << "' / index=" << streamIndex << " / channel=" << subStreamIndex - << " / encodingProfile=" << profile.at(constants::avProfileIdentificatorHuman) << " / offset=" << offset << "s") + LOG_INFO("Add transcode stream from " << inputStreamDesc << "with encodingProfile=" + << profile.at(constants::avProfileIdentificatorHuman) << std::endl + << "and offset=" << offset << "s") // Add input file - InputFile* referenceFile = addInputFile(filename, streamIndex, offset); + InputFile* referenceFile = addInputFile(inputStreamDesc._filename, inputStreamDesc._streamIndex, offset); + IInputStream& inputStream = referenceFile->getStream(inputStreamDesc._streamIndex); - switch(referenceFile->getStream(streamIndex).getProperties().getStreamType()) + switch(inputStream.getProperties().getStreamType()) { case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_AUDIO: { _streamTranscodersAllocated.push_back( - new StreamTranscoder(referenceFile->getStream(streamIndex), _outputFile, profile, subStreamIndex, offset)); + new StreamTranscoder(inputStreamDesc, inputStream, _outputFile, profile, offset)); _streamTranscoders.push_back(_streamTranscodersAllocated.back()); break; } @@ -381,19 +256,6 @@ void Transcoder::addTranscodeStream(const std::string& filename, const size_t st } } -void Transcoder::addDummyStream(const ProfileLoader::Profile& profile, const ICodec& codec) -{ - // Add profile - if(!_profileLoader.hasProfile(profile)) - _profileLoader.loadProfile(profile); - - LOG_INFO("Add generated stream with codec '" - << codec.getCodecName() << "' / encodingProfile=" << profile.at(constants::avProfileIdentificatorHuman)) - - _streamTranscodersAllocated.push_back(new StreamTranscoder(codec, _outputFile, profile)); - _streamTranscoders.push_back(_streamTranscodersAllocated.back()); -} - InputFile* Transcoder::addInputFile(const std::string& filename, const int streamIndex, const float offset) { InputFile* referenceFile = NULL; diff --git a/src/AvTranscoder/transcoder/Transcoder.hpp b/src/AvTranscoder/transcoder/Transcoder.hpp index 08f1654b..9c4ee023 100644 --- a/src/AvTranscoder/transcoder/Transcoder.hpp +++ b/src/AvTranscoder/transcoder/Transcoder.hpp @@ -8,7 +8,8 @@ #include #include -#include "StreamTranscoder.hpp" +#include +#include #include #include @@ -53,73 +54,27 @@ class AvExport Transcoder ~Transcoder(); - /** - * @brief Add all streams of the file with the given filename. - * All the streams will be rewrapped. - * @note Currently we rewrap only the video and the audio streams. The streams with an other type are skipped. - */ - void add(const std::string& filename); - - /** - * @brief Add a stream and set a profile - * @note If profileName is empty, rewrap. - * @note offset in seconds - * If offset is positive, the transcoder will generate black images or silence (depending on the type of stream) before - * the stream to process. - * If offset is negative, the transcoder will seek in the stream and start process at this specific time. - */ - void add(const std::string& filename, const size_t streamIndex, const std::string& profileName = "", - const float offset = 0); - /* - * @note If filename is empty, add a generated stream. - * @note If filename is empty, profileName can't be empty (no sens to rewrap a generated stream). - */ - void add(const std::string& filename, const size_t streamIndex, const std::string& profileName, ICodec& codec, - const float offset = 0); - - /** - * @brief Add a stream and set a custom profile - * @note Profile will be updated, be sure to pass unique profile name. - */ - void add(const std::string& filename, const size_t streamIndex, const ProfileLoader::Profile& profile, - const float offset = 0); - /* - * @note If filename is empty, add a generated stream. - */ - void add(const std::string& filename, const size_t streamIndex, const ProfileLoader::Profile& profile, ICodec& codec, - const float offset = 0); + //@{ + // @brief Add a new stream to the output file, created from the given input description to process. + // @param profileName: the encoding profile (rewrap if empty) + // @param offset: in seconds + // If offset is positive, the transcoder will generate black images or silence (depending on the type of stream) before + // the stream to process. + // If offset is negative, the transcoder will seek in the stream and start process at this specific time. + void addStream(const InputStreamDesc& inputStreamDesc, const std::string& profileName = "", const float offset = 0); + void addStream(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile, const float offset = 0); + //@} - /** - * @brief Add a stream and set a profile - * @note If profileName is empty, rewrap. - * @note If subStreamIndex is negative, no substream is selected it's the stream. - */ - void add(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const std::string& profileName = "", const float offset = 0); - /** - * @note If filename is empty, add a generated stream. - * @note If filename is empty, profileName can't be empty (no sens to rewrap a generated stream). - */ - void add(const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName, - ICodec& codec, const float offset = 0); - - /** - * @brief Add a stream and set a custom profile - * @note Profile will be updated, be sure to pass unique profile name. - * @note If subStreamIndex is negative, no substream is selected it's the stream. - */ - void add(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const ProfileLoader::Profile& profile, const float offset = 0); - /** - * @note If filename is empty, add a generated stream. - */ - void add(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const ProfileLoader::Profile& profile, ICodec& codec, const float offset = 0); + //@{ + // @brief Add a new generated stream to the output file, created from the given encoding profile. + void addGenerateStream(const std::string& encodingProfileName); + void addGenerateStream(const ProfileLoader::Profile& encodingProfile); + //@} /** * @brief Add the stream */ - void add(StreamTranscoder& streamTranscoder); + void addStream(StreamTranscoder& streamTranscoder); /** * @brief Initialize all added streams, processing codec latency. @@ -173,14 +128,11 @@ class AvExport Transcoder const double outputDuration = 0); private: - void addRewrapStream(const std::string& filename, const size_t streamIndex, const float offset); - - void addTranscodeStream(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const float offset); - void addTranscodeStream(const std::string& filename, const size_t streamIndex, const int subStreamIndex, - const ProfileLoader::Profile& profile, const float offset = 0); + void addRewrapStream(const InputStreamDesc& inputStreamDesc, const float offset); - void addDummyStream(const ProfileLoader::Profile& profile, const ICodec& codec); + void addTranscodeStream(const InputStreamDesc& inputStreamDesc, const float offset); + void addTranscodeStream(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile, + const float offset = 0); /** * @note If streamIndex is negative, activate all streams of the file. diff --git a/src/AvTranscoder/transcoder/transcoder.i b/src/AvTranscoder/transcoder/transcoder.i index ffb1eedd..229cd227 100644 --- a/src/AvTranscoder/transcoder/transcoder.i +++ b/src/AvTranscoder/transcoder/transcoder.i @@ -1,9 +1,11 @@ %{ +#include #include #include %} %template(StreamTranscoderVector) std::vector< avtranscoder::StreamTranscoder* >; +%include %include %include diff --git a/src/AvTranscoder/transform/AudioTransform.cpp b/src/AvTranscoder/transform/AudioTransform.cpp index 593965ea..41194a06 100644 --- a/src/AvTranscoder/transform/AudioTransform.cpp +++ b/src/AvTranscoder/transform/AudioTransform.cpp @@ -55,8 +55,8 @@ bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame) const AudioFrame& src = static_cast(srcFrame); const AudioFrame& dst = static_cast(dstFrame); - av_opt_set_int(_audioConvertContext, "in_channel_layout", av_get_default_channel_layout(src.getNbChannels()), 0); - av_opt_set_int(_audioConvertContext, "out_channel_layout", av_get_default_channel_layout(dst.getNbChannels()), 0); + av_opt_set_int(_audioConvertContext, "in_channel_layout", src.getChannelLayout(), 0); + av_opt_set_int(_audioConvertContext, "out_channel_layout", dst.getChannelLayout(), 0); av_opt_set_int(_audioConvertContext, "in_sample_rate", src.getSampleRate(), 0); av_opt_set_int(_audioConvertContext, "out_sample_rate", dst.getSampleRate(), 0); SetSampleFormat(_audioConvertContext, "in_sample_fmt", src.getSampleFormat(), 0); @@ -67,8 +67,8 @@ bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame) FreeResampleContext(&_audioConvertContext); std::stringstream msg; msg << "Unable to open audio convert context:" << std::endl; - msg << "in_channel_layout " << av_get_default_channel_layout(src.getNbChannels()) << std::endl; - msg << "out_channel_layout " << av_get_default_channel_layout(dst.getNbChannels()) << std::endl; + msg << "in_channel_layout " << src.getChannelLayoutDesc() << std::endl; + msg << "out_channel_layout " << dst.getChannelLayoutDesc() << std::endl; msg << "in_sample_rate " << src.getSampleRate() << std::endl; msg << "out_sample_rate " << dst.getSampleRate() << std::endl; msg << "in_sample_fmt " << src.getSampleFormat() << std::endl; @@ -80,8 +80,10 @@ bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame) msg << "Audio conversion from " << getSampleFormatName(src.getSampleFormat()) << " to " << getSampleFormatName(dst.getSampleFormat()) << std::endl; msg << "Source, number of channels = " << src.getNbChannels() << std::endl; + msg << "Source, channel layout = " << src.getChannelLayoutDesc() << std::endl; msg << "Source, sample rate = " << src.getSampleRate() << std::endl; msg << "Destination, number of channels = " << dst.getNbChannels() << std::endl; + msg << "Destination, channel layout = " << dst.getChannelLayoutDesc() << std::endl; msg << "Destination, sample rate = " << dst.getSampleRate() << std::endl; LOG_INFO(msg.str()) diff --git a/test/pyTest/testEProcessMethod.py b/test/pyTest/testEProcessMethod.py index 62e4c80a..0f3664b7 100644 --- a/test/pyTest/testEProcessMethod.py +++ b/test/pyTest/testEProcessMethod.py @@ -27,8 +27,8 @@ def testEProcessMethodShortest(): transcoder = av.Transcoder( ouputFile ) transcoder.setProcessMethod( av.eProcessMethodShortest ) - transcoder.add( inputFileName_longest, 0 ) - transcoder.add( inputFileName_shortest, 1 ) + transcoder.addStream( av.InputStreamDesc(inputFileName_longest, 0) ) + transcoder.addStream( av.InputStreamDesc(inputFileName_shortest, 1) ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -57,8 +57,8 @@ def testEProcessMethodLongest(): transcoder = av.Transcoder( ouputFile ) transcoder.setProcessMethod( av.eProcessMethodLongest ) - transcoder.add( inputFileName_longest, 0 ) - transcoder.add( inputFileName_shortest, 0 ) + transcoder.addStream( av.InputStreamDesc(inputFileName_longest, 0) ) + transcoder.addStream( av.InputStreamDesc(inputFileName_shortest, 0) ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -88,9 +88,9 @@ def testEProcessMethodBasedOnStream(): transcoder = av.Transcoder( ouputFile ) transcoder.setProcessMethod( av.eProcessMethodBasedOnStream, 1 ) - transcoder.add( inputFileName_first, 0 ) - transcoder.add( inputFileName_second, 0 ) - transcoder.add( inputFileName_third, 0 ) + transcoder.addStream( av.InputStreamDesc(inputFileName_first, 0) ) + transcoder.addStream( av.InputStreamDesc(inputFileName_second, 0) ) + transcoder.addStream( av.InputStreamDesc(inputFileName_third, 0) ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -121,9 +121,9 @@ def testEProcessMethodBasedOnDuration(): transcoder = av.Transcoder( ouputFile ) transcoder.setProcessMethod( av.eProcessMethodBasedOnDuration, 0, outputDuration ) - transcoder.add( inputFileName_first, 0 ) - transcoder.add( inputFileName_second, 0 ) - transcoder.add( inputFileName_third, 0 ) + transcoder.addStream( av.InputStreamDesc(inputFileName_first, 0) ) + transcoder.addStream( av.InputStreamDesc(inputFileName_second, 0) ) + transcoder.addStream( av.InputStreamDesc(inputFileName_third, 0) ) progress = av.ConsoleProgress() transcoder.process( progress ) diff --git a/test/pyTest/testFilter.py b/test/pyTest/testFilter.py index 8bf84278..5c7e0770 100644 --- a/test/pyTest/testFilter.py +++ b/test/pyTest/testFilter.py @@ -65,7 +65,7 @@ def testVideoTranscodeWithFilter(): customProfile[av.avProfileType] = av.avProfileTypeVideo customProfile[av.avProfileCodec] = "mpeg2video" customProfile[av.avProfilePixelFormat] = "yuv420p" - transcoder.add( inputFileName, videoStreamIndex, customProfile ) + transcoder.addStream( av.InputStreamDesc(inputFileName, videoStreamIndex), customProfile ) # add yadif filter streamTranscoder = transcoder.getStreamTranscoder(0) @@ -104,7 +104,7 @@ def testAudioTranscodeWithFilter(): # transcode the video stream audioStreamIndex = src_audioStream.getStreamIndex() - transcoder.add( inputFileName, audioStreamIndex, "wave24b48kmono" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex), "wave24b48kmono" ) # add volume filter (here +150% of current volume) streamTranscoder = transcoder.getStreamTranscoder(0) diff --git a/test/pyTest/testNbFrames.py b/test/pyTest/testNbFrames.py index 71217cb2..d97e349c 100644 --- a/test/pyTest/testNbFrames.py +++ b/test/pyTest/testNbFrames.py @@ -20,7 +20,7 @@ def testNbFramesVideoRewrap(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0) ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -47,7 +47,7 @@ def testNbFramesVideoTranscode(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "mpeg2" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "mpeg2" ) progress = av.ConsoleProgress() transcoder.process( progress ) diff --git a/test/pyTest/testNbSamples.py b/test/pyTest/testNbSamples.py index d373a884..3dad11b9 100644 --- a/test/pyTest/testNbSamples.py +++ b/test/pyTest/testNbSamples.py @@ -20,7 +20,7 @@ def testNbSamplesAudioRewrap(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0) ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -54,7 +54,7 @@ def testNbSamplesAudioTranscode(): customProfile[av.avProfileType] = av.avProfileTypeAudio customProfile[av.avProfileCodec] = "pcm_s16le" - transcoder.add( inputFileName, 0, customProfile ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), customProfile ) progress = av.ConsoleProgress() transcoder.process( progress ) diff --git a/test/pyTest/testOffset.py b/test/pyTest/testOffset.py index 76bc0a0f..002cc39f 100644 --- a/test/pyTest/testOffset.py +++ b/test/pyTest/testOffset.py @@ -26,7 +26,7 @@ def testTranscodeAudioPositiveOffset(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "wave24b48kmono", offset ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "wave24b48kmono", offset ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -56,7 +56,7 @@ def testTranscodeAudioNegativeOffset(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "wave24b48kmono", offset ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "wave24b48kmono", offset ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -86,7 +86,7 @@ def testRewrapAudioPositiveOffset(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "", offset ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "", offset ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -117,7 +117,7 @@ def testRewrapAudioNegativeOffset(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "", offset ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "", offset ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -150,7 +150,7 @@ def testTranscodeVideoPositiveOffset(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "mpeg2", offset ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "mpeg2", offset ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -180,7 +180,7 @@ def testTranscodeVideoNegativeOffset(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "mpeg2", offset ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "mpeg2", offset ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -210,7 +210,7 @@ def testRewrapVideoPositiveOffset(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "", offset ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "", offset ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -241,7 +241,7 @@ def testRewrapVideoNegativeOffset(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "", offset ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "", offset ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -275,8 +275,8 @@ def testMultipleOffsetFromSameInputFile(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "", offset_1 ) - transcoder.add( inputFileName, 1, "", offset_2 ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "", offset_1 ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 1), "", offset_2 ) progress = av.ConsoleProgress() transcoder.process( progress ) @@ -312,8 +312,8 @@ def testMultipleOffsetFromSameStream(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "", offset_1 ) - transcoder.add( inputFileName, 0, "", offset_2 ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "", offset_1 ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0), "", offset_2 ) progress = av.ConsoleProgress() transcoder.process( progress ) diff --git a/test/pyTest/testProcessStat.py b/test/pyTest/testProcessStat.py index 29831469..d8028d45 100644 --- a/test/pyTest/testProcessStat.py +++ b/test/pyTest/testProcessStat.py @@ -33,7 +33,7 @@ def testProcessWithStatistics(): src_properties = src_inputFile.getProperties() src_videoStream = src_properties.getVideoProperties()[0] videoStreamIndex = src_videoStream.getStreamIndex() - transcoder.add( inputFileName, videoStreamIndex, customProfile ) + transcoder.addStream( av.InputStreamDesc(inputFileName, videoStreamIndex), customProfile ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) diff --git a/test/pyTest/testProperties.py b/test/pyTest/testProperties.py index cf20ea0e..3e29c8b5 100644 --- a/test/pyTest/testProperties.py +++ b/test/pyTest/testProperties.py @@ -21,13 +21,14 @@ def testAddPossibleMetadata(): """ Add metadata 'date' to the outputFile. """ + inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_WAVE_FILE'] outputFileName = "testAddMetadataDate.wav" ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) # rewrap a stream - transcoder.add( os.environ['AVTRANSCODER_TEST_AUDIO_WAVE_FILE'], 0, "") + transcoder.addStream( av.InputStreamDesc(inputFileName, 0) ) # add a set of metadata metadata_to_check = av.PropertyVector() @@ -49,13 +50,14 @@ def testAddImpossibleMetadata(): """ Can't add an impossible metadata to the outputFile. """ + inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_WAVE_FILE'] outputFileName = "testAddMetadataPlop.wav" ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) # rewrap a stream - transcoder.add( os.environ['AVTRANSCODER_TEST_AUDIO_WAVE_FILE'], 0, "") + transcoder.addStream( av.InputStreamDesc(inputFileName, 0) ) # add one metadata metadata_to_check = ("undefinedMetadataKey", "undefinedMetadataValue") diff --git a/test/pyTest/testSetFrame.py b/test/pyTest/testSetFrame.py index b0807d03..18d35df1 100644 --- a/test/pyTest/testSetFrame.py +++ b/test/pyTest/testSetFrame.py @@ -7,19 +7,23 @@ def testSetVideoFrame(): """ Generate a video stream, and set its frame during process. """ - # create output outputFileName = "testSetVideoFrame.mov" ouputFile = av.OutputFile( outputFileName ) - # create video frame and codec - inputVideoCodec = av.VideoCodec( av.eCodecTypeEncoder, "mpeg2video" ); - imageDesc = av.VideoFrameDesc( 1920, 1080, "rgb24" ) - inputVideoCodec.setImageParameters( imageDesc ) + # create custom profile + encodingProfile = av.ProfileMap() + encodingProfile[av.avProfileIdentificator] = "encodingProfile" + encodingProfile[av.avProfileIdentificatorHuman] = "custom profile" + encodingProfile[av.avProfileType] = av.avProfileTypeVideo + encodingProfile[av.avProfileCodec] = "mpeg2video" + encodingProfile[av.avProfilePixelFormat] = "yuv422p" + encodingProfile[av.avProfileWidth] = "1920" + encodingProfile[av.avProfileHeight] = "1080" # create transcoder and add a video stream transcoder = av.Transcoder( ouputFile ) - transcoder.add( "", 0, "mpeg2", inputVideoCodec ) + transcoder.addGenerateStream( encodingProfile ) videoDecoder = transcoder.getStreamTranscoder( 0 ).getCurrentDecoder() # start process @@ -34,7 +38,7 @@ def testSetVideoFrame(): p.progress( i, nbFrames ) # set video frame - frame = av.VideoFrame( imageDesc ) + frame = av.VideoFrame( av.VideoFrameDesc(1920, 1080, "yuv422p") ) frame.assign(i) videoDecoder.setNextFrame( frame ) @@ -59,19 +63,13 @@ def testSetAudioFrame(): """ Generate a audio stream, and set its frame during process. """ - # create output outputFileName = "testSetAudioFrame.wav" ouputFile = av.OutputFile( outputFileName ) - # create video frame and codec - inputAudioCodec = av.AudioCodec( av.eCodecTypeEncoder, "pcm_s24le" ); - audioDesc = av.AudioFrameDesc( 48000, 1, "s32" ) - inputAudioCodec.setAudioParameters( audioDesc ); - # create transcoder and add a video stream transcoder = av.Transcoder( ouputFile ) - transcoder.add( "", 0, "wave24b48kmono", inputAudioCodec ) + transcoder.addGenerateStream( "wave24b48kmono" ) audioDecoder = transcoder.getStreamTranscoder( 0 ).getCurrentDecoder() # start process @@ -86,7 +84,7 @@ def testSetAudioFrame(): p.progress( i, nbFrames ) # set video frame - frame = av.AudioFrame( audioDesc ) + frame = av.AudioFrame( av.AudioFrameDesc(48000, 1, "s32") ) frame.assign(i) audioDecoder.setNextFrame( frame ) @@ -105,4 +103,3 @@ def testSetAudioFrame(): assert_equals( "signed 32 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) assert_equals( 1, dst_audioStream.getNbChannels() ) - diff --git a/test/pyTest/testTranscoderAdd.py b/test/pyTest/testTranscoderAdd.py index 50a2c9ac..2c359aa4 100644 --- a/test/pyTest/testTranscoderAdd.py +++ b/test/pyTest/testTranscoderAdd.py @@ -28,11 +28,10 @@ def testAddStreamTranscoder(): streamTranscoder = av.StreamTranscoder( inputFile.getStream( inputIndex ), ouputFile ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( streamTranscoder) + transcoder.addStream( streamTranscoder) # process - progress = av.NoDisplayProgress() - transcoder.process( progress ) + transcoder.process() @raises(IOError) @@ -48,43 +47,7 @@ def testAddAllStreamsOfFileWhichDoesNotExist(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0) ) # process - progress = av.ConsoleProgress() - transcoder.process( progress ) - - -def testAddAllStreamsOfAGivenFile(): - """ - Add all streams from a given file. - """ - # input - inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_MOV_FILE'] - - # output - outputFileName = "testAddAllStreamsOfAGivenFile.mov" - ouputFile = av.OutputFile( outputFileName ) - - transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName ) - - # process - progress = av.ConsoleProgress() - transcoder.process( progress ) - - # get src file - src_inputFile = av.InputFile( inputFileName ) - src_properties = src_inputFile.getProperties() - src_streams_properties = src_properties.getStreamProperties() - - # get dst file - dst_inputFile = av.InputFile( outputFileName ) - dst_properties = dst_inputFile.getProperties() - dst_streams_properties = dst_properties.getStreamProperties() - - import testTranscoderRewrap - # for each stream - for src_stream, dst_stream in zip(src_streams_properties, dst_streams_properties): - # check properties - testTranscoderRewrap.checkStream(src_stream, dst_stream) + transcoder.process() diff --git a/test/pyTest/testTranscoderDummy.py b/test/pyTest/testTranscoderDummy.py deleted file mode 100644 index f9f7035e..00000000 --- a/test/pyTest/testTranscoderDummy.py +++ /dev/null @@ -1,111 +0,0 @@ -from nose.tools import * - -from pyAvTranscoder import avtranscoder as av - - -@raises(RuntimeError) -def testTranscodeNoStream(): - """ - Can't process with no stream. - """ - outputFileName = "testTranscodeNoStream.avi" - - ouputFile = av.OutputFile( outputFileName ) - transcoder = av.Transcoder( ouputFile ) - - progress = av.NoDisplayProgress() - transcoder.process( progress ) - - -@raises(RuntimeError) -def testRewrapDummy(): - """ - Can't rewrap a dummy stream (no sense). - """ - outputFileName = "testRewrapDummy.avi" - - ouputFile = av.OutputFile( outputFileName ) - transcoder = av.Transcoder( ouputFile ) - - transcoder.add( "", 0, "") - transcoder.add( "", 0, -1, "") - - progress = av.NoDisplayProgress() - transcoder.process( progress ) - -@raises(RuntimeError) -def testTranscodeDummyExistingProfileWithNoEssenceDesc(): - """ - Can't add a dummy stream with no essence desc (for encoder). - """ - outputFileName = "testTranscodeDummyExistingProfileWithNoEssenceDesc.avi" - - ouputFile = av.OutputFile( outputFileName ) - transcoder = av.Transcoder( ouputFile ) - - transcoder.add( "", 0, "dnxhd120" ) - transcoder.add( "", 0, -1, "dnxhd120" ) - - progress = av.NoDisplayProgress() - transcoder.process( progress ) - -@raises(RuntimeError) -def testTranscodeDummyNewProfileWithNoEssenceDesc(): - """ - Can't add a dummy stream with no essence desc (for encoder). - """ - outputFileName = "testTranscodeDummyNewProfileWithNoEssenceDesc.avi" - - ouputFile = av.OutputFile( outputFileName ) - transcoder = av.Transcoder( ouputFile ) - - newProfile = { - av.avProfileIdentificator : "newAudioPreset", - av.avProfileIdentificatorHuman : "New audio preset", - av.avProfileType : av.avProfileTypeAudio, - } - transcoder.add( "", 0, newProfile ) - transcoder.add( "", 0, -1, newProfile ) - - progress = av.NoDisplayProgress() - transcoder.process( progress ) - -def testTranscodeDummyAudio(): - """ - Process one frame with a dummy audio (profile wave24b48kmono). - """ - outputFileName = "testTranscodeDummyAudio.wav" - - ouputFile = av.OutputFile( outputFileName ) - transcoder = av.Transcoder( ouputFile ) - - # add a dummy video stream - audioCodec = av.AudioCodec( av.eCodecTypeEncoder, "pcm_s16le" ) - audioDesc = av.AudioFrameDesc( 48000, 1, "s16" ) - audioCodec.setAudioParameters( audioDesc ) - transcoder.add( "", 0, "wave24b48kmono", audioCodec ) - - ouputFile.beginWrap() - transcoder.processFrame() - ouputFile.endWrap() - -def testTranscodeDummyVideo(): - """ - Process one frame with a dummy video (profile dnxhd120). - """ - outputFileName = "testTranscodeDummyVideo.avi" - - ouputFile = av.OutputFile( outputFileName ) - transcoder = av.Transcoder( ouputFile ) - - # add a dummy video stream - videoCodec = av.VideoCodec( av.eCodecTypeEncoder, "mpeg2video" ) - imageDesc = av.VideoFrameDesc( 1920, 1080, "yuv422p" ) - videoCodec.setImageParameters( imageDesc ) - - transcoder.add( "", 0, "dnxhd120", videoCodec ) - - ouputFile.beginWrap() - transcoder.processFrame() - ouputFile.endWrap() - diff --git a/test/pyTest/testTranscoderGenerateStream.py b/test/pyTest/testTranscoderGenerateStream.py new file mode 100644 index 00000000..9f55f78c --- /dev/null +++ b/test/pyTest/testTranscoderGenerateStream.py @@ -0,0 +1,98 @@ +from nose.tools import * + +from pyAvTranscoder import avtranscoder as av + + +@raises(RuntimeError) +def testTranscodeNoStream(): + """ + Can't process with no stream. + """ + outputFileName = "testTranscodeNoStream.avi" + + ouputFile = av.OutputFile( outputFileName ) + transcoder = av.Transcoder( ouputFile ) + + progress = av.NoDisplayProgress() + transcoder.process( progress ) + + +@raises(RuntimeError) +def testGenerateVideoWithIncompleteProfile(): + """ + Can't generate a video stream without an encoding profile with: + - codec name + - pixel format + - width + - height + """ + outputFileName = "testGenerateVideoWithIncompleteProfile.avi" + + ouputFile = av.OutputFile( outputFileName ) + transcoder = av.Transcoder( ouputFile ) + + encodingProfile = { + av.avProfileIdentificator : "newVideoPreset", + av.avProfileIdentificatorHuman : "New video preset", + av.avProfileType : av.avProfileTypeVideo, + } + transcoder.addGenerateStream( encodingProfile ) + + transcoder.process() + + +@raises(RuntimeError) +def testGenerateAudioWithIncompleteProfile(): + """ + Can't generate an audio stream without an encoding profile with: + - codec name + - sample format + - sample rate + - number of channels + """ + outputFileName = "testGenerateAudioWithIncompleteProfile.wav" + + ouputFile = av.OutputFile( outputFileName ) + transcoder = av.Transcoder( ouputFile ) + + encodingProfile = { + av.avProfileIdentificator : "newAudioPreset", + av.avProfileIdentificatorHuman : "New audio preset", + av.avProfileType : av.avProfileTypeAudio, + } + transcoder.addGenerateStream( encodingProfile ) + + transcoder.process() + +def testTranscodeDummyAudio(): + """ + Process one frame with a dummy audio (profile wave24b48kmono). + """ + outputFileName = "testTranscodeDummyAudio.wav" + + ouputFile = av.OutputFile( outputFileName ) + transcoder = av.Transcoder( ouputFile ) + + # generate an audio stream + transcoder.addGenerateStream( "wave24b48kmono" ) + + ouputFile.beginWrap() + transcoder.processFrame() + ouputFile.endWrap() + +def testTranscodeDummyVideo(): + """ + Process one frame with a dummy video (profile dnxhd120). + """ + outputFileName = "testTranscodeDummyVideo.avi" + + ouputFile = av.OutputFile( outputFileName ) + transcoder = av.Transcoder( ouputFile ) + + # generate a video stream + transcoder.addGenerateStream( "dnxhd120" ) + + ouputFile.beginWrap() + transcoder.processFrame() + ouputFile.endWrap() + diff --git a/test/pyTest/testTranscoderRewrap.py b/test/pyTest/testTranscoderRewrap.py index ea3fa1ba..cd4ae14a 100644 --- a/test/pyTest/testTranscoderRewrap.py +++ b/test/pyTest/testTranscoderRewrap.py @@ -72,9 +72,8 @@ def testRewrapAudioStream(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0 ) - progress = av.NoDisplayProgress() - processStat = transcoder.process( progress ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0) ) + processStat = transcoder.process() # check process stat returned audioStat = processStat.getAudioStat(0) @@ -107,9 +106,8 @@ def testRewrapAVIVideoStream(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0 ) - progress = av.NoDisplayProgress() - processStat = transcoder.process( progress ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0) ) + processStat = transcoder.process() # check process stat returned checkVideoStat(src_videoStream, processStat.getVideoStat(0)) @@ -141,9 +139,8 @@ def testRewrapMOVVideoStream(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 1 ) - progress = av.NoDisplayProgress() - processStat = transcoder.process( progress ) + transcoder.addStream( av.InputStreamDesc(inputFileName, 1) ) + processStat = transcoder.process() # check process stat returned checkVideoStat(src_videoStream, processStat.getVideoStat(0)) @@ -175,9 +172,8 @@ def testRewrapRawVideoStream(): ouputFile = av.OutputFile(outputFileName) transcoder = av.Transcoder(ouputFile) - transcoder.add(inputFileName, 0) - progress = av.NoDisplayProgress() - processStat = transcoder.process(progress) + transcoder.addStream( av.InputStreamDesc(inputFileName, 0) ) + processStat = transcoder.process() # check process stat returned checkVideoStat(src_videoStream, processStat.getVideoStat(0)) diff --git a/test/pyTest/testTranscoderTranscodeAudioMov.py b/test/pyTest/testTranscoderTranscodeAudioMov.py index 114466fc..228d47cb 100644 --- a/test/pyTest/testTranscoderTranscodeAudioMov.py +++ b/test/pyTest/testTranscoderTranscodeAudioMov.py @@ -32,7 +32,7 @@ def testTranscodeMovVariableNbSamplesPerFrame(): inputFile = av.InputFile( inputFileName ) src_audioStream = inputFile.getProperties().getAudioProperties()[0] audioStreamIndex = src_audioStream.getStreamIndex() - transcoder.add( inputFileName, audioStreamIndex, customProfile ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex), customProfile ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -52,7 +52,7 @@ def testTranscodeMovVariableNbSamplesPerFrame(): def testTranscodeMovExtractChannels(): """ Transcode the audio stream of a MOV file which contains a video stream. - Extract channel one and third of the audio stream (5.1). + Extract first and fourth channels of the audio stream (5.1), and create two output streams. The encoding profile will be found from from input. """ inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_MOV_FILE'] @@ -64,8 +64,8 @@ def testTranscodeMovExtractChannels(): inputFile = av.InputFile( inputFileName ) src_audioStream = inputFile.getProperties().getAudioProperties()[0] audioStreamIndex = src_audioStream.getStreamIndex() - transcoder.add( inputFileName, audioStreamIndex, 0 ) - transcoder.add( inputFileName, audioStreamIndex, 3 ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex, 0) ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex, 3) ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -78,3 +78,35 @@ def testTranscodeMovExtractChannels(): dst_inputFile = av.InputFile( outputFileName ) for dst_audioStream in dst_inputFile.getProperties().getAudioProperties(): assert_equals( 1, dst_audioStream.getNbChannels() ) + + +def testTranscodeMovExtractChannelsToOneOutput(): + """ + Transcode the audio stream of a MOV file which contains a video stream. + Extract first, third and last channels of the audio stream (5.1), and create one output streams. + The encoding profile will be found from from input. + """ + inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_MOV_FILE'] + outputFileName = "testTranscodeMovExtractChannelsToOneOutput.mov" + + ouputFile = av.OutputFile( outputFileName ) + transcoder = av.Transcoder( ouputFile ) + + inputFile = av.InputFile( inputFileName ) + src_audioStream = inputFile.getProperties().getAudioProperties()[0] + audioStreamIndex = src_audioStream.getStreamIndex() + audiochannelIndexArray = (0, 3, 5) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex, audiochannelIndexArray) ) + + progress = av.ConsoleProgress() + processStat = transcoder.process( progress ) + + # check process stat returned + audioStat = processStat.getAudioStat(0) + assert_equals(src_audioStream.getDuration(), audioStat.getDuration()) + + # check dst audio streams + dst_inputFile = av.InputFile( outputFileName ) + dst_audioProperties = dst_inputFile.getProperties().getAudioProperties() + assert_equals( 1, len(dst_audioProperties) ) + assert_equals( 3, dst_audioProperties[0].getNbChannels() ) diff --git a/test/pyTest/testTranscoderTranscodeAudioWave.py b/test/pyTest/testTranscoderTranscodeAudioWave.py index 36a44b99..acc1c108 100644 --- a/test/pyTest/testTranscoderTranscodeAudioWave.py +++ b/test/pyTest/testTranscoderTranscodeAudioWave.py @@ -23,7 +23,7 @@ def testTranscodeWave24b48k5_1(): inputFile = av.InputFile( inputFileName ) src_audioStream = inputFile.getProperties().getAudioProperties()[0] audioStreamIndex = src_audioStream.getStreamIndex() - transcoder.add( inputFileName, audioStreamIndex, "wave24b48k5_1" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex), "wave24b48k5_1" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -57,7 +57,7 @@ def testTranscodeWave24b48kstereo(): inputFile = av.InputFile( inputFileName ) src_audioStream = inputFile.getProperties().getAudioProperties()[0] audioStreamIndex = src_audioStream.getStreamIndex() - transcoder.add( inputFileName, audioStreamIndex, "wave24b48kstereo" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex), "wave24b48kstereo" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -91,7 +91,7 @@ def testTranscodeWave24b48kmono(): inputFile = av.InputFile( inputFileName ) src_audioStream = inputFile.getProperties().getAudioProperties()[0] audioStreamIndex = src_audioStream.getStreamIndex() - transcoder.add( inputFileName, audioStreamIndex, "wave24b48kmono" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex), "wave24b48kmono" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -125,7 +125,7 @@ def testTranscodeWave16b48kmono(): inputFile = av.InputFile( inputFileName ) src_audioStream = inputFile.getProperties().getAudioProperties()[0] audioStreamIndex = src_audioStream.getStreamIndex() - transcoder.add( inputFileName, audioStreamIndex, "wave16b48kmono" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex), "wave16b48kmono" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -162,7 +162,7 @@ def testTranscodeWave16b48kmonoWithSilence(): inputFile = av.InputFile( inputFileName ) src_audioStream = inputFile.getProperties().getAudioProperties()[0] audioStreamIndex = src_audioStream.getStreamIndex() - transcoder.add( inputFileName, audioStreamIndex, "wave16b48kmono" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, audioStreamIndex), "wave16b48kmono" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) diff --git a/test/pyTest/testTranscoderTranscodeImage.py b/test/pyTest/testTranscoderTranscodeImage.py index 5e1db9b9..c80080f7 100644 --- a/test/pyTest/testTranscoderTranscodeImage.py +++ b/test/pyTest/testTranscoderTranscodeImage.py @@ -26,7 +26,7 @@ def testTranscodePngToMjpeg(): inputFile = av.InputFile( inputFileName ) src_videoStream = inputFile.getProperties().getVideoProperties()[0] videoStreamIndex = src_videoStream.getStreamIndex() - transcoder.add( inputFileName, videoStreamIndex, "mjpeg" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, videoStreamIndex), "mjpeg" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -57,7 +57,7 @@ def testTranscodeJpgToMjpeg(): inputFile = av.InputFile( inputFileName ) src_videoStream = inputFile.getProperties().getVideoProperties()[0] videoStreamIndex = src_videoStream.getStreamIndex() - transcoder.add( inputFileName, videoStreamIndex, "mjpeg" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, videoStreamIndex), "mjpeg" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) diff --git a/test/pyTest/testTranscoderTranscodeVideo.py b/test/pyTest/testTranscoderTranscodeVideo.py index 8f486f94..1b8f6e95 100644 --- a/test/pyTest/testTranscoderTranscodeVideo.py +++ b/test/pyTest/testTranscoderTranscodeVideo.py @@ -23,7 +23,7 @@ def testTranscodeDnxhd120(): inputFile = av.InputFile( inputFileName ) src_videoStream = inputFile.getProperties().getVideoProperties()[0] videoStreamIndex = src_videoStream.getStreamIndex() - transcoder.add( inputFileName, videoStreamIndex, "dnxhd120" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, videoStreamIndex), "dnxhd120" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -61,7 +61,7 @@ def testTranscodeDnxhd185(): inputFile = av.InputFile( inputFileName ) src_videoStream = inputFile.getProperties().getVideoProperties()[0] videoStreamIndex = src_videoStream.getStreamIndex() - transcoder.add( inputFileName, videoStreamIndex, "dnxhd185" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, videoStreamIndex), "dnxhd185" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -99,7 +99,7 @@ def testTranscodeDnxhd185x(): inputFile = av.InputFile( inputFileName ) src_videoStream = inputFile.getProperties().getVideoProperties()[0] videoStreamIndex = src_videoStream.getStreamIndex() - transcoder.add( inputFileName, videoStreamIndex, "dnxhd185x" ) + transcoder.addStream( av.InputStreamDesc(inputFileName, videoStreamIndex), "dnxhd185x" ) progress = av.ConsoleProgress() processStat = transcoder.process( progress ) @@ -145,7 +145,7 @@ def testTranscodeYUV420(): inputFile = av.InputFile( inputFileName ) src_videoStream = inputFile.getProperties().getVideoProperties()[0] videoStreamIndex = src_videoStream.getStreamIndex() - transcoder.add( inputFileName, videoStreamIndex, customProfile ) + transcoder.addStream( av.InputStreamDesc(inputFileName, videoStreamIndex), customProfile ) progress = av.ConsoleProgress() processStat = transcoder.process( progress )