From 292df969e8f61ba5c0b8f6109eefbac135e0a137 Mon Sep 17 00:00:00 2001 From: Stepan Mikhailiuk Date: Thu, 1 Feb 2024 12:28:18 -0800 Subject: [PATCH 1/2] fix(*): fix external buffers --- src/frame.cc | 5 +++-- src/governor.cc | 2 +- src/packet.cc | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/frame.cc b/src/frame.cc index baf9d4b..19dee34 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -1066,6 +1066,7 @@ napi_value getFrameData(napi_env env, napi_callback_info info) { ref = f->frame->buf[0] ? av_buffer_ref(f->frame->buf[0]) : nullptr; size = ref ? ref->size : 0; curElem = 0; + void* resultData; // work through frame bufs checking whether allocation refcounts are shared for ( int x = 1 ; x < AV_NUM_DATA_POINTERS ; x++ ) { // printf("Buffer %i is %p\n", x, f->frame->data[x]); @@ -1073,7 +1074,7 @@ napi_value getFrameData(napi_env env, napi_callback_info info) { size_t bufSize = size; if (f->frame->buf[x] == nullptr) bufSize = f->frame->data[x] - f->frame->data[x-1]; - status = napi_create_external_buffer(env, bufSize, data, frameBufferFinalizer, ref, &element); + status = napi_create_buffer_copy(env, bufSize, data, &resultData, &element); CHECK_STATUS; status = napi_set_element(env, array, curElem, element); CHECK_STATUS; @@ -1088,7 +1089,7 @@ napi_value getFrameData(napi_env env, napi_callback_info info) { curElem++; } if (data) { - status = napi_create_external_buffer(env, size, data, frameBufferFinalizer, ref, &element); + status = napi_create_buffer_copy(env, size, data, &resultData, &element); CHECK_STATUS; status = napi_set_element(env, array, curElem, element); CHECK_STATUS; diff --git a/src/governor.cc b/src/governor.cc index e77bdb7..4544ec7 100644 --- a/src/governor.cc +++ b/src/governor.cc @@ -56,7 +56,7 @@ void readComplete(napi_env env, napi_status asyncStatus, void *data) { } REJECT_STATUS; - c->status = napi_create_external_buffer(env, c->readLen, c->readBuf, readFinalizer, (void*)(uint64_t)c->readLen, &result); + c->status = napi_create_buffer(env, c->readLen, &c->readBuf, &result); REJECT_STATUS; c->status = napi_adjust_external_memory(env, c->readLen, &externalMemory); diff --git a/src/packet.cc b/src/packet.cc index 80dddf7..f393771 100644 --- a/src/packet.cc +++ b/src/packet.cc @@ -127,6 +127,7 @@ napi_value getPacketData(napi_env env, napi_callback_info info) { napi_value result; packetData* p; AVBufferRef* hintRef; + void* resultData; status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &p); CHECK_STATUS; @@ -135,8 +136,7 @@ napi_value getPacketData(napi_env env, napi_callback_info info) { status = napi_get_null(env, &result); } else { hintRef = av_buffer_ref(p->packet->buf); - status = napi_create_external_buffer(env, hintRef->size, hintRef->data, - packetBufferFinalizer, hintRef, &result); + status = napi_create_buffer_copy(env, hintRef->size, hintRef->data, &resultData, &result); CHECK_STATUS; } From 9c5eb8a528c424e2b8cde8395a31fb05a7e303f3 Mon Sep 17 00:00:00 2001 From: Stepan Mikhailiuk Date: Fri, 19 Sep 2025 23:53:18 +0800 Subject: [PATCH 2/2] fix(*): fix YUVA420 access --- src/frame.cc | 62 +++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/src/frame.cc b/src/frame.cc index 19dee34..b0d6f97 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -21,6 +21,7 @@ #include "frame.h" #include "hwcontext.h" +#include napi_value getFrameLinesize(napi_env env, napi_callback_info info) { napi_status status; @@ -1051,51 +1052,42 @@ napi_value getFrameData(napi_env env, napi_callback_info info) { napi_status status; napi_value array, element; frameData* f; - uint8_t* data; - AVBufferRef* ref; - size_t size; - int curElem; - - status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f); + void* resultData; + int curElem = 0; + status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**)&f); CHECK_STATUS; status = napi_create_array(env, &array); CHECK_STATUS; - data = f->frame->data[0]; - ref = f->frame->buf[0] ? av_buffer_ref(f->frame->buf[0]) : nullptr; - size = ref ? ref->size : 0; - curElem = 0; - void* resultData; - // work through frame bufs checking whether allocation refcounts are shared - for ( int x = 1 ; x < AV_NUM_DATA_POINTERS ; x++ ) { - // printf("Buffer %i is %p\n", x, f->frame->data[x]); - if (f->frame->data[x] == nullptr) continue; - size_t bufSize = size; - if (f->frame->buf[x] == nullptr) - bufSize = f->frame->data[x] - f->frame->data[x-1]; - status = napi_create_buffer_copy(env, bufSize, data, &resultData, &element); - CHECK_STATUS; - status = napi_set_element(env, array, curElem, element); - CHECK_STATUS; - data = f->frame->data[x]; - if (f->frame->buf[x]) { - ref = av_buffer_ref(f->frame->buf[x]); - size = ref->size; - } else { - ref = nullptr; - size -= f->frame->data[x] - f->frame->data[x-1]; + AVFrame* frame = f->frame; + enum AVPixelFormat fmt = (enum AVPixelFormat)frame->format; + const AVPixFmtDescriptor* desc = av_pix_fmt_desc_get(fmt); + if (!desc) return array; // unknown format + + for (int x = 0; x < AV_NUM_DATA_POINTERS && frame->data[x]; x++) { + // Determine the number of rows for this plane + int plane_h = frame->height; + + // YUVA420P: Y=full, U/V=half, A=full + if (fmt == AV_PIX_FMT_YUVA420P) { + if (x == 1 || x == 2) plane_h = (frame->height + 1) / 2; } - curElem++; - } - if (data) { - status = napi_create_buffer_copy(env, size, data, &resultData, &element); + // For other planar formats, adjust with chroma subsampling if needed + else if (desc->log2_chroma_h && x > 0) { + plane_h = (frame->height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h; + } + + size_t plane_size = frame->linesize[x] * plane_h; + + // Copy exactly plane_size bytes for this plane + status = napi_create_buffer_copy(env, plane_size, frame->data[x], &resultData, &element); CHECK_STATUS; - status = napi_set_element(env, array, curElem, element); + + status = napi_set_element(env, array, curElem++, element); CHECK_STATUS; } - CHECK_STATUS; return array; }