Skip to content

Commit 11cbc0e

Browse files
committed
Allow wrap external data into VideoFrame
1 parent 9b27e12 commit 11cbc0e

2 files changed

Lines changed: 102 additions & 0 deletions

File tree

src/frame.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,20 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src)
8181

8282
#endif // LIBAVUTIL_VERSION_INT <= 53.5.0 (ffmpeg 2.2)
8383

84+
void avcpp_null_deleter(void* /*opaque*/, uint8_t */*data*/)
85+
{
86+
}
87+
8488
} // anonymous namespace
8589

8690
namespace av
8791
{
8892

93+
VideoFrame::VideoFrame()
94+
{
95+
96+
}
97+
8998
VideoFrame::VideoFrame(PixelFormat pixelFormat, int width, int height, int align)
9099
{
91100
m_raw->format = pixelFormat;
@@ -231,6 +240,49 @@ bool VideoFrame::copyToBuffer(std::vector<uint8_t> &dst, int align, OptionalErro
231240
return copyToBuffer(dst.data(), dst.size(), align, ec);
232241
}
233242

243+
namespace {
244+
VideoFrame _wrap(const void *data, size_t size, PixelFormat pixelFormat, int width, int height, int align,
245+
void (*deleter)(void *opaque, uint8_t *data), void *opaque)
246+
{
247+
VideoFrame out;
248+
249+
auto frame = out.raw();
250+
251+
frame->format = pixelFormat;
252+
frame->width = width;
253+
frame->height = height;
254+
255+
// setup buffers
256+
frame->buf[0] = av_buffer_create(const_cast<uint8_t*>(static_cast<const uint8_t*>(data)), size, deleter, opaque, AV_BUFFER_FLAG_READONLY);
257+
258+
av_image_fill_arrays(frame->data,
259+
frame->linesize,
260+
frame->buf[0]->data,
261+
pixelFormat, width, height, align);
262+
263+
frame->extended_data = frame->data;
264+
265+
return out;
266+
}
267+
}
268+
269+
VideoFrame VideoFrame::wrap(const void *data, size_t size, PixelFormat pixelFormat, int width, int height, int align)
270+
{
271+
return _wrap(data, size, pixelFormat, width, height, align, avcpp_null_deleter, nullptr);
272+
}
273+
274+
#ifdef __cpp_lib_span
275+
VideoFrame VideoFrame::wrap(std::span<const std::byte> data, PixelFormat pixelFormat, int width, int height, int align)
276+
{
277+
return wrap(data.data(), data.size(), pixelFormat, width, height, align);
278+
}
279+
280+
VideoFrame VideoFrame::wrap(std::span<const std::byte> data, void (*deleter)(void *opaque, uint8_t *data),
281+
void *opaque, PixelFormat pixelFormat, int width, int height, int align)
282+
{
283+
return _wrap(data.data(), data.size(), pixelFormat, width, height, align, deleter, opaque);
284+
}
285+
#endif
234286

235287
AudioSamples::AudioSamples(SampleFormat sampleFormat, int samplesCount, uint64_t channelLayout, int sampleRate, int align)
236288
{

src/frame.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,56 @@ class VideoFrame : public Frame<VideoFrame>
385385
size_t bufferSize(int align = 1, OptionalErrorCode ec = throws()) const;
386386
bool copyToBuffer(uint8_t *dst, size_t size, int align = 1, OptionalErrorCode ec = throws());
387387
bool copyToBuffer(std::vector<uint8_t>& dst, int align = 1, OptionalErrorCode ec = throws());
388+
389+
390+
/**
391+
* Wrap external data into VideoFrame object ready to use with FFmpeg/AvCpp.
392+
*
393+
* @note Ownershipping does not acquired.
394+
*
395+
* @param data data pointer to wrap
396+
* @param size whole data buffer size with alignment and real data
397+
* @param pixelFormat pixel format of the data
398+
* @param width image width
399+
* @param height image height
400+
* @param align image data alignemnt
401+
*
402+
* @return image data wrapped into VideoFrame object
403+
*/
404+
static VideoFrame wrap(const void *data, size_t size, PixelFormat pixelFormat, int width, int height, int align = 1);
405+
406+
#ifdef __cpp_lib_span
407+
/**
408+
* Wrap external data into VideoFrame object ready to use with FFmpeg/AvCpp.
409+
*
410+
* @note Ownershipping does not acquired.
411+
412+
* @param data external image data wrapped into std::span
413+
* @param pixelFormat pixel format of the data
414+
* @param width image width
415+
* @param height image height
416+
* @param align image data alignment
417+
* @return
418+
*/
419+
static VideoFrame wrap(std::span<const std::byte> data, PixelFormat pixelFormat, int width, int height, int align = 1);
420+
421+
/**
422+
* Wrap external data into VideoFrame object ready to use with FFmpeg/AvCpp.
423+
*
424+
* @note Ownershipping does not acquired. When data wants to be deleted, passed deleter function will be called.
425+
426+
* @param data external image data wrapped into std::span
427+
* @param deleter user defined deleter
428+
* @param opaque opaque data passed to the deleter, maybe nullptr
429+
* @param pixelFormat pixel format of the data
430+
* @param width image width
431+
* @param height image height
432+
* @param align image data alignment
433+
* @return
434+
*/
435+
static VideoFrame wrap(std::span<const std::byte> data, void (*deleter)(void *opaque, uint8_t *data),
436+
void *opaque, PixelFormat pixelFormat, int width, int height, int align = 1);
437+
#endif
388438
};
389439

390440

0 commit comments

Comments
 (0)