Skip to content
Snippets Groups Projects
Commit 6fe27867 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

sinkclient: allow to provide custom buffer

Change-Id: I1c3d2943f3347fa9214456a2e180b0836bd6420f
parent 15bdc648
Branches
No related tags found
No related merge requests found
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
extern "C" { extern "C" {
struct AVFrame; struct AVFrame;
struct AVPacket; struct AVPacket;
void av_frame_free(AVFrame **frame);
} }
#include "def.h" #include "def.h"
...@@ -52,24 +53,6 @@ namespace DRing { ...@@ -52,24 +53,6 @@ namespace DRing {
[[deprecated("Replaced by registerSignalHandlers")]] DRING_PUBLIC void registerVideoHandlers( [[deprecated("Replaced by registerSignalHandlers")]] DRING_PUBLIC void registerVideoHandlers(
const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&); const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&);
/* 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;
};
struct DRING_PUBLIC SinkTarget
{
using FrameBufferPtr = std::unique_ptr<FrameBuffer>;
std::function<FrameBufferPtr(std::size_t bytes)> pull;
std::function<void(FrameBufferPtr)> push;
};
class DRING_PUBLIC MediaFrame class DRING_PUBLIC MediaFrame
{ {
public: public:
...@@ -171,6 +154,27 @@ private: ...@@ -171,6 +154,27 @@ private:
void setGeometry(int format, int width, int height) noexcept; 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 SinkTarget
{
using FrameBufferPtr = std::unique_ptr<FrameBuffer>;
std::function<FrameBufferPtr(std::size_t bytes)> pull;
std::function<void(FrameBufferPtr)> push;
};
struct DRING_PUBLIC AVSinkTarget struct DRING_PUBLIC AVSinkTarget
{ {
std::function<void(std::unique_ptr<VideoFrame>)> push; std::function<void(std::unique_ptr<VideoFrame>)> push;
......
...@@ -437,7 +437,6 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/, ...@@ -437,7 +437,6 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/,
#endif #endif
std::lock_guard<std::mutex> lock(mtx_); std::lock_guard<std::mutex> lock(mtx_);
if (target_.pull) { if (target_.pull) {
VideoFrame dst;
width = frame->width(); width = frame->width();
height = frame->height(); height = frame->height();
#if defined(__ANDROID__) || (defined(__APPLE__) && !TARGET_OS_IPHONE) #if defined(__ANDROID__) || (defined(__APPLE__) && !TARGET_OS_IPHONE)
...@@ -448,11 +447,16 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/, ...@@ -448,11 +447,16 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/,
const auto bytes = videoFrameSize(format, width, height); const auto bytes = videoFrameSize(format, width, height);
if (bytes > 0) { if (bytes > 0) {
if (auto buffer_ptr = target_.pull(bytes)) { 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->format = format;
buffer_ptr->width = width; buffer_ptr->width = width;
buffer_ptr->height = height; buffer_ptr->height = height;
VideoFrame dst;
dst.setFromMemory(buffer_ptr->ptr, format, width, height); dst.setFromMemory(buffer_ptr->ptr, format, width, height);
scaler_->scale(*frame, dst); scaler_->scale(*frame, dst);
}
target_.push(std::move(buffer_ptr)); target_.push(std::move(buffer_ptr));
} }
} }
......
...@@ -41,10 +41,14 @@ VideoScaler::~VideoScaler() ...@@ -41,10 +41,14 @@ VideoScaler::~VideoScaler()
} }
void void
VideoScaler::scale(const VideoFrame& input, VideoFrame& output) VideoScaler::scale(const VideoFrame& input, VideoFrame& output){
scale(input, output.pointer());
}
void
VideoScaler::scale(const VideoFrame& input, AVFrame* output_frame)
{ {
const auto input_frame = input.pointer(); const auto input_frame = input.pointer();
auto output_frame = output.pointer();
ctx_ = sws_getCachedContext(ctx_, ctx_ = sws_getCachedContext(ctx_,
input_frame->width, input_frame->width,
......
...@@ -26,6 +26,10 @@ ...@@ -26,6 +26,10 @@
struct SwsContext; struct SwsContext;
extern "C" {
struct AVFrame;
}
namespace jami { namespace jami {
namespace video { namespace video {
...@@ -35,6 +39,7 @@ public: ...@@ -35,6 +39,7 @@ public:
VideoScaler(); VideoScaler();
~VideoScaler(); ~VideoScaler();
void reset(); void reset();
void scale(const VideoFrame& input, AVFrame* output);
void scale(const VideoFrame& input, VideoFrame& output); void scale(const VideoFrame& input, VideoFrame& output);
void scale_with_aspect(const VideoFrame& input, VideoFrame& output); void scale_with_aspect(const VideoFrame& input, VideoFrame& output);
void scale_and_pad(const VideoFrame& input, void scale_and_pad(const VideoFrame& input,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment