summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/ffmpeg/libavcodec/pthread_frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/ffmpeg/libavcodec/pthread_frame.c')
-rw-r--r--chromium/third_party/ffmpeg/libavcodec/pthread_frame.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/chromium/third_party/ffmpeg/libavcodec/pthread_frame.c b/chromium/third_party/ffmpeg/libavcodec/pthread_frame.c
index 51a163384b7..f01ac559024 100644
--- a/chromium/third_party/ffmpeg/libavcodec/pthread_frame.c
+++ b/chromium/third_party/ffmpeg/libavcodec/pthread_frame.c
@@ -121,8 +121,13 @@ typedef struct FrameThreadContext {
int die; ///< Set when threads should exit.
} FrameThreadContext;
+#if FF_API_GET_BUFFER
#define THREAD_SAFE_CALLBACKS(avctx) \
((avctx)->thread_safe_callbacks || (!(avctx)->get_buffer && (avctx)->get_buffer2 == avcodec_default_get_buffer2))
+#else
+#define THREAD_SAFE_CALLBACKS(avctx) \
+((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2)
+#endif
/**
* Codec worker thread.
@@ -152,6 +157,13 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
p->got_frame = 0;
p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt);
+ if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) {
+ if (avctx->internal->allocate_progress)
+ av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not "
+ "free the frame on failure. This is a bug, please report it.\n");
+ av_frame_unref(p->frame);
+ }
+
if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
pthread_mutex_lock(&p->progress_mutex);
@@ -219,6 +231,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src,
dst->sample_rate = src->sample_rate;
dst->sample_fmt = src->sample_fmt;
dst->channel_layout = src->channel_layout;
+ dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
}
if (for_user) {
@@ -310,6 +323,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
FrameThreadContext *fctx = p->parent;
PerThreadContext *prev_thread = fctx->prev_thread;
const AVCodec *codec = p->avctx->codec;
+ int ret;
if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0;
@@ -333,6 +347,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
}
}
+ av_packet_free_side_data(&p->avpkt);
av_buffer_unref(&p->avpkt.buf);
p->avpkt = *avpkt;
if (avpkt->buf)
@@ -347,6 +362,10 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
memcpy(p->buf, avpkt->data, avpkt->size);
memset(p->buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
}
+ if ((ret = av_copy_packet_side_data(&p->avpkt, avpkt)) < 0) {
+ pthread_mutex_unlock(&p->mutex);
+ return ret;
+ }
p->state = STATE_SETTING_UP;
pthread_cond_signal(&p->input_cond);
@@ -585,6 +604,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
pthread_cond_destroy(&p->input_cond);
pthread_cond_destroy(&p->progress_cond);
pthread_cond_destroy(&p->output_cond);
+ av_packet_free_side_data(&p->avpkt);
av_buffer_unref(&p->avpkt.buf);
av_freep(&p->buf);
av_freep(&p->released_buffers);
@@ -650,6 +670,7 @@ int ff_frame_thread_init(AVCodecContext *avctx)
p->frame = av_frame_alloc();
if (!p->frame) {
err = AVERROR(ENOMEM);
+ av_freep(&copy);
goto error;
}
@@ -719,8 +740,6 @@ void ff_thread_flush(AVCodecContext *avctx)
if (fctx->prev_thread) {
if (fctx->prev_thread != &fctx->threads[0])
update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);
- if (avctx->codec->flush)
- avctx->codec->flush(fctx->threads[0].avctx);
}
fctx->next_decoding = fctx->next_finished = 0;
@@ -733,6 +752,9 @@ void ff_thread_flush(AVCodecContext *avctx)
av_frame_unref(p->frame);
release_delayed_buffers(p);
+
+ if (avctx->codec->flush)
+ avctx->codec->flush(p->avctx);
}
}
@@ -816,7 +838,7 @@ enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixe
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)
- return avctx->get_format(avctx, fmt);
+ 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");
return -1;
@@ -859,7 +881,7 @@ FF_DISABLE_DEPRECATION_WARNINGS
avctx->get_buffer2 == avcodec_default_get_buffer2);
FF_ENABLE_DEPRECATION_WARNINGS
- if (!f->f->buf[0])
+ if (!f->f || !f->f->buf[0])
return;
if (avctx->debug & FF_DEBUG_BUFFERS)