Initial import from SVN

This commit is contained in:
emeric
2014-03-09 10:58:52 +01:00
commit b6abce0c2f
440 changed files with 30862 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
#include <cassert>
#include <stdexcept>
#include <iostream>
#include "Codec.hpp"
Codec::Codec(enum CodecID codec, Type type )
: _codec(nullptr)
{
if (type == Encoder)
_codec = avcodec_find_encoder(codec);
else if (type == Decoder)
_codec = avcodec_find_decoder(codec);
if (_codec == nullptr) {
std::cerr << "Codec constructor failed! codec = " << codec << ", type = " << type << std::endl;
throw std::runtime_error("can't find codec using this id!");
}
}
Codec::Codec(const AVCodec* codec)
: _codec(codec)
{
assert(_codec != nullptr);
}
Codec::~Codec()
{
if (_codec == nullptr) {
// TODO release iif ownership has not been taken?
// av_codec_close(_codec);
}
}
const AVCodec*
Codec::get() const
{
assert(_codec != nullptr);
return _codec;
}
Codec::Id
Codec::getId() const
{
assert(_codec != nullptr);
return _codec->id;
}
std::string
Codec::getName() const
{
assert(_codec != nullptr);
return _codec->name;
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef CODEC_HPP__
#define CODEC_HPP__
#include <string>
#include <memory>
#include <boost/utility.hpp>
#include "Common.hpp"
class Codec : boost::noncopyable
{
friend class CodecContext;
friend class FormatContext;
friend class OutputFormatContext;
public:
typedef enum CodecID Id;
enum Type {
Encoder,
Decoder,
};
Codec(Id codecId, Type type);
Codec(const AVCodec* codec); // Attach existing codec
~Codec();
Id getId() const;
std::string getName() const;
private:
const AVCodec* get() const;
const AVCodec* _codec;
};
#endif
+35
View File
@@ -0,0 +1,35 @@
#include <stdexcept>
#include <iostream>
#include <iomanip>
#include <boost/array.hpp>
#include "CodecContext.hpp"
namespace Av
{
CodecContext::CodecContext(AVCodecContext* CodecContext)
: _codecContext(CodecContext)
{
assert(_codecContext != nullptr);
}
void
CodecContext::dumpInfo(std::ostream& ost) const
{
ost << "BitRate = " << getBitRate() << ", SampleFormat = " << getSampleFormat() << ", SampleRate = " << getSampleRate() << ", ChannelLayout = " << getChannelLayout() << ", NbChannels = " << getNbChannels() << ", Timebase = " << getTimeBase().num << "/" << getTimeBase().den;
}
std::string
CodecContext::getCodecDesc(void) const
{
std::vector<char> buf(256, 0);
avcodec_string(&buf[0], buf.size(), _codecContext, 0);
return std::string(buf.begin(), buf.end());
}
} // namespace Av
+44
View File
@@ -0,0 +1,44 @@
#ifndef CODEC_CONTEXT_HPP
#define CODEC_CONTEXT_HPP
#include <boost/utility.hpp>
#include <iostream>
#include "Codec.hpp"
namespace Av
{
class CodecContext
{
public:
CodecContext(AVCodecContext* CodecContext); // Attach existing codec context (no free will be done)
// Codec getCodec();
enum AVMediaType getType(void) const { return _codecContext->codec_type; }
Codec::Id getCodecId(void) const { return _codecContext->codec_id; }
std::string getCodecDesc(void) const;
// Accessors
std::size_t getBitRate() const {return _codecContext->bit_rate;}
AVSampleFormat getSampleFormat() const {return _codecContext->sample_fmt;}
std::size_t getSampleRate() const {return _codecContext->sample_rate;}
std::uint64_t getChannelLayout() const {return _codecContext->channel_layout;}
std::size_t getNbChannels() const {return _codecContext->channels; }
AVRational getTimeBase() const {return _codecContext->time_base; }
void dumpInfo(std::ostream& ost) const;
private:
AVCodecContext* native() { return _codecContext; }
AVCodecContext* _codecContext;
};
} // namespace Av
#endif
+29
View File
@@ -0,0 +1,29 @@
#include "Common.hpp"
#include <boost/array.hpp>
std::string
AvError::to_str(void) const
{
boost::array<char, 128> buf = {0};
if (av_strerror(_errnum, buf.data(), buf.size()) == 0)
return std::string(&buf[0]);
else
return "Unknown error";
}
std::ostream& operator<<(std::ostream& ost, const AvError& err)
{
ost << err.to_str();
return ost;
}
void AvInit()
{
/* register all the codecs */
avcodec_register_all();
av_register_all();
std::cout << "AVCDOEC VERSION = " << avcodec_version() << std::endl;
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef TRANSCODE_COMMON_HPP__
#define TRANSCODE_COMMON_HPP__
// Hack to properly iinclude libavcodec/avcodec.h...
//
#define __STDC_CONSTANT_MACROS
#ifdef _STDINT_H
#undef _STDINT_H
#endif
# include <stdint.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/channel_layout.h>
#include <libavutil/mathematics.h>
}
#include <string>
void AvInit();
class AvError
{
public:
AvError() : _errnum(0) {}
AvError(int ernum) : _errnum(ernum) {}
void operator=(int errnum) { _errnum = errnum; }
operator bool() { return _errnum < 0; }
std::string to_str() const;
friend std::ostream& operator<<(std::ostream& ost, const AvError&);
bool eof() { return _errnum == AVERROR_EOF; } // TODO
private:
int _errnum;
};
#endif
+31
View File
@@ -0,0 +1,31 @@
#include "Dictionary.hpp"
namespace Av
{
Dictionary::Dictionary(AVDictionary* dictionary)
: _dictionary(dictionary)
{
}
void
Dictionary::get(std::map<std::string, std::string>& entries)
{
AVDictionaryEntry *tag = NULL;
while ((tag = av_dict_get(_dictionary, "", tag, AV_DICT_IGNORE_SUFFIX))) {
entries.insert( std::make_pair(tag->key, tag->value));
}
}
std::string
Dictionary::get(std::string key)
{
AVDictionaryEntry *tag = NULL;
tag = av_dict_get(_dictionary, key.c_str(), tag, 0);
return tag != NULL ? std::string(tag->value) : std::string();
}
} // namespace Av
+28
View File
@@ -0,0 +1,28 @@
#ifndef AV_DICTIONARY_HPP
#define AV_DICTIONARY_HPP
#include <map>
#include "Common.hpp"
namespace Av
{
class Dictionary
{
public:
Dictionary(AVDictionary* dictionary);
// Get all
void get(std::map<std::string, std::string>& entries);
// get a single entry
std::string get(std::string key);
private:
AVDictionary* _dictionary;
};
} // namespace Av
#endif
+16
View File
@@ -0,0 +1,16 @@
#include "FormatContext.hpp"
namespace Av
{
FormatContext::FormatContext()
: _context(nullptr)
{
}
FormatContext::~FormatContext()
{
}
} // namespace Av
+33
View File
@@ -0,0 +1,33 @@
#ifndef FORMAT_CONTEXT_HPP
#define FORMAT_CONTEXT_HPP
#include <boost/filesystem.hpp>
#include "Common.hpp"
namespace Av
{
class FormatContext
{
public:
FormatContext();
~FormatContext();
protected:
void native(AVFormatContext* c) { _context = c;}
AVFormatContext* native() { return _context; }
const AVFormatContext* native() const { return _context; }
private:
AVFormatContext* _context;
};
} // namespace Av
#endif
+99
View File
@@ -0,0 +1,99 @@
#include <stdexcept>
#include <iostream>
#include "InputFormatContext.hpp"
namespace Av
{
InputFormatContext::InputFormatContext(const boost::filesystem::path& p)
: _path(p)
{
std::cout << "Opening '" << p.string().c_str() << "'" << std::endl;
AVFormatContext* context = nullptr;
// The last three parameters specify the file format, buffer size and
// format parameters. By simply specifying NULL or 0 we ask libavformat
// to auto-detect the format and use a default buffer size.
AvError error = avformat_open_input(&context, p.string().c_str(), nullptr, nullptr);
if (error)
{
std::cerr << "Cannot open '" << p.string() << "', avformat_open_input returned " << error << std::endl;
throw std::runtime_error("avformat_open_input failed: " + error.to_str());
}
native(context);
}
InputFormatContext::~InputFormatContext()
{
AVFormatContext* context = native();
avformat_close_input(&context);
}
std::vector<Stream>
InputFormatContext::getStreams(void)
{
std::vector<Stream> res;
for (std::size_t i = 0; i < native()->nb_streams; ++i) {
res.push_back( Stream(native()->streams[i]));
}
return res;
}
bool
InputFormatContext::getBestStreamIdx(AVMediaType type, Stream::Idx& index)
{
int res = av_find_best_stream(native(),
type,
-1, // Auto
-1, // Auto
NULL,
0
);
AvError error(res);
if (error) {
std::cerr << "Cannot get best stream for type " << type << ": " << error << std::endl;
return false;
}
else {
index = res;
return true;
}
}
void
InputFormatContext::findStreamInfo(void)
{
native()->max_analyze_duration = 10 * AV_TIME_BASE; // 10 secs
AvError err = avformat_find_stream_info(native(), NULL);
if (err) {
std::cerr << "Couldn't find stream information: " << err << std::endl;
throw std::runtime_error("av_find_stream_info failed!");
}
}
std::size_t
InputFormatContext::getDurationSecs() const
{
if (native()->duration != AV_NOPTS_VALUE )
return native()->duration / AV_TIME_BASE;
else
return 0; // TODO, do something better?
}
Dictionary
InputFormatContext::getMetadata(void)
{
return Dictionary(native()->metadata);
}
} //namespace Av
+43
View File
@@ -0,0 +1,43 @@
#ifndef INPUT_FORMAT_CONTEXT_HPP
#define INPUT_FORMAT_CONTEXT_HPP
#include <vector>
#include <boost/filesystem.hpp>
#include "FormatContext.hpp"
#include "Stream.hpp"
#include "Dictionary.hpp"
namespace Av
{
class InputFormatContext : public FormatContext
{
public:
InputFormatContext(const boost::filesystem::path& p);
~InputFormatContext();
Dictionary getMetadata(void); // metadata access
// Scan file
void findStreamInfo();
std::vector<Stream> getStreams(void);
bool getBestStreamIdx(enum AVMediaType type, Stream::Idx& idx);
std::size_t getDurationSecs() const;
private:
boost::filesystem::path _path;
};
} // namespace av
#endif
+26
View File
@@ -0,0 +1,26 @@
#include <cassert>
#include "Stream.hpp"
namespace Av
{
Stream::Stream(AVStream* stream)
: _stream(stream)
{
assert(_stream != nullptr);
assert(_stream->codec != nullptr);
}
CodecContext
Stream::getCodecContext()
{
return _stream->codec;
}
Dictionary
Stream::getMetadata(void)
{
return Dictionary(_stream->metadata);
}
} // namespace Av
+35
View File
@@ -0,0 +1,35 @@
#ifndef STREAM_HPP__
#define STREAM_HPP__
#include "Common.hpp"
#include "CodecContext.hpp"
#include "Dictionary.hpp"
namespace Av
{
class Stream
{
friend class InputFormatContext;
public:
// Attach existing stream
Stream(AVStream* stream);
typedef size_t Idx;
// Idx getIdx() const { return _stream->index; }
Dictionary getMetadata(void);
CodecContext getCodecContext(void);
private:
AVStream* _stream;
};
} // namespace Av
#endif