mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
avdevice/decklink_dec: use a custom memory allocator
The default memory allocator is limited in the max number of frames available, and therefore caused frame drops if the frames were not freed fast enough. Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
parent
8a0c2901f1
commit
643123b29d
@ -21,6 +21,9 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
using std::atomic;
|
||||||
|
|
||||||
/* Include internal.h first to avoid conflict between winsock.h (used by
|
/* Include internal.h first to avoid conflict between winsock.h (used by
|
||||||
* DeckLink headers) and winsock2.h (used by libavformat) in MSVC++ builds */
|
* DeckLink headers) and winsock2.h (used by libavformat) in MSVC++ builds */
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -98,6 +101,44 @@ static VANCLineNumber vanc_line_numbers[] = {
|
|||||||
{bmdModeUnknown, 0, -1, -1, -1}
|
{bmdModeUnknown, 0, -1, -1, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class decklink_allocator : public IDeckLinkMemoryAllocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
decklink_allocator(): _refs(1) { }
|
||||||
|
virtual ~decklink_allocator() { }
|
||||||
|
|
||||||
|
// IDeckLinkMemoryAllocator methods
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE AllocateBuffer(unsigned int bufferSize, void* *allocatedBuffer)
|
||||||
|
{
|
||||||
|
void *buf = av_malloc(bufferSize + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
if (!buf)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
*allocatedBuffer = buf;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE ReleaseBuffer(void* buffer)
|
||||||
|
{
|
||||||
|
av_free(buffer);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Commit() { return S_OK; }
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Decommit() { return S_OK; }
|
||||||
|
|
||||||
|
// IUnknown methods
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
|
||||||
|
virtual ULONG STDMETHODCALLTYPE AddRef(void) { return ++_refs; }
|
||||||
|
virtual ULONG STDMETHODCALLTYPE Release(void)
|
||||||
|
{
|
||||||
|
int ret = --_refs;
|
||||||
|
if (!ret)
|
||||||
|
delete this;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic<int> _refs;
|
||||||
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static void decklink_object_free(void *opaque, uint8_t *data)
|
static void decklink_object_free(void *opaque, uint8_t *data)
|
||||||
{
|
{
|
||||||
@ -924,6 +965,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
|
|||||||
{
|
{
|
||||||
struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
|
struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
|
||||||
struct decklink_ctx *ctx;
|
struct decklink_ctx *ctx;
|
||||||
|
class decklink_allocator *allocator;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
char fname[1024];
|
char fname[1024];
|
||||||
@ -1017,6 +1059,14 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
|
|||||||
ctx->input_callback = new decklink_input_callback(avctx);
|
ctx->input_callback = new decklink_input_callback(avctx);
|
||||||
ctx->dli->SetCallback(ctx->input_callback);
|
ctx->dli->SetCallback(ctx->input_callback);
|
||||||
|
|
||||||
|
allocator = new decklink_allocator();
|
||||||
|
ret = (ctx->dli->SetVideoInputFrameMemoryAllocator(allocator) == S_OK ? 0 : AVERROR_EXTERNAL);
|
||||||
|
allocator->Release();
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "Cannot set custom memory allocator\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode_num == 0 && !cctx->format_code) {
|
if (mode_num == 0 && !cctx->format_code) {
|
||||||
if (decklink_autodetect(cctx) < 0) {
|
if (decklink_autodetect(cctx) < 0) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Cannot Autodetect input stream or No signal\n");
|
av_log(avctx, AV_LOG_ERROR, "Cannot Autodetect input stream or No signal\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user