4#include <libavcodec/avcodec.h>
5#include <libavdevice/avdevice.h>
6#include <libavformat/avformat.h>
7#include <libavutil/opt.h>
32 av_log_set_level(AV_LOG_WARNING);
41 if (avformat_open_input(&
format_context, filepath.c_str(),
nullptr,
nullptr) < 0) {
42 m_last_error =
"avformat_open_input failed: " + filepath;
48 m_last_error =
"avformat_find_stream_info failed: " + filepath;
65 const std::string& format_name,
66 AVDictionary** options)
71 const AVInputFormat* fmt = av_find_input_format(format_name.c_str());
73 m_last_error =
"av_find_input_format failed for: " + format_name;
78 device_name.c_str(), fmt, options);
80 char errbuf[AV_ERROR_MAX_STRING_SIZE];
81 av_strerror(ret, errbuf,
sizeof(errbuf));
83 + device_name +
" (" + errbuf +
")";
89 m_last_error =
"avformat_find_stream_info failed for device: " + device_name;
105 const AVCodec* codec =
nullptr;
106 int idx = av_find_best_stream(
108 static_cast<AVMediaType
>(media_type),
140 int ret = av_seek_frame(
format_context, stream_index, timestamp, AVSEEK_FLAG_BACKWARD);
173 AVDictionaryEntry* tag =
nullptr;
174 while ((tag = av_dict_get(
format_context->metadata,
"", tag, AV_DICT_IGNORE_SUFFIX)))
175 out.
attributes[std::string(
"tag_") + tag->key] = std::string(tag->value);
180 std::vector<FileRegion> regions;
188 r.
name =
"chapter_" + std::to_string(i);
190 AVDictionaryEntry* title = av_dict_get(ch->metadata,
"title",
nullptr, 0);
192 r.
name = title->value;
194 double tb = av_q2d(ch->time_base);
197 r.
attributes[
"chapter_index"] =
static_cast<int>(i);
199 regions.push_back(std::move(r));
208 return static_cast<double>(
format_context->duration) /
static_cast<double>(AV_TIME_BASE);
void flush()
Flush the demuxer's internal read buffers.
bool open(const std::string &filepath)
Open a media file and probe stream information.
static std::mutex s_ffmpeg_init_mutex
AVFormatContext * format_context
Owned; freed in destructor.
void close()
Close the format context and release all demux resources.
static void init_ffmpeg()
Initialise FFmpeg logging level once per process.
bool open_device(const std::string &device_name, const std::string &format_name, AVDictionary **options=nullptr)
Open an FFmpeg device input (camera, screen capture, etc.).
int find_best_stream(int media_type, const void **out_codec=nullptr) const
Find the best stream of the requested media type.
unsigned int stream_count() const
Number of streams in the container.
AVStream * get_stream(int index) const
Access a stream by index.
static std::atomic< bool > s_ffmpeg_initialized
bool seek(int stream_index, int64_t timestamp)
Seek to the nearest keyframe at or before the given timestamp.
std::vector< FileRegion > extract_chapter_regions() const
Extract chapter information as FileRegion entries.
void extract_container_metadata(FileMetadata &out_metadata) const
Extract container-level metadata tags into a FileMetadata attributes map.
double duration_seconds() const
Total container duration in seconds, or 0 if unknown.
std::vector< uint64_t > start_coordinates
N-dimensional start position (e.g., frame, x, y)
std::string name
Human-readable name for the region.
std::string type
Region type identifier (e.g., "cue", "scene", "block")
std::unordered_map< std::string, std::any > attributes
Region-specific metadata.
std::vector< uint64_t > end_coordinates
N-dimensional end position (inclusive)
Generic region descriptor for any file type.