forked from h4tr3d/avcpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
310 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
#include <utility> | ||
#include <cstring> | ||
|
||
#include "channellayout.h" | ||
|
||
namespace av { | ||
|
||
static constexpr size_t BufferSize = 128; | ||
|
||
|
||
std::string channel_name(AVChannel channel) | ||
{ | ||
char buf[BufferSize]{}; | ||
av_channel_name(buf, sizeof(buf), channel); | ||
return buf; | ||
} | ||
|
||
std::string channel_description(AVChannel channel) | ||
{ | ||
char buf[BufferSize]{}; | ||
av_channel_description(buf, sizeof(buf), channel); | ||
return buf; | ||
} | ||
|
||
AVChannel channel_from_string(const std::string &name) | ||
{ | ||
return channel_from_string(name.c_str()); | ||
} | ||
|
||
AVChannel channel_from_string(const char *name) | ||
{ | ||
return av_channel_from_string(name); | ||
} | ||
|
||
|
||
ChannelLayoutView::ChannelLayoutView() noexcept | ||
{ | ||
} | ||
|
||
ChannelLayoutView::ChannelLayoutView(const AVChannelLayout &layout) noexcept | ||
: m_layout(layout) | ||
{ | ||
} | ||
|
||
void ChannelLayoutView::dumpLayouts() | ||
{ | ||
//std::string; | ||
iterate([] (const ChannelLayoutView &ch) { | ||
char buf[BufferSize]{}; | ||
av_channel_layout_describe(ch.raw(), buf, sizeof(buf)); | ||
std::string channels; | ||
for (int i = 0; i < 63; i++) { | ||
auto idx = ch.index(AVChannel(i)); | ||
if (idx >= 0) { | ||
if (idx) | ||
channels.push_back('+'); | ||
channels.append(channel_name(AVChannel(i))); | ||
} | ||
} | ||
return false; // is not done | ||
}); | ||
} | ||
|
||
AVChannelLayout *ChannelLayoutView::raw() | ||
{ | ||
return &m_layout; | ||
} | ||
|
||
const AVChannelLayout *ChannelLayoutView::raw() const | ||
{ | ||
return &m_layout; | ||
} | ||
|
||
int ChannelLayoutView::channels() const noexcept | ||
{ | ||
return m_layout.nb_channels; | ||
} | ||
|
||
uint64_t ChannelLayoutView::layout() const noexcept | ||
{ | ||
return m_layout.order == AV_CHANNEL_ORDER_NATIVE ? m_layout.u.mask : 0; | ||
} | ||
|
||
uint64_t ChannelLayoutView::subset(uint64_t mask) const noexcept | ||
{ | ||
return av_channel_layout_subset(&m_layout, mask); | ||
} | ||
|
||
bool ChannelLayoutView::isValid() const noexcept | ||
{ | ||
return av_channel_layout_check(&m_layout); | ||
} | ||
|
||
std::string ChannelLayoutView::describe() const | ||
{ | ||
char buf[BufferSize]{}; | ||
av_channel_layout_describe(&m_layout, buf, sizeof(buf)); | ||
return buf; | ||
} | ||
|
||
void ChannelLayoutView::describe(std::string &desc) const | ||
{ | ||
// TBD | ||
if (desc.capacity()) { | ||
if (!desc.size()) | ||
desc.resize(desc.capacity()); | ||
av_channel_layout_describe(&m_layout, desc.data(), desc.size()); | ||
desc.resize(std::strlen(desc.data())); // hack? | ||
} else { | ||
desc = describe(); | ||
} | ||
} | ||
|
||
int ChannelLayoutView::index(AVChannel channel) const | ||
{ | ||
return av_channel_layout_index_from_channel(&m_layout, channel); | ||
} | ||
|
||
int ChannelLayoutView::index(const char *name) const | ||
{ | ||
return av_channel_layout_index_from_string(&m_layout, name); | ||
} | ||
|
||
AVChannel ChannelLayoutView::channel(unsigned int index) const | ||
{ | ||
return av_channel_layout_channel_from_index(&m_layout, index); | ||
} | ||
|
||
AVChannel ChannelLayoutView::channel(const char *name) const | ||
{ | ||
return av_channel_layout_channel_from_string(&m_layout, name); | ||
} | ||
|
||
bool ChannelLayoutView::operator==(const ChannelLayoutView &other) const noexcept | ||
{ | ||
return av_channel_layout_compare(&m_layout, &other.m_layout) == 0; | ||
} | ||
|
||
|
||
ChannelLayout::ChannelLayout(const ChannelLayout &other) | ||
: ChannelLayout() | ||
{ | ||
// TODO: error checking | ||
av_channel_layout_copy(&m_layout, &other.m_layout); | ||
} | ||
|
||
ChannelLayout &ChannelLayout::operator=(const ChannelLayout &other) | ||
{ | ||
ChannelLayout(other).swap(*this); | ||
return *this; | ||
} | ||
|
||
ChannelLayout::ChannelLayout(ChannelLayout &&other) | ||
: ChannelLayout() | ||
{ | ||
m_layout = std::move(other.m_layout); | ||
memset(&other.m_layout, 0, sizeof(other.m_layout)); // avoid double memory clean up | ||
} | ||
|
||
ChannelLayout &ChannelLayout::operator=(ChannelLayout&& other) | ||
{ | ||
ChannelLayout(std::move(other)).swap(*this); | ||
return *this; | ||
} | ||
|
||
ChannelLayout::~ChannelLayout() | ||
{ | ||
av_channel_layout_uninit(&m_layout); | ||
} | ||
|
||
ChannelLayout::ChannelLayout(std::bitset<64> mask) | ||
{ | ||
// TODO: error checking | ||
av_channel_layout_from_mask(&m_layout, mask.to_ullong()); | ||
} | ||
|
||
ChannelLayout::ChannelLayout(const char *str) | ||
{ | ||
// TODO: error checking | ||
av_channel_layout_from_string(&m_layout, str); | ||
} | ||
|
||
ChannelLayout::ChannelLayout(int channels) | ||
{ | ||
// TODO: error checking | ||
av_channel_layout_default(&m_layout, channels); | ||
} | ||
|
||
void ChannelLayout::release() | ||
{ | ||
memset(&m_layout, 0, sizeof(m_layout)); | ||
} | ||
|
||
void ChannelLayout::swap(ChannelLayout &other) | ||
{ | ||
//std::swap(*raw(), *other.raw()); | ||
std::swap(m_layout, other.m_layout); | ||
} | ||
|
||
|
||
} // namespace av |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
#include <string_view> | ||
#include <bitset> | ||
|
||
extern "C" { | ||
#include <libavutil/channel_layout.h> | ||
} | ||
|
||
namespace av { | ||
|
||
std::string channel_name(AVChannel channel); | ||
std::string channel_description(AVChannel channel); | ||
AVChannel channel_from_string(const std::string &name); | ||
AVChannel channel_from_string(const char *name); | ||
|
||
class ChannelLayoutView | ||
{ | ||
public: | ||
ChannelLayoutView() noexcept; | ||
// implicit by design | ||
ChannelLayoutView(const AVChannelLayout &layout) noexcept; | ||
|
||
// ??? | ||
//+ const AVChannelLayout *av_channel_layout_standard(void **opaque); | ||
template<typename Callable> | ||
static void iterate(Callable callable) { | ||
void *iter = nullptr; | ||
const AVChannelLayout *playout; | ||
while ((playout = av_channel_layout_standard(&iter))) { | ||
if (callable(ChannelLayoutView(*playout))) | ||
break; | ||
} | ||
} | ||
|
||
static void dumpLayouts(); | ||
|
||
//+ int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size); | ||
//+ int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel); | ||
//+ int av_channel_layout_index_from_string(const AVChannelLayout *channel_layout, const char *name); | ||
//+ enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx); | ||
//+ enum AVChannel av_channel_layout_channel_from_string(const AVChannelLayout *channel_layout, const char *name); | ||
//+ uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask); | ||
//+ int av_channel_layout_check(const AVChannelLayout *channel_layout); | ||
//+ int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1); | ||
|
||
AVChannelLayout *raw(); | ||
const AVChannelLayout *raw() const; | ||
|
||
int channels() const noexcept; | ||
uint64_t layout() const noexcept; | ||
uint64_t subset(uint64_t mask) const noexcept; | ||
bool isValid() const noexcept; | ||
std::string describe() const; | ||
void describe(std::string &desc) const; | ||
|
||
int index(AVChannel channel) const; | ||
int index(const char *name) const; | ||
|
||
AVChannel channel(unsigned int index) const; | ||
AVChannel channel(const char *name) const; | ||
|
||
bool operator==(const ChannelLayoutView &other) const noexcept; | ||
|
||
protected: | ||
AVChannelLayout m_layout{}; | ||
}; | ||
|
||
|
||
|
||
class ChannelLayout : public ChannelLayoutView | ||
{ | ||
public: | ||
ChannelLayout() = default; | ||
|
||
using ChannelLayoutView::ChannelLayoutView; | ||
|
||
ChannelLayout(const ChannelLayout& other); | ||
ChannelLayout& operator=(const ChannelLayout& other); | ||
|
||
ChannelLayout(ChannelLayout&& other); | ||
ChannelLayout& operator=(ChannelLayout&& other); | ||
|
||
~ChannelLayout(); | ||
|
||
//+ void av_channel_layout_uninit(AVChannelLayout *channel_layout); | ||
// | ||
//+ int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask); | ||
//+ int av_channel_layout_from_string(AVChannelLayout *channel_layout, const char *str); | ||
//+ void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels); | ||
//+ int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src); | ||
|
||
//explicit ChannelLayout(uint64_t mask); | ||
explicit ChannelLayout(std::bitset<64> mask); | ||
explicit ChannelLayout(const char *str); | ||
explicit ChannelLayout(int channels); | ||
|
||
// Stop control AVChannelLayout | ||
void release(); | ||
|
||
private: | ||
void swap(ChannelLayout &other); | ||
|
||
}; | ||
|
||
|
||
} // namespace av | ||
|