ffmpeg
読書メディア
サーチ…
前書き
Audio / VideoをFFmpegに読み込む方法はいくつかあります。
メモリからの読み込み
libavformatは通常、ファイル名を取り込み、ファイルシステムから直接メディアを読み込みます。メモリ(ストリームなど)から読み取る場合は、次の操作を行います。
// Define your buffer size
const int FILESTREAMBUFFERSZ = 8192;
// A IStream - you choose where it comes from
IStream* fileStreamData;
// Alloc a buffer for the stream
unsigned char* fileStreamBuffer = (unsigned char*)av_malloc(FILESTREAMBUFFERSZ);
if (fileStreamBuffer == nullptr){
// out of memory
}
// Get a AVContext stream
AVIOContext* ioContext = avio_alloc_context(
fileStreamBuffer, // Buffer
FILESTREAMBUFFERSZ, // Buffer size
0, // Buffer is only readable - set to 1 for read/write
fileStreamData, // User (your) specified data
FileStreamRead, // Function - Reading Packets (see example)
0, // Function - Write Packets
FileStreamSeek // Function - Seek to position in stream (see example)
);
if(ioContext == nullptr){
// out of memory
}
// Allocate a AVContext
AVFormatContext *formatContext = avformat_alloc_context();
// Set up the Format Context
formatContext->pb = ioContext;
formatContext->flags |= AVFMT_FLAG_CUSTOM_IO; // we set up our own IO
// Open "file" (open our custom IO)
// Empty string is where filename would go. Doesn't matter since we aren't reading a file
// NULL params are format and demuxer settings, respectively
if (avformat_open_input(&formatContext, "", nullptr, nullptr) < 0){
// Error opening file
}
// Do something with the formatContext
// Free resources!
avformat_close_input(&formatContext);
av_free(ioContext);
ファイルからの読み込み
ローカルファイルシステムからメディアファイルを開く。
AVFormatContext *formatContext;
// Open the file
if(avformat_open_file(&formatContext, "path/to/file.ogg", NULL, NULL) < 0){
// Error opening file
}
// Do something with the file
// Free resources
avformat_close_input(&formatContext);
書式コンテキストからの読み込み
形式には、1つまたは複数のエンコードされたストリームと多重化されたストリームが含まれます。通常はフレームと呼ばれるチャンクで読み込みます(FFmpegは、デコードされた未加工のメディアチャンクをフレームとして、エンコードされたチャンクをパケットとして参照しますが、混乱する可能性があります)。フォーマットから1つのフレームを読み込むには、以下を使用します。
// A Format Context - see other examples on how to create it
AVFormatContext *formatContext;
// Initialize the AVPacket manually
AVPacket avPacket;
av_init_packet(&avPacket); // set fields of avPacket to default.
avPacket.data = NULL;
avPacket.size = 0;
// Read from the context into the packet
if(av_read_frame(formatContext, &avPacket) == 0){
// nothing read
}
// Use the packet (such as decoding it and playing it)
// Free packet
av_packet_unref(&avPacket);
IOContext内のIStreamからの読み込み
カスタムIOコンテキストを設定するAPI呼び出しavio_alloc_contextは、Read関数へのポインタを受け取ります。 IStreamから読み込んでいる場合は、次を使用できます。
/**
* Reads from an IStream into FFmpeg.
*
* @param ptr A pointer to the user-defined IO data structure.
* @param buf A buffer to read into.
* @param buf_size The size of the buffer buff.
*
* @return The number of bytes read into the buffer.
*/
int FileStreamRead(void* ptr, uint8_t* buf, int buf_size)
{
// This is your IStream
IStream* stream = reinterpret_cast<IStream*>(ptr);
ULONG bytesRead = 0;
HRESULT hr = stream->Read(buf, buf_size, &bytesRead);
if(hr == S_FALSE)
return AVERROR_EOF; // End of file
if(FAILED(hr))
return -1;
return bytesRead;
}
IOContext内のIStream内で検索する
カスタムIOコンテキストを設定するAPIコールavio_alloc_contextは、 Seek関数へのポインタを受け取ります。 IStreamから読み込んでいる場合は、次を使用できます。
/**
* Seeks to a given position on an IStream.
*
* @param ptr A pointer to the user-defined IO data structure.
* @param pos The position to seek to.
* @param origin The relative point (origin) from which the seek is performed.
*
* @return The new position in the IStream.
*/
int64_t FileStreamSeek(void* ptr, int64_t pos, int origin){
// Your custom IStream
IStream* stream = reinterpret_cast<IStream*>(ptr);
// Prevent overflows
LARGE_INTEGER in = { pos };
ULARGE_INTEGER out = { 0 };
// Origin is an item from STREAM_SEEK enum.
// STREAM_SEEK_SET - relative to beginning of stream.
// STREAM_SEEK_CUR - relative to current position in stream.
// STREAM_SEEK_END - relative to end of stream.
if(FAILED(stream->Seek(in, origin, &out)))
return -1;
// Return the new position
return out.QuadPart;
}
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow