032e2beedf
Removing 0013-add-public-version-of-ff_read_frame_flush.patch in http://git.buildroot.net/buildroot/commit/package/ffmpeg?id=4d094d9eb4edba5b6c3c229a2c02da1427e43fe5 was a bit too early since Kodi 14.2 still uses it, so re-add 0013-add-public-version-of-ff_read_frame_flush.patch and rename 0013-fix-ff-thread-get-format.patch. When Kodi 15.0 is released the file 0013-add-public-version-of-ff_read_frame_flush.patch can be removed again. Fixes http://autobuild.buildroot.net/results/1c1/1c12779e67ddc6d3dffbc1d2e5ebf9887ae721ca/ http://autobuild.buildroot.net/results/c63/c6301fc6f11204ee157a4f6a848dda9666cfb450/ http://autobuild.buildroot.net/results/e61/e6138bac331370b02af746e319ce8fd6fe51b793/ http://autobuild.buildroot.net/results/c3d/c3dbb01608debd1bf0af6acd6eb9de6d01424982/ http://autobuild.buildroot.net/results/e1b/e1b0fbc6631a0073d743705400460b8679b28a0f/ http://autobuild.buildroot.net/results/180/1803aa8bd62e4fc126d0a791456804bb9b036e6d/ http://autobuild.buildroot.net/results/d2e/d2e9571f5747e609eb4f9b64ac6ab99bccb92767/ [Thomas: remove SoB from myself from inside the patch, as I was not involved with it.] Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
132 lines
5.3 KiB
Diff
132 lines
5.3 KiB
Diff
From b52c216539bdbee830e0d306b372037d4e0cb35f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Reimar=20D=C3=B6ffinger?= <Reimar.Doeffinger@gmx.de>
|
|
Date: Sun, 8 Mar 2015 19:44:12 +0100
|
|
Subject: [PATCH] pthread: Fix ff_thread_get_format issues when called outside
|
|
frame decode
|
|
|
|
Patch part of the XBMC patch set for ffmpeg, downloaded from
|
|
https://github.com/xbmc/FFmpeg/.
|
|
|
|
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
|
---
|
|
libavcodec/pthread_frame.c | 22 +++++++++++++++++++---
|
|
1 file changed, 19 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
|
|
index 5a4ab84..c29d0a9 100644
|
|
--- a/libavcodec/pthread_frame.c
|
|
+++ b/libavcodec/pthread_frame.c
|
|
@@ -53,6 +53,7 @@
|
|
* Context used by codec threads and stored in their AVCodecInternal thread_ctx.
|
|
*/
|
|
typedef struct PerThreadContext {
|
|
+ int main_thread;
|
|
struct FrameThreadContext *parent;
|
|
|
|
pthread_t thread;
|
|
@@ -83,7 +84,8 @@ typedef struct PerThreadContext {
|
|
* Set when the codec calls get_format().
|
|
* State is returned to STATE_SETTING_UP afterwards.
|
|
*/
|
|
- STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup().
|
|
+ STATE_SETUP_FINISHED, ///< Set after the codec has called ff_thread_finish_setup().
|
|
+ STATE_UPDATE_CONTEXT, ///< Main thread is updating its context
|
|
} state;
|
|
|
|
/**
|
|
@@ -105,6 +107,7 @@ typedef struct PerThreadContext {
|
|
* Context stored in the client AVCodecInternal thread_ctx.
|
|
*/
|
|
typedef struct FrameThreadContext {
|
|
+ int main_thread;
|
|
PerThreadContext *threads; ///< The contexts for each thread.
|
|
PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
|
|
|
|
@@ -143,6 +146,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
|
|
AVCodecContext *avctx = p->avctx;
|
|
const AVCodec *codec = avctx->codec;
|
|
|
|
+ av_assert0(!p->main_thread);
|
|
pthread_mutex_lock(&p->mutex);
|
|
while (1) {
|
|
while (p->state == STATE_INPUT_READY && !fctx->die)
|
|
@@ -330,6 +334,8 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
|
|
|
|
pthread_mutex_lock(&p->mutex);
|
|
|
|
+ p->state = STATE_UPDATE_CONTEXT;
|
|
+
|
|
release_delayed_buffers(p);
|
|
|
|
if (prev_thread) {
|
|
@@ -408,6 +414,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
|
|
int finished = fctx->next_finished;
|
|
PerThreadContext *p;
|
|
int err;
|
|
+ av_assert0(fctx->main_thread);
|
|
|
|
/*
|
|
* Submit a packet to the next decoding thread.
|
|
@@ -515,6 +522,7 @@ void ff_thread_finish_setup(AVCodecContext *avctx) {
|
|
|
|
if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
|
|
|
|
+ av_assert0(!p->main_thread);
|
|
if(p->state == STATE_SETUP_FINISHED){
|
|
av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
|
|
}
|
|
@@ -549,6 +557,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
|
|
const AVCodec *codec = avctx->codec;
|
|
int i;
|
|
|
|
+ av_assert0(fctx->main_thread);
|
|
park_frame_worker_threads(fctx, thread_count);
|
|
|
|
if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
|
|
@@ -634,6 +643,7 @@ int ff_frame_thread_init(AVCodecContext *avctx)
|
|
}
|
|
|
|
avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
|
|
+ fctx->main_thread = 1;
|
|
|
|
fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext));
|
|
pthread_mutex_init(&fctx->buffer_mutex, NULL);
|
|
@@ -718,6 +728,7 @@ void ff_thread_flush(AVCodecContext *avctx)
|
|
|
|
if (!fctx) return;
|
|
|
|
+ av_assert0(fctx->main_thread);
|
|
park_frame_worker_threads(fctx, avctx->thread_count);
|
|
if (fctx->prev_thread) {
|
|
if (fctx->prev_thread != &fctx->threads[0])
|
|
@@ -743,7 +754,10 @@ void ff_thread_flush(AVCodecContext *avctx)
|
|
int ff_thread_can_start_frame(AVCodecContext *avctx)
|
|
{
|
|
PerThreadContext *p = avctx->internal->thread_ctx;
|
|
- if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP &&
|
|
+ if (!(avctx->active_thread_type&FF_THREAD_FRAME))
|
|
+ return 1;
|
|
+ av_assert0(!p->main_thread);
|
|
+ if (p->state != STATE_SETTING_UP &&
|
|
(avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
|
|
return 0;
|
|
}
|
|
@@ -762,6 +776,7 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int
|
|
if (!(avctx->active_thread_type & FF_THREAD_FRAME))
|
|
return ff_get_buffer(avctx, f->f, flags);
|
|
|
|
+ av_assert0(!p->main_thread);
|
|
if (p->state != STATE_SETTING_UP &&
|
|
(avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
|
|
av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
|
|
@@ -819,7 +834,8 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe
|
|
enum AVPixelFormat res;
|
|
PerThreadContext *p = avctx->internal->thread_ctx;
|
|
if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks ||
|
|
- avctx->get_format == avcodec_default_get_format)
|
|
+ avctx->get_format == avcodec_default_get_format ||
|
|
+ p->main_thread || p->state == STATE_UPDATE_CONTEXT)
|
|
return ff_get_format(avctx, fmt);
|
|
if (p->state != STATE_SETTING_UP) {
|
|
av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n");
|