Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions src/framework/mlt_frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "mlt_log.h"
#include "mlt_producer.h"
#include "mlt_profile.h"
#include "mlt_slices.h"

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -1334,6 +1335,41 @@ mlt_properties mlt_frame_get_unique_properties(mlt_frame self, mlt_service servi
return mlt_properties_get_data(MLT_FRAME_PROPERTIES(self), unique, NULL);
}

struct copy_slice_context
{
uint8_t *dst;
const uint8_t *src;
int size;
};

static int copy_slice(int id, int index, int count, void *cookie)
{
struct copy_slice_context *ctx = cookie;
int start;
int size = mlt_slices_size_slice(count, index, ctx->size, &start);
memcpy(ctx->dst + start, ctx->src + start, size);
return 0;
}

/** The size from which copy_buffer() uses several threads. Images up to 1080p yuv422
* (about 4 MB) are copied with one memcpy() as before; 4K images and 1080p rgba
* images are copied in slices.
*/
#define SLICED_COPY_MIN_SIZE (4 << 20)

/** Copy a buffer, in slices on several threads when it is large, because one thread
* cannot use all of the memory bandwidth.
*/
static void copy_buffer(void *dst, const void *src, int size)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calls mlt_slices_run_normal from a public framework function. If a slice job anywhere, including in third-party modules, clones a frame, the global pool can deadlock. "No slice job in MLT clones a frame" is not a guarantee, and the gain is about 1.3 ms per frame. It isn't worth the risk.

{
if (size < SLICED_COPY_MIN_SIZE) {
memcpy(dst, src, size);
return;
}
struct copy_slice_context ctx = {.dst = dst, .src = src, .size = size};
mlt_slices_run_normal(0, copy_slice, &ctx);
}

/** Make a copy of a frame.
*
* This does not copy the get_image/get_audio processing stacks or any
Expand Down Expand Up @@ -1387,7 +1423,7 @@ mlt_frame mlt_frame_clone(mlt_frame self, int is_deep)
if (!size)
size = mlt_image_format_size(format, width, height, NULL);
copy = mlt_pool_alloc(size);
memcpy(copy, data, size);
copy_buffer(copy, data, size);
mlt_properties_set_data(new_props, "image", copy, size, mlt_pool_release, NULL);

size = 0;
Expand All @@ -1396,7 +1432,7 @@ mlt_frame mlt_frame_clone(mlt_frame self, int is_deep)
if (!size)
size = width * height;
copy = mlt_pool_alloc(size);
memcpy(copy, data, size);
copy_buffer(copy, data, size);
mlt_properties_set_data(new_props, "alpha", copy, size, mlt_pool_release, NULL);
};
}
Expand Down Expand Up @@ -1527,7 +1563,7 @@ mlt_frame mlt_frame_clone_image(mlt_frame self, int is_deep)
if (!size)
size = mlt_image_format_size(format, width, height, NULL);
copy = mlt_pool_alloc(size);
memcpy(copy, data, size);
copy_buffer(copy, data, size);
mlt_properties_set_data(new_props, "image", copy, size, mlt_pool_release, NULL);

size = 0;
Expand All @@ -1536,7 +1572,7 @@ mlt_frame mlt_frame_clone_image(mlt_frame self, int is_deep)
if (!size)
size = width * height;
copy = mlt_pool_alloc(size);
memcpy(copy, data, size);
copy_buffer(copy, data, size);
mlt_properties_set_data(new_props, "alpha", copy, size, mlt_pool_release, NULL);
};
}
Expand Down
61 changes: 21 additions & 40 deletions src/modules/avformat/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,60 +239,41 @@ mlt_channel_layout mlt_get_channel_layout_or_default(const char *name, int chann
return layout;
}

const int *mlt_get_sws_coefficients(mlt_colorspace colorspace)
{
switch (colorspace) {
case mlt_colorspace_smpte170m:
case mlt_colorspace_bt470bg:
case mlt_colorspace_bt601:
return sws_getCoefficients(SWS_CS_ITU601);
case mlt_colorspace_smpte240m:
return sws_getCoefficients(SWS_CS_SMPTE240M);
case mlt_colorspace_bt709:
return sws_getCoefficients(SWS_CS_ITU709);
case mlt_colorspace_bt2020_ncl:
case mlt_colorspace_bt2020_cl:
return sws_getCoefficients(SWS_CS_BT2020);
default:
return sws_getCoefficients(SWS_CS_DEFAULT);
}
}

int mlt_set_luma_transfer(struct SwsContext *context,
mlt_colorspace src_colorspace,
mlt_colorspace dst_colorspace,
int src_full_range,
int dst_full_range)
{
const int *src_coefficients = sws_getCoefficients(SWS_CS_DEFAULT);
const int *dst_coefficients = sws_getCoefficients(SWS_CS_DEFAULT);
int brightness = 0;
int contrast = 1 << 16;
int saturation = 1 << 16;
int src_range = src_full_range ? 1 : 0;
int dst_range = dst_full_range ? 1 : 0;

switch (src_colorspace) {
case mlt_colorspace_smpte170m:
case mlt_colorspace_bt470bg:
case mlt_colorspace_bt601:
src_coefficients = sws_getCoefficients(SWS_CS_ITU601);
break;
case mlt_colorspace_smpte240m:
src_coefficients = sws_getCoefficients(SWS_CS_SMPTE240M);
break;
case mlt_colorspace_bt709:
src_coefficients = sws_getCoefficients(SWS_CS_ITU709);
break;
case mlt_colorspace_bt2020_ncl:
case mlt_colorspace_bt2020_cl:
src_coefficients = sws_getCoefficients(SWS_CS_BT2020);
default:
break;
}
switch (dst_colorspace) {
case mlt_colorspace_smpte170m:
case mlt_colorspace_bt470bg:
case mlt_colorspace_bt601:
dst_coefficients = sws_getCoefficients(SWS_CS_ITU601);
break;
case mlt_colorspace_smpte240m:
dst_coefficients = sws_getCoefficients(SWS_CS_SMPTE240M);
break;
case mlt_colorspace_bt709:
dst_coefficients = sws_getCoefficients(SWS_CS_ITU709);
break;
case mlt_colorspace_bt2020_ncl:
case mlt_colorspace_bt2020_cl:
dst_coefficients = sws_getCoefficients(SWS_CS_BT2020);
default:
break;
}
return sws_setColorspaceDetails(context,
src_coefficients,
mlt_get_sws_coefficients(src_colorspace),
src_range,
dst_coefficients,
mlt_get_sws_coefficients(dst_colorspace),
dst_range,
brightness,
contrast,
Expand Down
1 change: 1 addition & 0 deletions src/modules/avformat/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ mlt_channel_layout av_channel_layout_to_mlt(AVChannelLayout *layout);
mlt_channel_layout av_channel_layout_to_mlt(int64_t layout);
#endif
mlt_channel_layout mlt_get_channel_layout_or_default(const char *name, int channels);
const int *mlt_get_sws_coefficients(mlt_colorspace colorspace);
int mlt_set_luma_transfer(struct SwsContext *context,
mlt_colorspace src_colorspace,
mlt_colorspace dst_colorspace,
Expand Down
Loading