diff --git a/bin/jni/videomanager.i b/bin/jni/videomanager.i index 1e411953bbf34e2749f49d7bf65b5f801972fbc6..414da8da48d140cad8f9aee185fc0c38514db6ef 100644 --- a/bin/jni/videomanager.i +++ b/bin/jni/videomanager.i @@ -57,7 +57,7 @@ public: %{ -std::map<ANativeWindow*, std::unique_ptr<DRing::FrameBuffer>> windows {}; +std::map<ANativeWindow*, DRing::FrameBuffer> windows {}; std::mutex windows_mutex; std::vector<uint8_t> workspace; @@ -159,13 +159,9 @@ JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_captureVideoPacket(JN auto frame = DRing::getNewFrame(input); if (not frame) return; - auto packet = std::unique_ptr<AVPacket, void(*)(AVPacket*)>(new AVPacket, [](AVPacket* pkt){ - if (pkt) { - av_packet_unref(pkt); - delete pkt; - } + auto packet = std::unique_ptr<AVPacket, void(*)(AVPacket*)>(av_packet_alloc(), [](AVPacket* pkt){ + av_packet_free(&pkt); }); - av_init_packet(packet.get()); if (keyframe) packet->flags = AV_PKT_FLAG_KEY; setRotation(rotation); @@ -314,7 +310,7 @@ JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_setNativeWindowGeomet ANativeWindow_setBuffersGeometry(window, width, height, WINDOW_FORMAT_RGBX_8888); } -void releaseBuffer(ANativeWindow *window, std::unique_ptr<DRing::FrameBuffer> frame) +void releaseBuffer(ANativeWindow *window, DRing::FrameBuffer frame) { std::unique_lock<std::mutex> guard(windows_mutex); try { @@ -324,16 +320,16 @@ void releaseBuffer(ANativeWindow *window, std::unique_ptr<DRing::FrameBuffer> fr } } -void AndroidDisplayCb(ANativeWindow *window, std::unique_ptr<DRing::FrameBuffer> frame) +void AndroidDisplayCb(ANativeWindow *window, DRing::FrameBuffer frame) { ANativeWindow_unlockAndPost(window); releaseBuffer(window, std::move(frame)); } -std::unique_ptr<DRing::FrameBuffer> sinkTargetPullCallback(ANativeWindow *window, std::size_t bytes) +DRing::FrameBuffer sinkTargetPullCallback(ANativeWindow *window) { try { - std::unique_ptr<DRing::FrameBuffer> frame; + DRing::FrameBuffer frame; { std::lock_guard<std::mutex> guard(windows_mutex); frame = std::move(windows.at(window)); @@ -341,11 +337,11 @@ std::unique_ptr<DRing::FrameBuffer> sinkTargetPullCallback(ANativeWindow *window if (frame) { ANativeWindow_Buffer buffer; if (ANativeWindow_lock(window, &buffer, nullptr) == 0) { - frame->avframe->format = AV_PIX_FMT_RGBA; - frame->avframe->width = buffer.width; - frame->avframe->height = buffer.height; - frame->avframe->data[0] = (uint8_t *) buffer.bits; - frame->avframe->linesize[0] = buffer.stride * 4; + frame->format = AV_PIX_FMT_RGBA; + frame->width = buffer.width; + frame->height = buffer.height; + frame->data[0] = (uint8_t *) buffer.bits; + frame->linesize[0] = buffer.stride * 4; return frame; } else { __android_log_print(ANDROID_LOG_WARN, TAG, "Can't lock window"); @@ -371,13 +367,11 @@ JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_registerVideoCallback ANativeWindow* nativeWindow = (ANativeWindow*)((intptr_t) window); auto f_display_cb = std::bind(&AndroidDisplayCb, nativeWindow, std::placeholders::_1); - auto p_display_cb = std::bind(&sinkTargetPullCallback, nativeWindow, std::placeholders::_1); + auto p_display_cb = std::bind(&sinkTargetPullCallback, nativeWindow); { std::lock_guard<std::mutex> guard(windows_mutex); - auto buf = std::make_unique<DRing::FrameBuffer>(); - buf->avframe.reset(av_frame_alloc()); - windows.emplace(nativeWindow, std::move(buf)); + windows.emplace(nativeWindow, av_frame_alloc()); } DRing::registerSinkTarget(sink, DRing::SinkTarget {.pull=p_display_cb, .push=f_display_cb}); } diff --git a/src/jami/videomanager_interface.h b/src/jami/videomanager_interface.h index 2a0d13f4689f4e0efd78ed5e2a50d4477c2b26c3..a53cb16903af451100fc582949190db85c0a755d 100644 --- a/src/jami/videomanager_interface.h +++ b/src/jami/videomanager_interface.h @@ -157,26 +157,16 @@ private: void setGeometry(int format, int width, int height) noexcept; }; -/* FrameBuffer is a generic video frame container */ -struct DRING_PUBLIC FrameBuffer -{ - uint8_t* ptr {nullptr}; // data as a plain raw pointer - std::size_t ptrSize {0}; // size in byte of ptr array - int format {0}; // as listed by AVPixelFormat (avutils/pixfmt.h) - int width {0}; // frame width - int height {0}; // frame height - std::vector<uint8_t> storage; - // If set, new frame will be written to this buffer instead - std::unique_ptr<AVFrame, void (*)(AVFrame*)> avframe {nullptr, [](AVFrame* frame) { - av_frame_free(&frame); - }}; +struct DRING_PUBLIC AVFrame_deleter { + void operator()(AVFrame* frame) const { av_frame_free(&frame); } }; +typedef std::unique_ptr<AVFrame, AVFrame_deleter> FrameBuffer; + struct DRING_PUBLIC SinkTarget { - using FrameBufferPtr = std::unique_ptr<FrameBuffer>; - std::function<FrameBufferPtr(std::size_t bytes)> pull; - std::function<void(FrameBufferPtr)> push; + std::function<FrameBuffer()> pull; + std::function<void(FrameBuffer)> push; }; struct DRING_PUBLIC AVSinkTarget diff --git a/src/media/media_buffer.h b/src/media/media_buffer.h index ef287e0576ab682c1dc4a53b8ddbb3ded940f84b..3752d84632f01fa5dcd1e3cab18eb2139e810bda 100644 --- a/src/media/media_buffer.h +++ b/src/media/media_buffer.h @@ -27,14 +27,6 @@ #include <memory> #include <functional> -extern "C" { -struct AVFrame; -} - -namespace DRing { -struct FrameBuffer; // from jami/videomanager_interface.h -} - namespace jami { using MediaFrame = DRing::MediaFrame; diff --git a/src/media/video/sinkclient.cpp b/src/media/video/sinkclient.cpp index 4dcbf2bba5b10472b83ca89a774e43de0917a08f..0195b4ed5eb1dc230bde0c757e3e8b81584fb3a9 100644 --- a/src/media/video/sinkclient.cpp +++ b/src/media/video/sinkclient.cpp @@ -438,24 +438,9 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/, if (target_.pull) { int width = frame->width(); int height = frame->height(); -#if defined(__ANDROID__) || (defined(__APPLE__) && !TARGET_OS_IPHONE) - const int format = AV_PIX_FMT_RGBA; -#else - const int format = AV_PIX_FMT_BGRA; -#endif - const auto bytes = videoFrameSize(format, width, height); - if (bytes > 0) { - if (auto buffer_ptr = target_.pull(bytes)) { - if (buffer_ptr->avframe) { - scaler_->scale(*frame, buffer_ptr->avframe.get()); - } else { - buffer_ptr->format = format; - buffer_ptr->width = width; - buffer_ptr->height = height; - VideoFrame dst; - dst.setFromMemory(buffer_ptr->ptr, format, width, height); - scaler_->scale(*frame, dst); - } + if (width > 0 && height > 0) { + if (auto buffer_ptr = target_.pull()) { + scaler_->scale(*frame, buffer_ptr.get()); target_.push(std::move(buffer_ptr)); } }