diff options
Diffstat (limited to 'chromium/third_party/ffmpeg/libavcodec/pthread_frame.c')
-rw-r--r-- | chromium/third_party/ffmpeg/libavcodec/pthread_frame.c | 30 |
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(©); 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) |