Files
lms/av/InputFormatContext.cpp
T

118 lines
2.6 KiB
C++

#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);
}
void
InputFormatContext::getPictures(std::vector< std::vector<unsigned char> >& pictures) const
{
for (std::size_t i = 0; i < native()->nb_streams; ++i)
{
if (native()->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC)
{
std::cout << "Found album art..." << std::endl;
AVPacket pkt = native()->streams[i]->attached_pic;
std::vector<unsigned char> data;
std::copy(pkt.data, pkt.data + pkt.size, std::back_inserter(data));
pictures.push_back( data );
}
}
}
} //namespace Av