From 3c5acc55273e273f56fac43d94eb92e5c4c567a5 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Wed, 23 Nov 2016 15:54:15 +0100 Subject: [PATCH 1/2] rename header define --- src/AvTranscoder/properties/JsonWriter.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/properties/JsonWriter.hpp b/src/AvTranscoder/properties/JsonWriter.hpp index ab809326..0e24a238 100644 --- a/src/AvTranscoder/properties/JsonWriter.hpp +++ b/src/AvTranscoder/properties/JsonWriter.hpp @@ -1,5 +1,5 @@ -#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_JSONWRITER_HPP_ -#define _AV_TRANSCODER_MEDIA_PROPERTY_JSONWRITER_HPP_ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_JSON_WRITER_HPP_ +#define _AV_TRANSCODER_MEDIA_PROPERTY_JSON_WRITER_HPP_ #include From 14920f9f7af73cde4b1936020207ae717bc22bd8 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Wed, 23 Nov 2016 16:24:36 +0100 Subject: [PATCH 2/2] update output Json structure to return typed values --- src/AvTranscoder/file/OutputFile.cpp | 2 +- .../properties/AudioProperties.cpp | 20 +-- .../properties/AudioProperties.hpp | 16 -- .../properties/FileProperties.cpp | 33 ++-- .../properties/FileProperties.hpp | 16 -- .../properties/PixelProperties.cpp | 30 ++-- .../properties/PixelProperties.hpp | 15 -- src/AvTranscoder/properties/PropertyValue.cpp | 146 ++++++++++++++++++ src/AvTranscoder/properties/PropertyValue.hpp | 53 +++++++ .../properties/StreamProperties.cpp | 23 ++- .../properties/StreamProperties.hpp | 16 -- .../properties/VideoProperties.cpp | 52 +++---- .../properties/VideoProperties.hpp | 15 -- .../properties/jsonWriterHelper.cpp | 63 ++++++++ .../properties/jsonWriterHelper.hpp | 16 ++ src/AvTranscoder/properties/util.cpp | 35 +++-- src/AvTranscoder/properties/util.hpp | 31 +++- 17 files changed, 404 insertions(+), 178 deletions(-) create mode 100644 src/AvTranscoder/properties/PropertyValue.cpp create mode 100644 src/AvTranscoder/properties/PropertyValue.hpp create mode 100644 src/AvTranscoder/properties/jsonWriterHelper.cpp create mode 100644 src/AvTranscoder/properties/jsonWriterHelper.hpp diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index 72042db5..2f00f4c4 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -242,7 +242,7 @@ void OutputFile::addMetadata(const PropertyVector& data) { for(PropertyVector::const_iterator it = data.begin(); it != data.end(); ++it) { - addMetadata(it->first, it->second); + addMetadata(it->first, it->second.asString()); } } diff --git a/src/AvTranscoder/properties/AudioProperties.cpp b/src/AvTranscoder/properties/AudioProperties.cpp index 2ec52828..028e8ac9 100644 --- a/src/AvTranscoder/properties/AudioProperties.cpp +++ b/src/AvTranscoder/properties/AudioProperties.cpp @@ -158,16 +158,16 @@ PropertyVector& AudioProperties::fillVector(PropertyVector& data) const StreamProperties::fillVector(basedProperty); data.insert(data.begin(), basedProperty.begin(), basedProperty.end()); - addProperty(data, "sampleFormatName", &AudioProperties::getSampleFormatName); - addProperty(data, "sampleFormatLongName", &AudioProperties::getSampleFormatLongName); - addProperty(data, "bitRate", &AudioProperties::getBitRate); - addProperty(data, "sampleRate", &AudioProperties::getSampleRate); - addProperty(data, "nbSamples", &AudioProperties::getNbSamples); - addProperty(data, "nbChannels", &AudioProperties::getNbChannels); - addProperty(data, "channelLayout", &AudioProperties::getChannelLayout); - addProperty(data, "channelName", &AudioProperties::getChannelName); - addProperty(data, "channelDescription", &AudioProperties::getChannelDescription); - addProperty(data, "ticksPerFrame", &AudioProperties::getTicksPerFrame); + detail::addProperty(data, "sampleFormatName", this, &AudioProperties::getSampleFormatName); + detail::addProperty(data, "sampleFormatLongName", this, &AudioProperties::getSampleFormatLongName); + detail::addProperty(data, "bitRate", this, &AudioProperties::getBitRate); + detail::addProperty(data, "sampleRate", this, &AudioProperties::getSampleRate); + detail::addProperty(data, "nbSamples", this, &AudioProperties::getNbSamples); + detail::addProperty(data, "nbChannels", this, &AudioProperties::getNbChannels); + detail::addProperty(data, "channelLayout", this, &AudioProperties::getChannelLayout); + detail::addProperty(data, "channelName", this, &AudioProperties::getChannelName); + detail::addProperty(data, "channelDescription", this, &AudioProperties::getChannelDescription); + detail::addProperty(data, "ticksPerFrame", this, &AudioProperties::getTicksPerFrame); return data; } diff --git a/src/AvTranscoder/properties/AudioProperties.hpp b/src/AvTranscoder/properties/AudioProperties.hpp index a82f2462..61875cc4 100644 --- a/src/AvTranscoder/properties/AudioProperties.hpp +++ b/src/AvTranscoder/properties/AudioProperties.hpp @@ -31,22 +31,6 @@ class AvExport AudioProperties : public StreamProperties #endif PropertyVector& fillVector(PropertyVector& data) const; - -private: -#ifndef SWIG - template - void addProperty(PropertyVector& data, const std::string& key, T (AudioProperties::*getter)(void) const) const - { - try - { - detail::add(data, key, (this->*getter)()); - } - catch(const std::exception& e) - { - detail::add(data, key, detail::propertyValueIfError); - } - } -#endif }; #ifndef SWIG diff --git a/src/AvTranscoder/properties/FileProperties.cpp b/src/AvTranscoder/properties/FileProperties.cpp index 8cabd289..fe1aefaf 100644 --- a/src/AvTranscoder/properties/FileProperties.cpp +++ b/src/AvTranscoder/properties/FileProperties.cpp @@ -2,11 +2,13 @@ #include #include +#include #include #include #include #include +#include namespace avtranscoder { @@ -259,19 +261,19 @@ PropertyVector FileProperties::asVector() const PropertyVector& FileProperties::fillVector(PropertyVector& data) const { - addProperty(data, "filename", &FileProperties::getFilename); - addProperty(data, "formatName", &FileProperties::getFormatName); - addProperty(data, "formatLongName", &FileProperties::getFormatLongName); - addProperty(data, "mimeType", &FileProperties::getFormatMimeType); - addProperty(data, "rawFormat", &FileProperties::isRawFormat); - - addProperty(data, "startTime", &FileProperties::getStartTime); - addProperty(data, "duration", &FileProperties::getDuration); - addProperty(data, "bitrate", &FileProperties::getBitRate); - addProperty(data, "fileSize", &FileProperties::getFileSize); - addProperty(data, "packetSize", &FileProperties::getPacketSize); - addProperty(data, "numberOfStreams", &FileProperties::getNbStreams); - addProperty(data, "numberOfPrograms", &FileProperties::getProgramsCount); + detail::addProperty(data, "filename", this, &FileProperties::getFilename); + detail::addProperty(data, "formatName", this, &FileProperties::getFormatName); + detail::addProperty(data, "formatLongName", this, &FileProperties::getFormatLongName); + detail::addProperty(data, "mimeType", this, &FileProperties::getFormatMimeType); + detail::addProperty(data, "rawFormat", this, &FileProperties::isRawFormat); + + detail::addProperty(data, "startTime", this, &FileProperties::getStartTime); + detail::addProperty(data, "duration", this, &FileProperties::getDuration); + detail::addProperty(data, "bitrate", this, &FileProperties::getBitRate); + detail::addProperty(data, "fileSize", this, &FileProperties::getFileSize); + detail::addProperty(data, "packetSize", this, &FileProperties::getPacketSize); + detail::addProperty(data, "numberOfStreams", this, &FileProperties::getNbStreams); + detail::addProperty(data, "numberOfPrograms", this, &FileProperties::getProgramsCount); detail::add(data, "numberOfVideoStreams", getNbVideoStreams()); detail::add(data, "numberOfAudioStreams", getNbAudioStreams()); @@ -303,11 +305,8 @@ PropertyMap FileProperties::asMap() const std::string FileProperties::asJson() const { - json::JsonObjectStreamWriter writer; PropertyMap properties = asMap(); - for(PropertyMap::iterator it = properties.begin(); it != properties.end(); ++it) - writer << std::make_pair(it->first.c_str(), it->second.c_str()); - return writer.build(); + return json::build(properties); } std::string FileProperties::allPropertiesAsJson() const diff --git a/src/AvTranscoder/properties/FileProperties.hpp b/src/AvTranscoder/properties/FileProperties.hpp index 780eb64f..27831284 100644 --- a/src/AvTranscoder/properties/FileProperties.hpp +++ b/src/AvTranscoder/properties/FileProperties.hpp @@ -91,22 +91,6 @@ class AvExport FileProperties PropertyVector asVector() const; ///< Return format properties as a vector (name of property: value) PropertyVector& fillVector(PropertyVector& data) const; ///< To avoid copy of the vector -private: -#ifndef SWIG - template - void addProperty(PropertyVector& data, const std::string& key, T (FileProperties::*getter)(void) const) const - { - try - { - detail::add(data, key, (this->*getter)()); - } - catch(const std::exception& e) - { - detail::add(data, key, detail::propertyValueIfError); - } - } -#endif - private: const InputFile& _file; ///< Has link (no ownership) const FormatContext* _formatContext; ///< Has link (no ownership) diff --git a/src/AvTranscoder/properties/PixelProperties.cpp b/src/AvTranscoder/properties/PixelProperties.cpp index 2d761e01..16de1157 100644 --- a/src/AvTranscoder/properties/PixelProperties.cpp +++ b/src/AvTranscoder/properties/PixelProperties.cpp @@ -241,13 +241,13 @@ PropertyVector PixelProperties::asVector() const PropertyVector& PixelProperties::fillVector(PropertyVector& data) const { - addProperty(data, "pixelName", &PixelProperties::getPixelName); - addProperty(data, "pixelFormatName", &PixelProperties::getPixelFormatName); - addProperty(data, "bitDepth", &PixelProperties::getBitsPerPixel); - addProperty(data, "maxNbBitsInChannels", &PixelProperties::getMaxNbBitsInChannels); - addProperty(data, "nbComponents", &PixelProperties::getNbComponents); - addProperty(data, "chromaWidth", &PixelProperties::getChromaWidth); - addProperty(data, "chromaHeight", &PixelProperties::getChromaHeight); + detail::addProperty(data, "pixelName", this, &PixelProperties::getPixelName); + detail::addProperty(data, "pixelFormatName", this, &PixelProperties::getPixelFormatName); + detail::addProperty(data, "bitDepth", this, &PixelProperties::getBitsPerPixel); + detail::addProperty(data, "maxNbBitsInChannels", this, &PixelProperties::getMaxNbBitsInChannels); + detail::addProperty(data, "nbComponents", this, &PixelProperties::getNbComponents); + detail::addProperty(data, "chromaWidth", this, &PixelProperties::getChromaWidth); + detail::addProperty(data, "chromaHeight", this, &PixelProperties::getChromaHeight); try { @@ -308,14 +308,14 @@ PropertyVector& PixelProperties::fillVector(PropertyVector& data) const detail::add(data, "subsampling", detail::propertyValueIfError); } - addProperty(data, "isBigEndian", &PixelProperties::isBigEndian); - addProperty(data, "hasAlpha", &PixelProperties::hasAlpha); - addProperty(data, "isPlanar", &PixelProperties::isPlanar); - addProperty(data, "isIndexedColors", &PixelProperties::isIndexedColors); - addProperty(data, "bitWiseAcked", &PixelProperties::isBitWisePacked); - addProperty(data, "isHardwareAccelerated", &PixelProperties::isHardwareAccelerated); - addProperty(data, "rgbPixel", &PixelProperties::isRgbPixelData); - addProperty(data, "isPseudoPaletted", &PixelProperties::isPseudoPaletted); + detail::addProperty(data, "isBigEndian", this, &PixelProperties::isBigEndian); + detail::addProperty(data, "hasAlpha", this, &PixelProperties::hasAlpha); + detail::addProperty(data, "isPlanar", this, &PixelProperties::isPlanar); + detail::addProperty(data, "isIndexedColors", this, &PixelProperties::isIndexedColors); + detail::addProperty(data, "bitWiseAcked", this, &PixelProperties::isBitWisePacked); + detail::addProperty(data, "isHardwareAccelerated", this, &PixelProperties::isHardwareAccelerated); + detail::addProperty(data, "rgbPixel", this, &PixelProperties::isRgbPixelData); + detail::addProperty(data, "isPseudoPaletted", this, &PixelProperties::isPseudoPaletted); try { diff --git a/src/AvTranscoder/properties/PixelProperties.hpp b/src/AvTranscoder/properties/PixelProperties.hpp index 5e087ef2..9fbe7dc7 100644 --- a/src/AvTranscoder/properties/PixelProperties.hpp +++ b/src/AvTranscoder/properties/PixelProperties.hpp @@ -86,21 +86,6 @@ class AvExport PixelProperties private: void init(const AVPixelFormat avPixelFormat); -#ifndef SWIG - template - void addProperty(PropertyVector& data, const std::string& key, T (PixelProperties::*getter)(void) const) const - { - try - { - detail::add(data, key, (this->*getter)()); - } - catch(const std::exception& e) - { - detail::add(data, key, detail::propertyValueIfError); - } - } -#endif - private: AVPixelFormat _pixelFormat; const AVPixFmtDescriptor* _pixelDesc; ///< Has link (no ownership) diff --git a/src/AvTranscoder/properties/PropertyValue.cpp b/src/AvTranscoder/properties/PropertyValue.cpp new file mode 100644 index 00000000..ef2edeff --- /dev/null +++ b/src/AvTranscoder/properties/PropertyValue.cpp @@ -0,0 +1,146 @@ + +#include "PropertyValue.hpp" +#include +#include + +namespace avtranscoder +{ + +PropertyValue::PropertyValue(const EPropertyValueKind kind, const std::string& data) + : _kind(kind) + , _data(data.c_str(), data.c_str() + data.size() + 1) +{} + +PropertyValue::PropertyValue(const EPropertyValueKind kind, const bool data) + : _kind(kind) + , _data(sizeof(bool), data) +{} + +PropertyValue::PropertyValue(const EPropertyValueKind kind, const size_t data) + : _kind(kind) + , _data(sizeof(size_t), data) +{ + ::memcpy(_data.data(), &data, sizeof(size_t)); +} + +PropertyValue::PropertyValue(const EPropertyValueKind kind, const int data) + : _kind(kind) + , _data(sizeof(int), data) +{} + +PropertyValue::PropertyValue(const EPropertyValueKind kind, const float data) + : _kind(kind) + , _data(sizeof(float), data) +{} + +PropertyValue::PropertyValue(const EPropertyValueKind kind, const double data) + : _kind(kind) + , _data(sizeof(double), data) +{} + +PropertyValue::PropertyValue(const EPropertyValueKind kind, const Rational data) + : _kind(kind) + , _data(2 * sizeof(int), 0) +{ + _data[sizeof(int)] = data.num; + _data[0] = data.den; +} + + +const EPropertyValueKind PropertyValue::getType() const +{ + return _kind; +} + +const std::string PropertyValue::getString() const +{ + return std::string(_data.begin(), _data.begin() + _data.size()); +} + +const bool PropertyValue::getBool() const +{ + return (bool)_data[0]; +} + +const size_t PropertyValue::getUInt() const +{ + size_t v = 0; + ::memcpy(&v, _data.data(), sizeof(size_t)); + return v; +} + +const int PropertyValue::getInt() const +{ + return (int)_data[0]; +} + +const float PropertyValue::getFloat() const +{ + return (float)_data[0]; +} + +const double PropertyValue::getDouble() const +{ + return (double)_data[0]; +} + +const Rational PropertyValue::getRational() const +{ + Rational r; + r.num = (int)_data[sizeof(int)]; + r.den = (int)_data[0]; + return r; +} + +const std::string PropertyValue::asString() const +{ + std::ostringstream os; + switch(getType()) + { + case EPropertyValueKind::EPropertyValueKindString: + { + os << getString(); + break; + } + case EPropertyValueKind::EPropertyValueKindUInt: + { + os << getUInt(); + break; + } + case EPropertyValueKind::EPropertyValueKindInt: + { + os << getInt(); + break; + } + case EPropertyValueKind::EPropertyValueKindFloat: + { + os << getFloat(); + break; + } + case EPropertyValueKind::EPropertyValueKindDouble: + { + os << getDouble(); + break; + } + case EPropertyValueKind::EPropertyValueKindBoolean: + { + os << (getBool() ? "true": "false"); + break; + } + case EPropertyValueKind::EPropertyValueKindRational: + { + Rational r = getRational(); + os << r.num << "/" << r.den; + break; + } + } + return os.str(); +} + +std::ostream& operator<<(std::ostream& stream, const PropertyValue& value) +{ + stream << value.asString(); + return stream; +} + +} diff --git a/src/AvTranscoder/properties/PropertyValue.hpp b/src/AvTranscoder/properties/PropertyValue.hpp new file mode 100644 index 00000000..7d4ab862 --- /dev/null +++ b/src/AvTranscoder/properties/PropertyValue.hpp @@ -0,0 +1,53 @@ +#ifndef _AV_TRANSCODER_PROPERTIES_PROPERTY_VALUE_HPP_ +#define _AV_TRANSCODER_PROPERTIES_PROPERTY_VALUE_HPP_ + +#include +#include +#include + +namespace avtranscoder +{ + +enum EPropertyValueKind +{ + EPropertyValueKindString = 0, + EPropertyValueKindBoolean, + EPropertyValueKindInt, + EPropertyValueKindUInt, + EPropertyValueKindFloat, + EPropertyValueKindDouble, + EPropertyValueKindRational, +}; + +class PropertyValue +{ +public: + PropertyValue(const EPropertyValueKind kind, const std::string& data); + PropertyValue(const EPropertyValueKind kind, const bool data); + PropertyValue(const EPropertyValueKind kind, const int data); + PropertyValue(const EPropertyValueKind kind, const size_t data); + PropertyValue(const EPropertyValueKind kind, const float data); + PropertyValue(const EPropertyValueKind kind, const double data); + PropertyValue(const EPropertyValueKind kind, const Rational data); + + const EPropertyValueKind getType() const; + const std::string getString() const; + const bool getBool() const; + const size_t getUInt() const; + const int getInt() const; + const float getFloat() const; + const double getDouble() const; + const Rational getRational() const; + + const std::string asString() const; + +private: + EPropertyValueKind _kind; + std::vector _data; +}; + +std::ostream& operator<<(std::ostream& stream, const PropertyValue& value); + +} + +#endif diff --git a/src/AvTranscoder/properties/StreamProperties.cpp b/src/AvTranscoder/properties/StreamProperties.cpp index 6f6fcf02..5efd9a29 100644 --- a/src/AvTranscoder/properties/StreamProperties.cpp +++ b/src/AvTranscoder/properties/StreamProperties.cpp @@ -1,7 +1,7 @@ #include "StreamProperties.hpp" #include -#include +#include #include #include @@ -134,17 +134,17 @@ PropertyVector StreamProperties::asVector() const PropertyVector& StreamProperties::fillVector(PropertyVector& data) const { - addProperty(data, "streamId", &StreamProperties::getStreamId); - addProperty(data, "streamIndex", &StreamProperties::getStreamIndex); - addProperty(data, "timeBase", &StreamProperties::getTimeBase); - addProperty(data, "duration", &StreamProperties::getDuration); - addProperty(data, "codecId", &StreamProperties::getCodecId); - addProperty(data, "codecName", &StreamProperties::getCodecName); - addProperty(data, "codecLongName", &StreamProperties::getCodecLongName); + detail::addProperty(data, "streamId", this, &StreamProperties::getStreamId); + detail::addProperty(data, "streamIndex", this, &StreamProperties::getStreamIndex); + detail::addProperty(data, "timeBase", this, &StreamProperties::getTimeBase); + detail::addProperty(data, "duration", this, &StreamProperties::getDuration); + detail::addProperty(data, "codecId", this, &StreamProperties::getCodecId); + detail::addProperty(data, "codecName", this, &StreamProperties::getCodecName); + detail::addProperty(data, "codecLongName", this, &StreamProperties::getCodecLongName); for(size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex) { - detail::add(data, _metadatas.at(metadataIndex).first, _metadatas.at(metadataIndex).second); + // detail::add(data, _metadatas.at(metadataIndex).first, _metadatas.at(metadataIndex).second); } return data; @@ -165,11 +165,8 @@ PropertyMap StreamProperties::asMap() const std::string StreamProperties::asJson() const { - json::JsonObjectStreamWriter writer; PropertyMap properties = asMap(); - for(PropertyMap::iterator it = properties.begin(); it != properties.end(); ++it) - writer << std::make_pair(it->first.c_str(), it->second.c_str()); - return writer.build(); + return json::build(properties); } std::ostream& operator<<(std::ostream& flux, const StreamProperties& streamProperties) diff --git a/src/AvTranscoder/properties/StreamProperties.hpp b/src/AvTranscoder/properties/StreamProperties.hpp index 2820119b..03ef11c9 100644 --- a/src/AvTranscoder/properties/StreamProperties.hpp +++ b/src/AvTranscoder/properties/StreamProperties.hpp @@ -51,22 +51,6 @@ class AvExport StreamProperties PropertyVector asVector() const; ///< Same data with a specific order virtual PropertyVector& fillVector(PropertyVector& data) const; ///< To avoid copy of the vector -private: -#ifndef SWIG - template - void addProperty(PropertyVector& dataVector, const std::string& key, T (StreamProperties::*getter)(void) const) const - { - try - { - detail::add(dataVector, key, (this->*getter)()); - } - catch(const std::exception& e) - { - detail::add(dataVector, key, detail::propertyValueIfError); - } - } -#endif - protected: const FileProperties* _fileProperties; ///< Has link (no ownership) const AVFormatContext* _formatContext; ///< Has link (no ownership) diff --git a/src/AvTranscoder/properties/VideoProperties.cpp b/src/AvTranscoder/properties/VideoProperties.cpp index 97b8f4e1..2805f4bc 100644 --- a/src/AvTranscoder/properties/VideoProperties.cpp +++ b/src/AvTranscoder/properties/VideoProperties.cpp @@ -568,29 +568,29 @@ PropertyVector& VideoProperties::fillVector(PropertyVector& data) const StreamProperties::fillVector(basedProperty); data.insert(data.begin(), basedProperty.begin(), basedProperty.end()); - addProperty(data, "profile", &VideoProperties::getProfile); - addProperty(data, "profileName", &VideoProperties::getProfileName); - addProperty(data, "level", &VideoProperties::getLevel); - addProperty(data, "startTimecode", &VideoProperties::getStartTimecodeString); - addProperty(data, "width", &VideoProperties::getWidth); - addProperty(data, "height", &VideoProperties::getHeight); - addProperty(data, "pixelAspectRatio", &VideoProperties::getSar); - addProperty(data, "displayAspectRatio", &VideoProperties::getDar); - addProperty(data, "dtgActiveFormat", &VideoProperties::getDtgActiveFormat); - addProperty(data, "colorTransfert", &VideoProperties::getColorTransfert); - addProperty(data, "colorspace", &VideoProperties::getColorspace); - addProperty(data, "colorRange", &VideoProperties::getColorRange); - addProperty(data, "colorPrimaries", &VideoProperties::getColorPrimaries); - addProperty(data, "chromaSampleLocation", &VideoProperties::getChromaSampleLocation); - addProperty(data, "fieldOrder", &VideoProperties::getFieldOrder); - addProperty(data, "fps", &VideoProperties::getFps); - addProperty(data, "nbFrames", &VideoProperties::getNbFrames); - addProperty(data, "ticksPerFrame", &VideoProperties::getTicksPerFrame); - addProperty(data, "bitRate", &VideoProperties::getBitRate); - addProperty(data, "maxBitRate", &VideoProperties::getMaxBitRate); - addProperty(data, "minBitRate", &VideoProperties::getMinBitRate); - addProperty(data, "hasBFrames", &VideoProperties::hasBFrames); - addProperty(data, "referencesFrames", &VideoProperties::getReferencesFrames); + detail::addProperty(data, "profile", this, &VideoProperties::getProfile); + detail::addProperty(data, "profileName", this, &VideoProperties::getProfileName); + detail::addProperty(data, "level", this, &VideoProperties::getLevel); + detail::addProperty(data, "startTimecode", this, &VideoProperties::getStartTimecodeString); + detail::addProperty(data, "width", this, &VideoProperties::getWidth); + detail::addProperty(data, "height", this, &VideoProperties::getHeight); + detail::addProperty(data, "pixelAspectRatio", this, &VideoProperties::getSar); + detail::addProperty(data, "displayAspectRatio", this, &VideoProperties::getDar); + detail::addProperty(data, "dtgActiveFormat", this, &VideoProperties::getDtgActiveFormat); + detail::addProperty(data, "colorTransfert", this, &VideoProperties::getColorTransfert); + detail::addProperty(data, "colorspace", this, &VideoProperties::getColorspace); + detail::addProperty(data, "colorRange", this, &VideoProperties::getColorRange); + detail::addProperty(data, "colorPrimaries", this, &VideoProperties::getColorPrimaries); + detail::addProperty(data, "chromaSampleLocation", this, &VideoProperties::getChromaSampleLocation); + detail::addProperty(data, "fieldOrder", this, &VideoProperties::getFieldOrder); + detail::addProperty(data, "fps", this, &VideoProperties::getFps); + detail::addProperty(data, "nbFrames", this, &VideoProperties::getNbFrames); + detail::addProperty(data, "ticksPerFrame", this, &VideoProperties::getTicksPerFrame); + detail::addProperty(data, "bitRate", this, &VideoProperties::getBitRate); + detail::addProperty(data, "maxBitRate", this, &VideoProperties::getMaxBitRate); + detail::addProperty(data, "minBitRate", this, &VideoProperties::getMinBitRate); + detail::addProperty(data, "hasBFrames", this, &VideoProperties::hasBFrames); + detail::addProperty(data, "referencesFrames", this, &VideoProperties::getReferencesFrames); // Add properties available when decode first gop if(_levelAnalysis < eAnalyseLevelFirstGop) @@ -602,7 +602,7 @@ PropertyVector& VideoProperties::fillVector(PropertyVector& data) const } else { - addProperty(data, "gopSize", &VideoProperties::getGopSize); + detail::addProperty(data, "gopSize", this, &VideoProperties::getGopSize); std::stringstream gop; for(size_t frameIndex = 0; frameIndex < _gopStructure.size(); ++frameIndex) @@ -616,8 +616,8 @@ PropertyVector& VideoProperties::fillVector(PropertyVector& data) const detail::add(data, "gop", gop.str()); // detail::add( data, "isClosedGop", isClosedGop() ); - addProperty(data, "interlaced ", &VideoProperties::isInterlaced); - addProperty(data, "topFieldFirst", &VideoProperties::isTopFieldFirst); + detail::addProperty(data, "interlaced ", this, &VideoProperties::isInterlaced); + detail::addProperty(data, "topFieldFirst", this, &VideoProperties::isTopFieldFirst); } // Add properties of the pixel diff --git a/src/AvTranscoder/properties/VideoProperties.hpp b/src/AvTranscoder/properties/VideoProperties.hpp index 27b6d0c5..d5819d15 100644 --- a/src/AvTranscoder/properties/VideoProperties.hpp +++ b/src/AvTranscoder/properties/VideoProperties.hpp @@ -109,21 +109,6 @@ class AvExport VideoProperties : public StreamProperties */ void analyseGopStructure(IProgress& progress); -#ifndef SWIG - template - void addProperty(PropertyVector& dataVector, const std::string& key, T (VideoProperties::*getter)(void) const) const - { - try - { - detail::add(dataVector, key, (this->*getter)()); - } - catch(const std::exception& e) - { - detail::add(dataVector, key, detail::propertyValueIfError); - } - } -#endif - private: /** * @brief Level of analysis asked. diff --git a/src/AvTranscoder/properties/jsonWriterHelper.cpp b/src/AvTranscoder/properties/jsonWriterHelper.cpp new file mode 100644 index 00000000..d2ccad1b --- /dev/null +++ b/src/AvTranscoder/properties/jsonWriterHelper.cpp @@ -0,0 +1,63 @@ + +#include +#include + +namespace avtranscoder +{ +namespace json +{ + +std::string build(PropertyMap& properties) +{ + json::JsonObjectStreamWriter writer; + for(PropertyMap::iterator it = properties.begin(); it != properties.end(); ++it) + { + switch(it->second.getType()) + { + case EPropertyValueKind::EPropertyValueKindString: + { + writer << std::make_pair(it->first.c_str(), it->second.getString().c_str()); + break; + } + case EPropertyValueKind::EPropertyValueKindInt: + { + writer << std::make_pair(it->first.c_str(), it->second.getInt()); + break; + } + case EPropertyValueKind::EPropertyValueKindUInt: + { + writer << std::make_pair(it->first.c_str(), it->second.getUInt()); + break; + } + case EPropertyValueKind::EPropertyValueKindFloat: + { + writer << std::make_pair(it->first.c_str(), it->second.getFloat()); + break; + } + case EPropertyValueKind::EPropertyValueKindDouble: + { + writer << std::make_pair(it->first.c_str(), it->second.getDouble()); + break; + } + case EPropertyValueKind::EPropertyValueKindBoolean: + { + writer << std::make_pair(it->first.c_str(), it->second.getBool()); + break; + } + case EPropertyValueKind::EPropertyValueKindRational: + { + Rational r = it->second.getRational(); + JsonObjectStreamWriter ratio; + ratio << std::make_pair("num", r.num); + ratio << std::make_pair("den", r.den); + writer << std::make_pair(it->first.c_str(), ratio.build()); + break; + } + } + + } + return writer.build(); +} + +} +} diff --git a/src/AvTranscoder/properties/jsonWriterHelper.hpp b/src/AvTranscoder/properties/jsonWriterHelper.hpp new file mode 100644 index 00000000..3b6d553c --- /dev/null +++ b/src/AvTranscoder/properties/jsonWriterHelper.hpp @@ -0,0 +1,16 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_JSON_WRITER_HELPER_HPP_ +#define _AV_TRANSCODER_MEDIA_PROPERTY_JSON_WRITER_HELPER_HPP_ + +#include + +namespace avtranscoder +{ +namespace json +{ + +std::string build(PropertyMap& properties); + +} +} + +#endif diff --git a/src/AvTranscoder/properties/util.cpp b/src/AvTranscoder/properties/util.cpp index d6201b33..b7ebd64e 100644 --- a/src/AvTranscoder/properties/util.cpp +++ b/src/AvTranscoder/properties/util.cpp @@ -5,6 +5,7 @@ extern "C" { } #include +#include namespace avtranscoder { @@ -15,41 +16,43 @@ namespace detail template <> void add(PropertyVector& propertyVector, const std::string& key, const size_t& value) { - std::stringstream ss; - if(value == (size_t)AV_NOPTS_VALUE) - ss << "N/A"; - else - ss << value; - add(propertyVector, key, ss.str()); + addWithKind(propertyVector, key, EPropertyValueKind::EPropertyValueKindUInt, value); +} + +template <> +void add(PropertyVector& propertyVector, const std::string& key, const int& value) +{ + addWithKind(propertyVector, key, EPropertyValueKind::EPropertyValueKindInt, value); } template <> void add(PropertyVector& propertyVector, const std::string& key, const float& value) { - std::stringstream ss; - if(value <= AV_NOPTS_VALUE || value >= -(float)AV_NOPTS_VALUE) - ss << "N/A"; - else - ss << value; - add(propertyVector, key, ss.str()); + addWithKind(propertyVector, key, EPropertyValueKind::EPropertyValueKindFloat, value); +} + +template <> +void add(PropertyVector& propertyVector, const std::string& key, const double& value) +{ + addWithKind(propertyVector, key, EPropertyValueKind::EPropertyValueKindDouble, value); } template <> void add(PropertyVector& propertyVector, const std::string& key, const std::string& value) { - propertyVector.push_back(std::make_pair(key, value)); + addWithKind(propertyVector, key, EPropertyValueKind::EPropertyValueKindString, value); } template <> void add(PropertyVector& propertyVector, const std::string& key, const bool& value) { - add(propertyVector, key, value ? "True" : "False"); + addWithKind(propertyVector, key, EPropertyValueKind::EPropertyValueKindBoolean, value); } template <> void add(PropertyVector& propertyVector, const std::string& key, const Rational& value) { - add(propertyVector, key, value.num / (double)value.den); + addWithKind(propertyVector, key, EPropertyValueKind::EPropertyValueKindRational, value); } void fillMetadataDictionnary(AVDictionary* avdictionnary, PropertyVector& metadata) @@ -57,7 +60,7 @@ void fillMetadataDictionnary(AVDictionary* avdictionnary, PropertyVector& metada AVDictionaryEntry* tag = NULL; while((tag = av_dict_get(avdictionnary, "", tag, AV_DICT_IGNORE_SUFFIX))) { - metadata.push_back(std::make_pair(tag->key, tag->value)); + addWithKind(metadata, tag->key, EPropertyValueKind::EPropertyValueKindString, std::string(tag->value)); } } } diff --git a/src/AvTranscoder/properties/util.hpp b/src/AvTranscoder/properties/util.hpp index 411fd01c..5fb7a97e 100644 --- a/src/AvTranscoder/properties/util.hpp +++ b/src/AvTranscoder/properties/util.hpp @@ -2,6 +2,7 @@ #define _AV_TRANSCODER_MEDIA_PROPERTY_UTIL_HPP_ #include +#include extern "C" { #include @@ -13,6 +14,7 @@ extern "C" { #include #include #include +#include namespace avtranscoder { @@ -20,8 +22,8 @@ namespace avtranscoder /** * @brief PropertyVector is a vector of pair, because the order of properties matters to us. */ -typedef std::vector > PropertyVector; -typedef std::map PropertyMap; +typedef std::vector > PropertyVector; +typedef std::map PropertyMap; namespace detail { @@ -48,6 +50,9 @@ void add(PropertyVector& propertyVector, const std::string& key, const T& value) template <> void add(PropertyVector& propertyVector, const std::string& key, const size_t& value); +template <> +void add(PropertyVector& propertyVector, const std::string& key, const int& value); + template <> void add(PropertyVector& propertyVector, const std::string& key, const float& value); @@ -60,6 +65,28 @@ void add(PropertyVector& propertyVector, const std::string& key, const bool& val template <> void add(PropertyVector& propertyVector, const std::string& key, const Rational& value); +#ifndef SWIG +template +void addWithKind(PropertyVector& propertyVector, const std::string& key, const EPropertyValueKind kind, const T& value) +{ + PropertyValue pv = PropertyValue(kind, value); + propertyVector.push_back(std::make_pair(key, pv)); +} + +template +void addProperty(PropertyVector& data, const std::string& key, const C* obj, T (C::*getter)(void) const) +{ + try + { + add(data, key, (obj->*getter)()); + } + catch(const std::exception& e) + { + add(data, key, detail::propertyValueIfError); + } +} +#endif + /** * @brief Fill metadata parameter with the given AVDictionary. */