mirror of https://git.ffmpeg.org/ffmpeg.git
pthread_frame: do not embed full AVFrame structs into per-thread contexts
Use the AVFrame API to properly allocate and free frames for delayed release.
This commit is contained in:
parent
e40107c1ad
commit
b630a270f5
|
@ -93,9 +93,9 @@ typedef struct PerThreadContext {
|
||||||
* Array of frames passed to ff_thread_release_buffer().
|
* Array of frames passed to ff_thread_release_buffer().
|
||||||
* Frames are released after all threads referencing them are finished.
|
* Frames are released after all threads referencing them are finished.
|
||||||
*/
|
*/
|
||||||
AVFrame *released_buffers;
|
AVFrame **released_buffers;
|
||||||
int num_released_buffers;
|
int num_released_buffers;
|
||||||
int released_buffers_allocated;
|
int released_buffers_allocated;
|
||||||
|
|
||||||
AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
|
AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
|
||||||
int requested_flags; ///< flags passed to get_buffer() for requested_frame
|
int requested_flags; ///< flags passed to get_buffer() for requested_frame
|
||||||
|
@ -370,7 +370,7 @@ static void release_delayed_buffers(PerThreadContext *p)
|
||||||
// fix extended data in case the caller screwed it up
|
// fix extended data in case the caller screwed it up
|
||||||
av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
|
av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
|
||||||
p->avctx->codec_type == AVMEDIA_TYPE_AUDIO);
|
p->avctx->codec_type == AVMEDIA_TYPE_AUDIO);
|
||||||
f = &p->released_buffers[--p->num_released_buffers];
|
f = p->released_buffers[--p->num_released_buffers];
|
||||||
f->extended_data = f->data;
|
f->extended_data = f->data;
|
||||||
av_frame_unref(f);
|
av_frame_unref(f);
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
|
||||||
{
|
{
|
||||||
FrameThreadContext *fctx = avctx->internal->thread_ctx;
|
FrameThreadContext *fctx = avctx->internal->thread_ctx;
|
||||||
const AVCodec *codec = avctx->codec;
|
const AVCodec *codec = avctx->codec;
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
park_frame_worker_threads(fctx, thread_count);
|
park_frame_worker_threads(fctx, thread_count);
|
||||||
|
|
||||||
|
@ -700,6 +700,9 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
|
||||||
pthread_cond_destroy(&p->progress_cond);
|
pthread_cond_destroy(&p->progress_cond);
|
||||||
pthread_cond_destroy(&p->output_cond);
|
pthread_cond_destroy(&p->output_cond);
|
||||||
av_packet_unref(&p->avpkt);
|
av_packet_unref(&p->avpkt);
|
||||||
|
|
||||||
|
for (j = 0; j < p->released_buffers_allocated; j++)
|
||||||
|
av_frame_free(&p->released_buffers[j]);
|
||||||
av_freep(&p->released_buffers);
|
av_freep(&p->released_buffers);
|
||||||
|
|
||||||
if (p->avctx) {
|
if (p->avctx) {
|
||||||
|
@ -988,7 +991,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
|
||||||
{
|
{
|
||||||
PerThreadContext *p = avctx->internal->thread_ctx;
|
PerThreadContext *p = avctx->internal->thread_ctx;
|
||||||
FrameThreadContext *fctx;
|
FrameThreadContext *fctx;
|
||||||
AVFrame *dst, *tmp;
|
AVFrame *dst;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
|
int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
|
||||||
THREAD_SAFE_CALLBACKS(avctx);
|
THREAD_SAFE_CALLBACKS(avctx);
|
||||||
|
@ -1011,20 +1014,22 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
|
||||||
fctx = p->parent;
|
fctx = p->parent;
|
||||||
pthread_mutex_lock(&fctx->buffer_mutex);
|
pthread_mutex_lock(&fctx->buffer_mutex);
|
||||||
|
|
||||||
if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers)) {
|
if (p->num_released_buffers == p->released_buffers_allocated) {
|
||||||
ret = AVERROR(ENOMEM);
|
AVFrame **tmp = av_realloc_array(p->released_buffers, p->released_buffers_allocated + 1,
|
||||||
goto fail;
|
sizeof(*p->released_buffers));
|
||||||
}
|
if (tmp) {
|
||||||
tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
|
tmp[p->released_buffers_allocated] = av_frame_alloc();
|
||||||
(p->num_released_buffers + 1) *
|
p->released_buffers = tmp;
|
||||||
sizeof(*p->released_buffers));
|
}
|
||||||
if (!tmp) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
p->released_buffers = tmp;
|
|
||||||
|
|
||||||
dst = &p->released_buffers[p->num_released_buffers];
|
if (!tmp || !tmp[p->released_buffers_allocated]) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
p->released_buffers_allocated++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = p->released_buffers[p->num_released_buffers];
|
||||||
av_frame_move_ref(dst, f->f);
|
av_frame_move_ref(dst, f->f);
|
||||||
|
|
||||||
p->num_released_buffers++;
|
p->num_released_buffers++;
|
||||||
|
|
Loading…
Reference in New Issue