mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-04-24 17:12:34 +02:00
avcodec/pthread_frame: Use RefStruct API for ThreadFrame.progress
Avoids allocations and error checks and allows to remove cleanup code for earlier allocations. Also avoids casts and indirections. Reviewed-by: Anton Khirnov <anton@khirnov.net> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
452089ee23
commit
2ec62b1ca6
@ -66,7 +66,7 @@ static inline void get_lowest_part_y(const H264Context *h, H264SliceContext *sl,
|
|||||||
// Error resilience puts the current picture in the ref list.
|
// Error resilience puts the current picture in the ref list.
|
||||||
// Don't try to wait on these as it will cause a deadlock.
|
// Don't try to wait on these as it will cause a deadlock.
|
||||||
// Fields can wait on each other, though.
|
// Fields can wait on each other, though.
|
||||||
if (ref->parent->tf.progress->data != h->cur_pic.tf.progress->data ||
|
if (ref->parent->tf.progress != h->cur_pic.tf.progress ||
|
||||||
(ref->reference & 3) != h->picture_structure) {
|
(ref->reference & 3) != h->picture_structure) {
|
||||||
my = get_lowest_part_list_y(sl, n, height, y_offset, 0);
|
my = get_lowest_part_list_y(sl, n, height, y_offset, 0);
|
||||||
if (refs[0][ref_n] < 0)
|
if (refs[0][ref_n] < 0)
|
||||||
@ -79,7 +79,7 @@ static inline void get_lowest_part_y(const H264Context *h, H264SliceContext *sl,
|
|||||||
int ref_n = sl->ref_cache[1][scan8[n]];
|
int ref_n = sl->ref_cache[1][scan8[n]];
|
||||||
H264Ref *ref = &sl->ref_list[1][ref_n];
|
H264Ref *ref = &sl->ref_list[1][ref_n];
|
||||||
|
|
||||||
if (ref->parent->tf.progress->data != h->cur_pic.tf.progress->data ||
|
if (ref->parent->tf.progress != h->cur_pic.tf.progress ||
|
||||||
(ref->reference & 3) != h->picture_structure) {
|
(ref->reference & 3) != h->picture_structure) {
|
||||||
my = get_lowest_part_list_y(sl, n, height, y_offset, 1);
|
my = get_lowest_part_list_y(sl, n, height, y_offset, 1);
|
||||||
if (refs[1][ref_n] < 0)
|
if (refs[1][ref_n] < 0)
|
||||||
|
@ -66,6 +66,10 @@ enum {
|
|||||||
INITIALIZED, ///< Thread has been properly set up
|
INITIALIZED, ///< Thread has been properly set up
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct ThreadFrameProgress {
|
||||||
|
atomic_int progress[2];
|
||||||
|
} ThreadFrameProgress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context used by codec threads and stored in their AVCodecInternal thread_ctx.
|
* Context used by codec threads and stored in their AVCodecInternal thread_ctx.
|
||||||
*/
|
*/
|
||||||
@ -585,7 +589,7 @@ finish:
|
|||||||
void ff_thread_report_progress(ThreadFrame *f, int n, int field)
|
void ff_thread_report_progress(ThreadFrame *f, int n, int field)
|
||||||
{
|
{
|
||||||
PerThreadContext *p;
|
PerThreadContext *p;
|
||||||
atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
|
atomic_int *progress = f->progress ? f->progress->progress : NULL;
|
||||||
|
|
||||||
if (!progress ||
|
if (!progress ||
|
||||||
atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
|
atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
|
||||||
@ -608,7 +612,7 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field)
|
|||||||
void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
|
void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
|
||||||
{
|
{
|
||||||
PerThreadContext *p;
|
PerThreadContext *p;
|
||||||
atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
|
atomic_int *progress = f->progress ? f->progress->progress : NULL;
|
||||||
|
|
||||||
if (!progress ||
|
if (!progress ||
|
||||||
atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
|
atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
|
||||||
@ -991,20 +995,17 @@ int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
|
|||||||
return ff_get_buffer(avctx, f->f, flags);
|
return ff_get_buffer(avctx, f->f, flags);
|
||||||
|
|
||||||
if (ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS) {
|
if (ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_ALLOCATE_PROGRESS) {
|
||||||
atomic_int *progress;
|
f->progress = ff_refstruct_allocz(sizeof(*f->progress));
|
||||||
f->progress = av_buffer_alloc(2 * sizeof(*progress));
|
if (!f->progress)
|
||||||
if (!f->progress) {
|
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
|
||||||
progress = (atomic_int*)f->progress->data;
|
|
||||||
|
|
||||||
atomic_init(&progress[0], -1);
|
atomic_init(&f->progress->progress[0], -1);
|
||||||
atomic_init(&progress[1], -1);
|
atomic_init(&f->progress->progress[1], -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ff_thread_get_buffer(avctx, f->f, flags);
|
ret = ff_thread_get_buffer(avctx, f->f, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
av_buffer_unref(&f->progress);
|
ff_refstruct_unref(&f->progress);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,7 +1022,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
|
|||||||
|
|
||||||
void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f)
|
void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f)
|
||||||
{
|
{
|
||||||
av_buffer_unref(&f->progress);
|
ff_refstruct_unref(&f->progress);
|
||||||
f->owner[0] = f->owner[1] = NULL;
|
f->owner[0] = f->owner[1] = NULL;
|
||||||
ff_thread_release_buffer(avctx, f->f);
|
ff_thread_release_buffer(avctx, f->f);
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,7 @@
|
|||||||
typedef struct ThreadFrame {
|
typedef struct ThreadFrame {
|
||||||
AVFrame *f;
|
AVFrame *f;
|
||||||
AVCodecContext *owner[2];
|
AVCodecContext *owner[2];
|
||||||
// progress->data is an array of 2 ints holding progress for top/bottom
|
struct ThreadFrameProgress *progress;
|
||||||
// fields
|
|
||||||
AVBufferRef *progress;
|
|
||||||
} ThreadFrame;
|
} ThreadFrame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "codec_par.h"
|
#include "codec_par.h"
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
#include "hwconfig.h"
|
#include "hwconfig.h"
|
||||||
|
#include "refstruct.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "threadframe.h"
|
#include "threadframe.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
@ -880,11 +881,8 @@ int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src)
|
|||||||
|
|
||||||
av_assert0(!dst->progress);
|
av_assert0(!dst->progress);
|
||||||
|
|
||||||
if (src->progress &&
|
if (src->progress)
|
||||||
!(dst->progress = av_buffer_ref(src->progress))) {
|
dst->progress = ff_refstruct_ref(src->progress);
|
||||||
ff_thread_release_ext_buffer(dst->owner[0], dst);
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -901,11 +899,7 @@ int ff_thread_replace_frame(AVCodecContext *avctx, ThreadFrame *dst,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = av_buffer_replace(&dst->progress, src->progress);
|
ff_refstruct_replace(&dst->progress, src->progress);
|
||||||
if (ret < 0) {
|
|
||||||
ff_thread_release_ext_buffer(dst->owner[0], dst);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user