Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/native-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ export interface NativeModule {
videoDecoders: number;
audioEncoders: number;
audioDecoders: number;
imageDecoders: number;
queue: number;
process: number;
frames: number;
Expand Down
2 changes: 2 additions & 0 deletions src/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ Napi::Value GetCountersJS(const Napi::CallbackInfo& info) {
static_cast<double>(webcodecs::counterAudioEncoders.load()));
counters.Set("audioDecoders",
static_cast<double>(webcodecs::counterAudioDecoders.load()));
counters.Set("imageDecoders",
static_cast<double>(webcodecs::counterImageDecoders.load()));

// Legacy counters (for backwards compatibility)
counters.Set("queue", webcodecs::counterQueue.load());
Expand Down
5 changes: 5 additions & 0 deletions src/common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ static std::atomic<int64_t>& GetCounterAudioDecoders() {
static auto* counter = new std::atomic<int64_t>(0);
return *counter;
}
static std::atomic<int64_t>& GetCounterImageDecoders() {
static auto* counter = new std::atomic<int64_t>(0);
return *counter;
}

// Legacy counters (maintained for backwards compatibility)
static std::atomic<int>& GetCounterQueue() {
Expand All @@ -75,6 +79,7 @@ std::atomic<int64_t>& counterVideoEncoders = GetCounterVideoEncoders();
std::atomic<int64_t>& counterVideoDecoders = GetCounterVideoDecoders();
std::atomic<int64_t>& counterAudioEncoders = GetCounterAudioEncoders();
std::atomic<int64_t>& counterAudioDecoders = GetCounterAudioDecoders();
std::atomic<int64_t>& counterImageDecoders = GetCounterImageDecoders();

std::atomic<int>& counterQueue = GetCounterQueue();
std::atomic<int>& counterProcess = GetCounterProcess();
Expand Down
1 change: 1 addition & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ extern std::atomic<int64_t>& counterVideoEncoders;
extern std::atomic<int64_t>& counterVideoDecoders;
extern std::atomic<int64_t>& counterAudioEncoders;
extern std::atomic<int64_t>& counterAudioDecoders;
extern std::atomic<int64_t>& counterImageDecoders;

// Legacy counters (maintained for backwards compatibility)
extern std::atomic<int>& counterQueue;
Expand Down
39 changes: 39 additions & 0 deletions src/ffmpeg_raii.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,40 @@ struct AVFilterInOutDeleter {
}
};

// Forward declare MemoryBufferContext from image_decoder.cc
struct MemoryBufferContext;

// MemoryBufferContext deleter (custom delete)
// Used by ImageDecoder for in-memory buffer I/O context
struct MemoryBufferContextDeleter {
void operator()(MemoryBufferContext* ctx) const noexcept { delete ctx; }
};

// AVIOContext deleter (handles avio_context_free semantics)
// NOTE: Also frees the internal buffer allocated with av_malloc
struct AVIOContextDeleter {
void operator()(AVIOContext* ctx) const noexcept {
if (ctx) {
// Free the buffer allocated with av_malloc before freeing context
if (ctx->buffer) {
av_freep(&ctx->buffer);
}
avio_context_free(&ctx);
}
}
};

// AVFormatContext deleter for image decoding (uses alloc + close_input)
// Also cleans up associated AVIO context stored in ctx->pb
struct ImageFormatContextDeleter {
void operator()(AVFormatContext* ctx) const noexcept {
if (ctx) {
// avformat_close_input handles both the context and its streams
avformat_close_input(&ctx);
}
}
};

// Type aliases for convenient usage
using AVFramePtr = std::unique_ptr<AVFrame, AVFrameDeleter>;
using AVPacketPtr = std::unique_ptr<AVPacket, AVPacketDeleter>;
Expand All @@ -128,6 +162,11 @@ using AVFormatContextOutputPtr =
std::unique_ptr<AVFormatContext, AVFormatContextOutputDeleter>;
using AVFilterGraphPtr = std::unique_ptr<AVFilterGraph, AVFilterGraphDeleter>;
using AVFilterInOutPtr = std::unique_ptr<AVFilterInOut, AVFilterInOutDeleter>;
using MemoryBufferContextPtr =
std::unique_ptr<MemoryBufferContext, MemoryBufferContextDeleter>;
using AVIOContextPtr = std::unique_ptr<AVIOContext, AVIOContextDeleter>;
using ImageFormatContextPtr =
std::unique_ptr<AVFormatContext, ImageFormatContextDeleter>;

// Factory functions for cleaner allocation
inline AVFramePtr make_frame() { return AVFramePtr(av_frame_alloc()); }
Expand Down
Loading