ffmpeg avformat_open_input带有自定义流对象
ffmpeg avformat_open_input with custom stream object
我当前正在尝试使用FFMPEG的库编写用于SFML的自定义SoundFileReader
。我唯一可以与Avcodec和Avformat一起使用的是SFML的一部分InputStream
。我已经查看了avformat_open_input
和AVIOContext
,并且学会了如何使用缓冲区使用自定义流,但是如何创建与自定义阅读,搜索和LSEEK功能一起使用的AVIOContext
?
class InputStream {
int64_t getSize()
int64_t read(void* data, int64_t size);
int64_t seek(int64_t position);
int64_t tell(); // Gets the stream position
};
您需要编写一组回调函数,然后将指针传递给这些回调,然后将不透明的参数传递给avio_alloc_context
。请注意,这些回调不得投掷。
/// <summary>
/// Reads up to buffer_capacity_bytes_count bytes into supplied buffer.
/// Basically should work like ::read C method.
/// </summary>
/// <param name="opaque">
/// Opaque pointer to reader instance. Passing nullptr is not allowed.
/// </param>
/// <param name="p_buffer">
/// Pointer to data buffer. Passing nullptr is not allowed.
/// </param>
/// <param name="buffer_capacity_bytes_count">
/// Size of the buffer pointed to by p_buffer, in bytes.
/// Passing value less than or equal to 0 is not allowed.
/// </param>
/// <returns>
/// Non negative values containing amount of bytes actually read. 0 if EOF has been reached.
/// -1 if an error occurred.
/// </returns>
static auto
Read(void * const opaque, uint8_t * const p_buffer, int const buffer_capacity_bytes_count) noexcept
{
int result{-1};
if(opaque && p_buffer && (0 <= buffer_capacity_bytes_count))
{
auto & stream{*reinterpret_cast< InputStream * >(opaque)};
try
{
auto const read_result{stream.read(p_buffer, buffer_capacity_bytes_count)};
if((0 <= read_result) && (read_result <= buffer_capacity_bytes_count))
{
result = read_result;
}
}
catch(...)
{
// print error or something
}
}
return(result);
}
/// <summary>
/// Changes file pointer position or retrieves file size.
/// Basically should work like ::lseek and ::fstat C methods.
/// </summary>
/// <param name="opaque">
/// Opaque pointer to reader instance. Passing nullptr is not allowed.
/// </param>
/// <param name="pos">
/// Target offset. When retrieving file size this should be 0.
/// </param>
/// <param name="whence">
/// Flag indicating operation. Valid values are SEEK_SET, SEEK_CUR, SEEK_END (as in C library),
/// AVSEEK_SIZE and optional AVSEEK_FORCE bit.
/// </param>
/// <returns>
/// Non-negative values containing offset of the file pointer or file size in bytes.
/// Negative values if an error occurred.
/// </returns>
static auto
Seek(void * const opaque, int64_t const pos, int const whence) noexcept
{
int64_t result{AVERROR(EBADF)};
if(opaque)
{
auto & stream{*reinterpret_cast< InputStream * >(opaque)};
try
{
auto const action{whence & (SEEK_SET | SEEK_CUR | SEEK_END | AVSEEK_SIZE)};
auto const forced{0 != (whence & AVSEEK_FORCE)}; // can be ignored
switch(action)
{
case SEEK_SET:
case SEEK_CUR:
case SEEK_END:
{
// TODO perform seek...
break;
}
case AVSEEK_SIZE:
{
result = stream.getSize();
break;
}
}
}
catch(...)
{
// print error or something
}
}
return(result);
}
...
InputStream stream;
auto const opaque{reinterpret_cast< void * >(::std::addressof(stream))};
auto p_io_context
{
::avio_alloc_context
(
static_cast< unsigned char * >(p_buffer) // ownership is not transferred
, buffer_size
, 0 // 0 if openning for reading, 1 if openning for writing
, opaque
, &Read
, nullptr // write callback function, not used if we open for reading
, &Seek
)
};
相关文章:
- 自定义对象的dlib序列化在gcc中失败
- 如何将带有自定义对象的容器从C++传递到QML
- 如何使用Q_PROPERTY公开自定义对象列表
- 如何在自定义对象的<<运算符中添加自定义前缀
- 将自定义对象作为参数从目标 C 传递到 C++
- 使用自定义对象声明shared_ptr数组时出现错误 C2664
- 在具有自定义对象的集合中查找值
- std::set 不会检测到重复的自定义对象
- 如何使用自定义对象的序列化在 c++ 中编写自定义二进制文件处理程序
- std::排序为排序自定义对象时出现的向量引发错误
- 具有自定义对象的C 优先级队列
- 自定义对象构造函数在循环外部循环
- 带有自定义对象的C 范围循环
- 如何正确地将规则 5(或零?)应用于包含带有字符串的自定义对象向量的类
- 如何在包含自定义对象的容器中使用分区函数C++
- 如何在具有多个成员的自定义对象的向量上使用查找
- std::vector 如何支持未知大小的自定义对象的连续内存
- 将指针的QVECTOR分类到自定义对象
- (C )正在创建专门用于处理所有其他自定义对象的类/对象一种处理项目的正确方法
- C soci查询到自定义对象的向量