LCOV - code coverage report
Current view: top level - libavcodec - pthread_frame.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 342 507 67.5 %
Date: 2017-12-17 04:34:43 Functions: 19 20 95.0 %

          Line data    Source code
       1             : /*
       2             :  * This file is part of FFmpeg.
       3             :  *
       4             :  * FFmpeg is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU Lesser General Public
       6             :  * License as published by the Free Software Foundation; either
       7             :  * version 2.1 of the License, or (at your option) any later version.
       8             :  *
       9             :  * FFmpeg is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Lesser General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public
      15             :  * License along with FFmpeg; if not, write to the Free Software
      16             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      17             :  */
      18             : 
      19             : /**
      20             :  * @file
      21             :  * Frame multithreading support functions
      22             :  * @see doc/multithreading.txt
      23             :  */
      24             : 
      25             : #include "config.h"
      26             : 
      27             : #include <stdatomic.h>
      28             : #include <stdint.h>
      29             : 
      30             : #include "avcodec.h"
      31             : #include "hwaccel.h"
      32             : #include "internal.h"
      33             : #include "pthread_internal.h"
      34             : #include "thread.h"
      35             : #include "version.h"
      36             : 
      37             : #include "libavutil/avassert.h"
      38             : #include "libavutil/buffer.h"
      39             : #include "libavutil/common.h"
      40             : #include "libavutil/cpu.h"
      41             : #include "libavutil/frame.h"
      42             : #include "libavutil/internal.h"
      43             : #include "libavutil/log.h"
      44             : #include "libavutil/mem.h"
      45             : #include "libavutil/opt.h"
      46             : #include "libavutil/thread.h"
      47             : 
      48             : enum {
      49             :     ///< Set when the thread is awaiting a packet.
      50             :     STATE_INPUT_READY,
      51             :     ///< Set before the codec has called ff_thread_finish_setup().
      52             :     STATE_SETTING_UP,
      53             :     /**
      54             :      * Set when the codec calls get_buffer().
      55             :      * State is returned to STATE_SETTING_UP afterwards.
      56             :      */
      57             :     STATE_GET_BUFFER,
      58             :      /**
      59             :       * Set when the codec calls get_format().
      60             :       * State is returned to STATE_SETTING_UP afterwards.
      61             :       */
      62             :     STATE_GET_FORMAT,
      63             :     ///< Set after the codec has called ff_thread_finish_setup().
      64             :     STATE_SETUP_FINISHED,
      65             : };
      66             : 
      67             : /**
      68             :  * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
      69             :  */
      70             : typedef struct PerThreadContext {
      71             :     struct FrameThreadContext *parent;
      72             : 
      73             :     pthread_t      thread;
      74             :     int            thread_init;
      75             :     pthread_cond_t input_cond;      ///< Used to wait for a new packet from the main thread.
      76             :     pthread_cond_t progress_cond;   ///< Used by child threads to wait for progress to change.
      77             :     pthread_cond_t output_cond;     ///< Used by the main thread to wait for frames to finish.
      78             : 
      79             :     pthread_mutex_t mutex;          ///< Mutex used to protect the contents of the PerThreadContext.
      80             :     pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
      81             : 
      82             :     AVCodecContext *avctx;          ///< Context used to decode packets passed to this thread.
      83             : 
      84             :     AVPacket       avpkt;           ///< Input packet (for decoding) or output (for encoding).
      85             : 
      86             :     AVFrame *frame;                 ///< Output frame (for decoding) or input (for encoding).
      87             :     int     got_frame;              ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
      88             :     int     result;                 ///< The result of the last codec decode/encode() call.
      89             : 
      90             :     atomic_int state;
      91             : 
      92             :     /**
      93             :      * Array of frames passed to ff_thread_release_buffer().
      94             :      * Frames are released after all threads referencing them are finished.
      95             :      */
      96             :     AVFrame *released_buffers;
      97             :     int  num_released_buffers;
      98             :     int      released_buffers_allocated;
      99             : 
     100             :     AVFrame *requested_frame;       ///< AVFrame the codec passed to get_buffer()
     101             :     int      requested_flags;       ///< flags passed to get_buffer() for requested_frame
     102             : 
     103             :     const enum AVPixelFormat *available_formats; ///< Format array for get_format()
     104             :     enum AVPixelFormat result_format;            ///< get_format() result
     105             : 
     106             :     int die;                        ///< Set when the thread should exit.
     107             : 
     108             :     int hwaccel_serializing;
     109             :     int async_serializing;
     110             : 
     111             :     atomic_int debug_threads;       ///< Set if the FF_DEBUG_THREADS option is set.
     112             : } PerThreadContext;
     113             : 
     114             : /**
     115             :  * Context stored in the client AVCodecInternal thread_ctx.
     116             :  */
     117             : typedef struct FrameThreadContext {
     118             :     PerThreadContext *threads;     ///< The contexts for each thread.
     119             :     PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
     120             : 
     121             :     pthread_mutex_t buffer_mutex;  ///< Mutex used to protect get/release_buffer().
     122             :     /**
     123             :      * This lock is used for ensuring threads run in serial when hwaccel
     124             :      * is used.
     125             :      */
     126             :     pthread_mutex_t hwaccel_mutex;
     127             :     pthread_mutex_t async_mutex;
     128             :     pthread_cond_t async_cond;
     129             :     int async_lock;
     130             : 
     131             :     int next_decoding;             ///< The next context to submit a packet to.
     132             :     int next_finished;             ///< The next context to return output from.
     133             : 
     134             :     int delaying;                  /**<
     135             :                                     * Set for the first N packets, where N is the number of threads.
     136             :                                     * While it is set, ff_thread_en/decode_frame won't return any results.
     137             :                                     */
     138             : } FrameThreadContext;
     139             : 
     140             : #define THREAD_SAFE_CALLBACKS(avctx) \
     141             : ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2)
     142             : 
     143         147 : static void async_lock(FrameThreadContext *fctx)
     144             : {
     145         147 :     pthread_mutex_lock(&fctx->async_mutex);
     146         294 :     while (fctx->async_lock)
     147           0 :         pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex);
     148         147 :     fctx->async_lock = 1;
     149         147 :     pthread_mutex_unlock(&fctx->async_mutex);
     150         147 : }
     151             : 
     152         147 : static void async_unlock(FrameThreadContext *fctx)
     153             : {
     154         147 :     pthread_mutex_lock(&fctx->async_mutex);
     155         147 :     av_assert0(fctx->async_lock);
     156         147 :     fctx->async_lock = 0;
     157         147 :     pthread_cond_broadcast(&fctx->async_cond);
     158         147 :     pthread_mutex_unlock(&fctx->async_mutex);
     159         147 : }
     160             : 
     161             : /**
     162             :  * Codec worker thread.
     163             :  *
     164             :  * Automatically calls ff_thread_finish_setup() if the codec does
     165             :  * not provide an update_thread_context method, or if the codec returns
     166             :  * before calling it.
     167             :  */
     168          38 : static attribute_align_arg void *frame_worker_thread(void *arg)
     169             : {
     170          38 :     PerThreadContext *p = arg;
     171          38 :     AVCodecContext *avctx = p->avctx;
     172          38 :     const AVCodec *codec = avctx->codec;
     173             : 
     174          38 :     pthread_mutex_lock(&p->mutex);
     175             :     while (1) {
     176         638 :         while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die)
     177         166 :             pthread_cond_wait(&p->input_cond, &p->mutex);
     178             : 
     179         170 :         if (p->die) break;
     180             : 
     181         132 :         if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx))
     182         128 :             ff_thread_finish_setup(avctx);
     183             : 
     184             :         /* If a decoder supports hwaccel, then it must call ff_get_format().
     185             :          * Since that call must happen before ff_thread_finish_setup(), the
     186             :          * decoder is required to implement update_thread_context() and call
     187             :          * ff_thread_finish_setup() manually. Therefore the above
     188             :          * ff_thread_finish_setup() call did not happen and hwaccel_serializing
     189             :          * cannot be true here. */
     190         132 :         av_assert0(!p->hwaccel_serializing);
     191             : 
     192             :         /* if the previous thread uses hwaccel then we take the lock to ensure
     193             :          * the threads don't run concurrently */
     194         132 :         if (avctx->hwaccel) {
     195           0 :             pthread_mutex_lock(&p->parent->hwaccel_mutex);
     196           0 :             p->hwaccel_serializing = 1;
     197             :         }
     198             : 
     199         132 :         av_frame_unref(p->frame);
     200         132 :         p->got_frame = 0;
     201         132 :         p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt);
     202             : 
     203         132 :         if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) {
     204           0 :             if (avctx->internal->allocate_progress)
     205           0 :                 av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not "
     206             :                        "free the frame on failure. This is a bug, please report it.\n");
     207           0 :             av_frame_unref(p->frame);
     208             :         }
     209             : 
     210         132 :         if (atomic_load(&p->state) == STATE_SETTING_UP)
     211           0 :             ff_thread_finish_setup(avctx);
     212             : 
     213         132 :         if (p->hwaccel_serializing) {
     214           0 :             p->hwaccel_serializing = 0;
     215           0 :             pthread_mutex_unlock(&p->parent->hwaccel_mutex);
     216             :         }
     217             : 
     218         132 :         if (p->async_serializing) {
     219           0 :             p->async_serializing = 0;
     220             : 
     221           0 :             async_unlock(p->parent);
     222             :         }
     223             : 
     224         132 :         pthread_mutex_lock(&p->progress_mutex);
     225             : 
     226         132 :         atomic_store(&p->state, STATE_INPUT_READY);
     227             : 
     228         132 :         pthread_cond_broadcast(&p->progress_cond);
     229         132 :         pthread_cond_signal(&p->output_cond);
     230         132 :         pthread_mutex_unlock(&p->progress_mutex);
     231             :     }
     232          38 :     pthread_mutex_unlock(&p->mutex);
     233             : 
     234          38 :     return NULL;
     235             : }
     236             : 
     237             : /**
     238             :  * Update the next thread's AVCodecContext with values from the reference thread's context.
     239             :  *
     240             :  * @param dst The destination context.
     241             :  * @param src The source context.
     242             :  * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
     243             :  * @return 0 on success, negative error code on failure
     244             :  */
     245         270 : static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user)
     246             : {
     247         270 :     int err = 0;
     248             : 
     249         270 :     if (dst != src && (for_user || !(src->codec_descriptor->props & AV_CODEC_PROP_INTRA_ONLY))) {
     250         142 :         dst->time_base = src->time_base;
     251         142 :         dst->framerate = src->framerate;
     252         142 :         dst->width     = src->width;
     253         142 :         dst->height    = src->height;
     254         142 :         dst->pix_fmt   = src->pix_fmt;
     255         142 :         dst->sw_pix_fmt = src->sw_pix_fmt;
     256             : 
     257         142 :         dst->coded_width  = src->coded_width;
     258         142 :         dst->coded_height = src->coded_height;
     259             : 
     260         142 :         dst->has_b_frames = src->has_b_frames;
     261         142 :         dst->idct_algo    = src->idct_algo;
     262             : 
     263         142 :         dst->bits_per_coded_sample = src->bits_per_coded_sample;
     264         142 :         dst->sample_aspect_ratio   = src->sample_aspect_ratio;
     265             : 
     266         142 :         dst->profile = src->profile;
     267         142 :         dst->level   = src->level;
     268             : 
     269         142 :         dst->bits_per_raw_sample = src->bits_per_raw_sample;
     270         142 :         dst->ticks_per_frame     = src->ticks_per_frame;
     271         142 :         dst->color_primaries     = src->color_primaries;
     272             : 
     273         142 :         dst->color_trc   = src->color_trc;
     274         142 :         dst->colorspace  = src->colorspace;
     275         142 :         dst->color_range = src->color_range;
     276         142 :         dst->chroma_sample_location = src->chroma_sample_location;
     277             : 
     278         142 :         dst->hwaccel = src->hwaccel;
     279         142 :         dst->hwaccel_context = src->hwaccel_context;
     280             : 
     281         142 :         dst->channels       = src->channels;
     282         142 :         dst->sample_rate    = src->sample_rate;
     283         142 :         dst->sample_fmt     = src->sample_fmt;
     284         142 :         dst->channel_layout = src->channel_layout;
     285         142 :         dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
     286             : 
     287         284 :         if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
     288         142 :             (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
     289           0 :             av_buffer_unref(&dst->hw_frames_ctx);
     290             : 
     291           0 :             if (src->hw_frames_ctx) {
     292           0 :                 dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
     293           0 :                 if (!dst->hw_frames_ctx)
     294           0 :                     return AVERROR(ENOMEM);
     295             :             }
     296             :         }
     297             : 
     298         142 :         dst->hwaccel_flags = src->hwaccel_flags;
     299             :     }
     300             : 
     301         270 :     if (for_user) {
     302         142 :         dst->delay       = src->thread_count - 1;
     303             : #if FF_API_CODED_FRAME
     304             : FF_DISABLE_DEPRECATION_WARNINGS
     305         142 :         dst->coded_frame = src->coded_frame;
     306             : FF_ENABLE_DEPRECATION_WARNINGS
     307             : #endif
     308             :     } else {
     309         128 :         if (dst->codec->update_thread_context)
     310           0 :             err = dst->codec->update_thread_context(dst, src);
     311             :     }
     312             : 
     313         270 :     return err;
     314             : }
     315             : 
     316             : /**
     317             :  * Update the next thread's AVCodecContext with values set by the user.
     318             :  *
     319             :  * @param dst The destination context.
     320             :  * @param src The source context.
     321             :  * @return 0 on success, negative error code on failure
     322             :  */
     323         132 : static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
     324             : {
     325             : #define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s);
     326         132 :     dst->flags          = src->flags;
     327             : 
     328         132 :     dst->draw_horiz_band= src->draw_horiz_band;
     329         132 :     dst->get_buffer2    = src->get_buffer2;
     330             : 
     331         132 :     dst->opaque   = src->opaque;
     332         132 :     dst->debug    = src->debug;
     333         132 :     dst->debug_mv = src->debug_mv;
     334             : 
     335         132 :     dst->slice_flags = src->slice_flags;
     336         132 :     dst->flags2      = src->flags2;
     337             : 
     338         132 :     copy_fields(skip_loop_filter, subtitle_header);
     339             : 
     340         132 :     dst->frame_number     = src->frame_number;
     341         132 :     dst->reordered_opaque = src->reordered_opaque;
     342         132 :     dst->thread_safe_callbacks = src->thread_safe_callbacks;
     343             : 
     344         132 :     if (src->slice_count && src->slice_offset) {
     345           0 :         if (dst->slice_count < src->slice_count) {
     346           0 :             int err = av_reallocp_array(&dst->slice_offset, src->slice_count,
     347             :                                         sizeof(*dst->slice_offset));
     348           0 :             if (err < 0)
     349           0 :                 return err;
     350             :         }
     351           0 :         memcpy(dst->slice_offset, src->slice_offset,
     352           0 :                src->slice_count * sizeof(*dst->slice_offset));
     353             :     }
     354         132 :     dst->slice_count = src->slice_count;
     355         132 :     return 0;
     356             : #undef copy_fields
     357             : }
     358             : 
     359             : /// Releases the buffers that this decoding thread was the last user of.
     360         170 : static void release_delayed_buffers(PerThreadContext *p)
     361             : {
     362         170 :     FrameThreadContext *fctx = p->parent;
     363             : 
     364         340 :     while (p->num_released_buffers > 0) {
     365             :         AVFrame *f;
     366             : 
     367           0 :         pthread_mutex_lock(&fctx->buffer_mutex);
     368             : 
     369             :         // fix extended data in case the caller screwed it up
     370           0 :         av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
     371             :                    p->avctx->codec_type == AVMEDIA_TYPE_AUDIO);
     372           0 :         f = &p->released_buffers[--p->num_released_buffers];
     373           0 :         f->extended_data = f->data;
     374           0 :         av_frame_unref(f);
     375             : 
     376           0 :         pthread_mutex_unlock(&fctx->buffer_mutex);
     377             :     }
     378         170 : }
     379             : 
     380         142 : static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx,
     381             :                          AVPacket *avpkt)
     382             : {
     383         142 :     FrameThreadContext *fctx = p->parent;
     384         142 :     PerThreadContext *prev_thread = fctx->prev_thread;
     385         142 :     const AVCodec *codec = p->avctx->codec;
     386             :     int ret;
     387             : 
     388         142 :     if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY))
     389          10 :         return 0;
     390             : 
     391         132 :     pthread_mutex_lock(&p->mutex);
     392             : 
     393         132 :     ret = update_context_from_user(p->avctx, user_avctx);
     394         132 :     if (ret) {
     395           0 :         pthread_mutex_unlock(&p->mutex);
     396           0 :         return ret;
     397             :     }
     398         132 :     atomic_store_explicit(&p->debug_threads,
     399             :                           (p->avctx->debug & FF_DEBUG_THREADS) != 0,
     400             :                           memory_order_relaxed);
     401             : 
     402         132 :     release_delayed_buffers(p);
     403             : 
     404         132 :     if (prev_thread) {
     405             :         int err;
     406         127 :         if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) {
     407          65 :             pthread_mutex_lock(&prev_thread->progress_mutex);
     408         195 :             while (atomic_load(&prev_thread->state) == STATE_SETTING_UP)
     409          65 :                 pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
     410          65 :             pthread_mutex_unlock(&prev_thread->progress_mutex);
     411             :         }
     412             : 
     413         127 :         err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
     414         127 :         if (err) {
     415           0 :             pthread_mutex_unlock(&p->mutex);
     416           0 :             return err;
     417             :         }
     418             :     }
     419             : 
     420         132 :     av_packet_unref(&p->avpkt);
     421         132 :     ret = av_packet_ref(&p->avpkt, avpkt);
     422         132 :     if (ret < 0) {
     423           0 :         pthread_mutex_unlock(&p->mutex);
     424           0 :         av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n");
     425           0 :         return ret;
     426             :     }
     427             : 
     428         132 :     atomic_store(&p->state, STATE_SETTING_UP);
     429         132 :     pthread_cond_signal(&p->input_cond);
     430         132 :     pthread_mutex_unlock(&p->mutex);
     431             : 
     432             :     /*
     433             :      * If the client doesn't have a thread-safe get_buffer(),
     434             :      * then decoding threads call back to the main thread,
     435             :      * and it calls back to the client here.
     436             :      */
     437             : 
     438         132 :     if (!p->avctx->thread_safe_callbacks && (
     439           0 :          p->avctx->get_format != avcodec_default_get_format ||
     440           0 :          p->avctx->get_buffer2 != avcodec_default_get_buffer2)) {
     441           0 :         while (atomic_load(&p->state) != STATE_SETUP_FINISHED && atomic_load(&p->state) != STATE_INPUT_READY) {
     442           0 :             int call_done = 1;
     443           0 :             pthread_mutex_lock(&p->progress_mutex);
     444           0 :             while (atomic_load(&p->state) == STATE_SETTING_UP)
     445           0 :                 pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
     446             : 
     447           0 :             switch (atomic_load_explicit(&p->state, memory_order_acquire)) {
     448           0 :             case STATE_GET_BUFFER:
     449           0 :                 p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags);
     450           0 :                 break;
     451           0 :             case STATE_GET_FORMAT:
     452           0 :                 p->result_format = ff_get_format(p->avctx, p->available_formats);
     453           0 :                 break;
     454           0 :             default:
     455           0 :                 call_done = 0;
     456           0 :                 break;
     457             :             }
     458           0 :             if (call_done) {
     459           0 :                 atomic_store(&p->state, STATE_SETTING_UP);
     460           0 :                 pthread_cond_signal(&p->progress_cond);
     461             :             }
     462           0 :             pthread_mutex_unlock(&p->progress_mutex);
     463             :         }
     464             :     }
     465             : 
     466         132 :     fctx->prev_thread = p;
     467         132 :     fctx->next_decoding++;
     468             : 
     469         132 :     return 0;
     470             : }
     471             : 
     472         142 : int ff_thread_decode_frame(AVCodecContext *avctx,
     473             :                            AVFrame *picture, int *got_picture_ptr,
     474             :                            AVPacket *avpkt)
     475             : {
     476         142 :     FrameThreadContext *fctx = avctx->internal->thread_ctx;
     477         142 :     int finished = fctx->next_finished;
     478             :     PerThreadContext *p;
     479             :     int err;
     480             : 
     481             :     /* release the async lock, permitting blocked hwaccel threads to
     482             :      * go forward while we are in this function */
     483         142 :     async_unlock(fctx);
     484             : 
     485             :     /*
     486             :      * Submit a packet to the next decoding thread.
     487             :      */
     488             : 
     489         142 :     p = &fctx->threads[fctx->next_decoding];
     490         142 :     err = submit_packet(p, avctx, avpkt);
     491         142 :     if (err)
     492           0 :         goto finish;
     493             : 
     494             :     /*
     495             :      * If we're still receiving the initial packets, don't return a frame.
     496             :      */
     497             : 
     498         142 :     if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
     499          64 :         fctx->delaying = 0;
     500             : 
     501         142 :     if (fctx->delaying) {
     502          13 :         *got_picture_ptr=0;
     503          13 :         if (avpkt->size) {
     504           5 :             err = avpkt->size;
     505           5 :             goto finish;
     506             :         }
     507             :     }
     508             : 
     509             :     /*
     510             :      * Return the next available frame from the oldest thread.
     511             :      * If we're at the end of the stream, then we have to skip threads that
     512             :      * didn't output a frame/error, because we don't want to accidentally signal
     513             :      * EOF (avpkt->size == 0 && *got_picture_ptr == 0 && err >= 0).
     514             :      */
     515             : 
     516             :     do {
     517         170 :         p = &fctx->threads[finished++];
     518             : 
     519         170 :         if (atomic_load(&p->state) != STATE_INPUT_READY) {
     520          66 :             pthread_mutex_lock(&p->progress_mutex);
     521         198 :             while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY)
     522          66 :                 pthread_cond_wait(&p->output_cond, &p->progress_mutex);
     523          66 :             pthread_mutex_unlock(&p->progress_mutex);
     524             :         }
     525             : 
     526         170 :         av_frame_move_ref(picture, p->frame);
     527         170 :         *got_picture_ptr = p->got_frame;
     528         170 :         picture->pkt_dts = p->avpkt.dts;
     529         170 :         err = p->result;
     530             : 
     531             :         /*
     532             :          * A later call with avkpt->size == 0 may loop over all threads,
     533             :          * including this one, searching for a frame/error to return before being
     534             :          * stopped by the "finished != fctx->next_finished" condition.
     535             :          * Make sure we don't mistakenly return the same frame/error again.
     536             :          */
     537         170 :         p->got_frame = 0;
     538         170 :         p->result = 0;
     539             : 
     540         170 :         if (finished >= avctx->thread_count) finished = 0;
     541         170 :     } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished);
     542             : 
     543         137 :     update_context_from_thread(avctx, p->avctx, 1);
     544             : 
     545         137 :     if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
     546             : 
     547         137 :     fctx->next_finished = finished;
     548             : 
     549             :     /* return the size of the consumed packet if no error occurred */
     550         137 :     if (err >= 0)
     551         137 :         err = avpkt->size;
     552         142 : finish:
     553         142 :     async_lock(fctx);
     554         142 :     return err;
     555             : }
     556             : 
     557      392923 : void ff_thread_report_progress(ThreadFrame *f, int n, int field)
     558             : {
     559             :     PerThreadContext *p;
     560      392923 :     atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
     561             : 
     562      392927 :     if (!progress ||
     563           4 :         atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
     564      392919 :         return;
     565             : 
     566           4 :     p = f->owner[field]->internal->thread_ctx;
     567             : 
     568           4 :     if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
     569           0 :         av_log(f->owner[field], AV_LOG_DEBUG,
     570             :                "%p finished %d field %d\n", progress, n, field);
     571             : 
     572           4 :     pthread_mutex_lock(&p->progress_mutex);
     573             : 
     574           4 :     atomic_store_explicit(&progress[field], n, memory_order_release);
     575             : 
     576           4 :     pthread_cond_broadcast(&p->progress_cond);
     577           4 :     pthread_mutex_unlock(&p->progress_mutex);
     578             : }
     579             : 
     580     2489722 : void ff_thread_await_progress(ThreadFrame *f, int n, int field)
     581             : {
     582             :     PerThreadContext *p;
     583     2489722 :     atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
     584             : 
     585     2489722 :     if (!progress ||
     586           0 :         atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
     587     2489722 :         return;
     588             : 
     589           0 :     p = f->owner[field]->internal->thread_ctx;
     590             : 
     591           0 :     if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
     592           0 :         av_log(f->owner[field], AV_LOG_DEBUG,
     593             :                "thread awaiting %d field %d from %p\n", n, field, progress);
     594             : 
     595           0 :     pthread_mutex_lock(&p->progress_mutex);
     596           0 :     while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n)
     597           0 :         pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
     598           0 :     pthread_mutex_unlock(&p->progress_mutex);
     599             : }
     600             : 
     601       21124 : void ff_thread_finish_setup(AVCodecContext *avctx) {
     602       21124 :     PerThreadContext *p = avctx->internal->thread_ctx;
     603             : 
     604       21124 :     if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
     605             : 
     606         132 :     if (avctx->hwaccel && !p->hwaccel_serializing) {
     607           0 :         pthread_mutex_lock(&p->parent->hwaccel_mutex);
     608           0 :         p->hwaccel_serializing = 1;
     609             :     }
     610             : 
     611             :     /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */
     612         132 :     if (avctx->hwaccel &&
     613           0 :         !(avctx->hwaccel->caps_internal & HWACCEL_CAP_ASYNC_SAFE)) {
     614           0 :         p->async_serializing = 1;
     615             : 
     616           0 :         async_lock(p->parent);
     617             :     }
     618             : 
     619         132 :     pthread_mutex_lock(&p->progress_mutex);
     620         132 :     if(atomic_load(&p->state) == STATE_SETUP_FINISHED){
     621           0 :         av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
     622             :     }
     623             : 
     624         132 :     atomic_store(&p->state, STATE_SETUP_FINISHED);
     625             : 
     626         132 :     pthread_cond_broadcast(&p->progress_cond);
     627         132 :     pthread_mutex_unlock(&p->progress_mutex);
     628             : }
     629             : 
     630             : /// Waits for all threads to finish.
     631           5 : static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
     632             : {
     633             :     int i;
     634             : 
     635           5 :     async_unlock(fctx);
     636             : 
     637          43 :     for (i = 0; i < thread_count; i++) {
     638          38 :         PerThreadContext *p = &fctx->threads[i];
     639             : 
     640          38 :         if (atomic_load(&p->state) != STATE_INPUT_READY) {
     641           0 :             pthread_mutex_lock(&p->progress_mutex);
     642           0 :             while (atomic_load(&p->state) != STATE_INPUT_READY)
     643           0 :                 pthread_cond_wait(&p->output_cond, &p->progress_mutex);
     644           0 :             pthread_mutex_unlock(&p->progress_mutex);
     645             :         }
     646          38 :         p->got_frame = 0;
     647             :     }
     648             : 
     649           5 :     async_lock(fctx);
     650           5 : }
     651             : 
     652           5 : void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
     653             : {
     654           5 :     FrameThreadContext *fctx = avctx->internal->thread_ctx;
     655           5 :     const AVCodec *codec = avctx->codec;
     656             :     int i;
     657             : 
     658           5 :     park_frame_worker_threads(fctx, thread_count);
     659             : 
     660           5 :     if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
     661           1 :         if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
     662           0 :             av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
     663           0 :             fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy;
     664           0 :             fctx->threads->avctx->internal->is_copy = 1;
     665             :         }
     666             : 
     667          43 :     for (i = 0; i < thread_count; i++) {
     668          38 :         PerThreadContext *p = &fctx->threads[i];
     669             : 
     670          38 :         pthread_mutex_lock(&p->mutex);
     671          38 :         p->die = 1;
     672          38 :         pthread_cond_signal(&p->input_cond);
     673          38 :         pthread_mutex_unlock(&p->mutex);
     674             : 
     675          38 :         if (p->thread_init)
     676          38 :             pthread_join(p->thread, NULL);
     677          38 :         p->thread_init=0;
     678             : 
     679          38 :         if (codec->close && p->avctx)
     680          38 :             codec->close(p->avctx);
     681             : 
     682          38 :         release_delayed_buffers(p);
     683          38 :         av_frame_free(&p->frame);
     684             :     }
     685             : 
     686          43 :     for (i = 0; i < thread_count; i++) {
     687          38 :         PerThreadContext *p = &fctx->threads[i];
     688             : 
     689          38 :         pthread_mutex_destroy(&p->mutex);
     690          38 :         pthread_mutex_destroy(&p->progress_mutex);
     691          38 :         pthread_cond_destroy(&p->input_cond);
     692          38 :         pthread_cond_destroy(&p->progress_cond);
     693          38 :         pthread_cond_destroy(&p->output_cond);
     694          38 :         av_packet_unref(&p->avpkt);
     695          38 :         av_freep(&p->released_buffers);
     696             : 
     697          38 :         if (i && p->avctx) {
     698          33 :             av_freep(&p->avctx->priv_data);
     699          33 :             av_freep(&p->avctx->slice_offset);
     700             :         }
     701             : 
     702          38 :         if (p->avctx) {
     703          38 :             av_freep(&p->avctx->internal);
     704          38 :             av_buffer_unref(&p->avctx->hw_frames_ctx);
     705             :         }
     706             : 
     707          38 :         av_freep(&p->avctx);
     708             :     }
     709             : 
     710           5 :     av_freep(&fctx->threads);
     711           5 :     pthread_mutex_destroy(&fctx->buffer_mutex);
     712           5 :     pthread_mutex_destroy(&fctx->hwaccel_mutex);
     713           5 :     pthread_mutex_destroy(&fctx->async_mutex);
     714           5 :     pthread_cond_destroy(&fctx->async_cond);
     715             : 
     716           5 :     av_freep(&avctx->internal->thread_ctx);
     717             : 
     718           5 :     if (avctx->priv_data && avctx->codec && avctx->codec->priv_class)
     719           1 :         av_opt_free(avctx->priv_data);
     720           5 :     avctx->codec = NULL;
     721           5 : }
     722             : 
     723           5 : int ff_frame_thread_init(AVCodecContext *avctx)
     724             : {
     725           5 :     int thread_count = avctx->thread_count;
     726           5 :     const AVCodec *codec = avctx->codec;
     727           5 :     AVCodecContext *src = avctx;
     728             :     FrameThreadContext *fctx;
     729           5 :     int i, err = 0;
     730             : 
     731             : #if HAVE_W32THREADS
     732             :     w32thread_init();
     733             : #endif
     734             : 
     735           5 :     if (!thread_count) {
     736           4 :         int nb_cpus = av_cpu_count();
     737             : #if FF_API_DEBUG_MV
     738             :         if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
     739             :             nb_cpus = 1;
     740             : #endif
     741             :         // use number of cores + 1 as thread count if there is more than one
     742           4 :         if (nb_cpus > 1)
     743           4 :             thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
     744             :         else
     745           0 :             thread_count = avctx->thread_count = 1;
     746             :     }
     747             : 
     748           5 :     if (thread_count <= 1) {
     749           0 :         avctx->active_thread_type = 0;
     750           0 :         return 0;
     751             :     }
     752             : 
     753           5 :     avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
     754           5 :     if (!fctx)
     755           0 :         return AVERROR(ENOMEM);
     756             : 
     757           5 :     fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext));
     758           5 :     if (!fctx->threads) {
     759           0 :         av_freep(&avctx->internal->thread_ctx);
     760           0 :         return AVERROR(ENOMEM);
     761             :     }
     762             : 
     763           5 :     pthread_mutex_init(&fctx->buffer_mutex, NULL);
     764           5 :     pthread_mutex_init(&fctx->hwaccel_mutex, NULL);
     765           5 :     pthread_mutex_init(&fctx->async_mutex, NULL);
     766           5 :     pthread_cond_init(&fctx->async_cond, NULL);
     767             : 
     768           5 :     fctx->async_lock = 1;
     769           5 :     fctx->delaying = 1;
     770             : 
     771          86 :     for (i = 0; i < thread_count; i++) {
     772          38 :         AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
     773          38 :         PerThreadContext *p  = &fctx->threads[i];
     774             : 
     775          38 :         pthread_mutex_init(&p->mutex, NULL);
     776          38 :         pthread_mutex_init(&p->progress_mutex, NULL);
     777          38 :         pthread_cond_init(&p->input_cond, NULL);
     778          38 :         pthread_cond_init(&p->progress_cond, NULL);
     779          38 :         pthread_cond_init(&p->output_cond, NULL);
     780             : 
     781          38 :         p->frame = av_frame_alloc();
     782          38 :         if (!p->frame) {
     783           0 :             av_freep(&copy);
     784           0 :             err = AVERROR(ENOMEM);
     785           0 :             goto error;
     786             :         }
     787             : 
     788          38 :         p->parent = fctx;
     789          38 :         p->avctx  = copy;
     790             : 
     791          38 :         if (!copy) {
     792           0 :             err = AVERROR(ENOMEM);
     793           0 :             goto error;
     794             :         }
     795             : 
     796          38 :         *copy = *src;
     797             : 
     798          38 :         copy->internal = av_malloc(sizeof(AVCodecInternal));
     799          38 :         if (!copy->internal) {
     800           0 :             copy->priv_data = NULL;
     801           0 :             err = AVERROR(ENOMEM);
     802           0 :             goto error;
     803             :         }
     804          38 :         *copy->internal = *src->internal;
     805          38 :         copy->internal->thread_ctx = p;
     806          38 :         copy->internal->last_pkt_props = &p->avpkt;
     807             : 
     808          38 :         if (!i) {
     809           5 :             src = copy;
     810             : 
     811           5 :             if (codec->init)
     812           5 :                 err = codec->init(copy);
     813             : 
     814           5 :             update_context_from_thread(avctx, copy, 1);
     815             :         } else {
     816          33 :             copy->priv_data = av_malloc(codec->priv_data_size);
     817          33 :             if (!copy->priv_data) {
     818           0 :                 err = AVERROR(ENOMEM);
     819           0 :                 goto error;
     820             :             }
     821          33 :             memcpy(copy->priv_data, src->priv_data, codec->priv_data_size);
     822          33 :             copy->internal->is_copy = 1;
     823             : 
     824          33 :             if (codec->init_thread_copy)
     825          33 :                 err = codec->init_thread_copy(copy);
     826             :         }
     827             : 
     828          38 :         if (err) goto error;
     829             : 
     830          38 :         atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
     831             : 
     832          38 :         err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
     833          38 :         p->thread_init= !err;
     834          38 :         if(!p->thread_init)
     835           0 :             goto error;
     836             :     }
     837             : 
     838           5 :     return 0;
     839             : 
     840           0 : error:
     841           0 :     ff_frame_thread_free(avctx, i+1);
     842             : 
     843           0 :     return err;
     844             : }
     845             : 
     846           0 : void ff_thread_flush(AVCodecContext *avctx)
     847             : {
     848             :     int i;
     849           0 :     FrameThreadContext *fctx = avctx->internal->thread_ctx;
     850             : 
     851           0 :     if (!fctx) return;
     852             : 
     853           0 :     park_frame_worker_threads(fctx, avctx->thread_count);
     854           0 :     if (fctx->prev_thread) {
     855           0 :         if (fctx->prev_thread != &fctx->threads[0])
     856           0 :             update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);
     857             :     }
     858             : 
     859           0 :     fctx->next_decoding = fctx->next_finished = 0;
     860           0 :     fctx->delaying = 1;
     861           0 :     fctx->prev_thread = NULL;
     862           0 :     for (i = 0; i < avctx->thread_count; i++) {
     863           0 :         PerThreadContext *p = &fctx->threads[i];
     864             :         // Make sure decode flush calls with size=0 won't return old frames
     865           0 :         p->got_frame = 0;
     866           0 :         av_frame_unref(p->frame);
     867           0 :         p->result = 0;
     868             : 
     869           0 :         release_delayed_buffers(p);
     870             : 
     871           0 :         if (avctx->codec->flush)
     872           0 :             avctx->codec->flush(p->avctx);
     873             :     }
     874             : }
     875             : 
     876       33292 : int ff_thread_can_start_frame(AVCodecContext *avctx)
     877             : {
     878       33292 :     PerThreadContext *p = avctx->internal->thread_ctx;
     879       33292 :     if ((avctx->active_thread_type&FF_THREAD_FRAME) && atomic_load(&p->state) != STATE_SETTING_UP &&
     880           0 :         (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
     881           0 :         return 0;
     882             :     }
     883       33292 :     return 1;
     884             : }
     885             : 
     886       76055 : static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)
     887             : {
     888       76055 :     PerThreadContext *p = avctx->internal->thread_ctx;
     889             :     int err;
     890             : 
     891       76055 :     f->owner[0] = f->owner[1] = avctx;
     892             : 
     893       76055 :     ff_init_buffer_info(avctx, f->f);
     894             : 
     895       76055 :     if (!(avctx->active_thread_type & FF_THREAD_FRAME))
     896       75923 :         return ff_get_buffer(avctx, f->f, flags);
     897             : 
     898         260 :     if (atomic_load(&p->state) != STATE_SETTING_UP &&
     899         256 :         (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
     900           0 :         av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
     901           0 :         return -1;
     902             :     }
     903             : 
     904         132 :     if (avctx->internal->allocate_progress) {
     905             :         atomic_int *progress;
     906           4 :         f->progress = av_buffer_alloc(2 * sizeof(*progress));
     907           4 :         if (!f->progress) {
     908           0 :             return AVERROR(ENOMEM);
     909             :         }
     910           4 :         progress = (atomic_int*)f->progress->data;
     911             : 
     912           4 :         atomic_init(&progress[0], -1);
     913           4 :         atomic_init(&progress[1], -1);
     914             :     }
     915             : 
     916         132 :     pthread_mutex_lock(&p->parent->buffer_mutex);
     917         132 :     if (avctx->thread_safe_callbacks ||
     918           0 :         avctx->get_buffer2 == avcodec_default_get_buffer2) {
     919         132 :         err = ff_get_buffer(avctx, f->f, flags);
     920             :     } else {
     921           0 :         pthread_mutex_lock(&p->progress_mutex);
     922           0 :         p->requested_frame = f->f;
     923           0 :         p->requested_flags = flags;
     924           0 :         atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release);
     925           0 :         pthread_cond_broadcast(&p->progress_cond);
     926             : 
     927           0 :         while (atomic_load(&p->state) != STATE_SETTING_UP)
     928           0 :             pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
     929             : 
     930           0 :         err = p->result;
     931             : 
     932           0 :         pthread_mutex_unlock(&p->progress_mutex);
     933             : 
     934             :     }
     935         132 :     if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context)
     936           0 :         ff_thread_finish_setup(avctx);
     937         132 :     if (err)
     938           0 :         av_buffer_unref(&f->progress);
     939             : 
     940         132 :     pthread_mutex_unlock(&p->parent->buffer_mutex);
     941             : 
     942         132 :     return err;
     943             : }
     944             : 
     945        1554 : enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
     946             : {
     947             :     enum AVPixelFormat res;
     948        1554 :     PerThreadContext *p = avctx->internal->thread_ctx;
     949        1554 :     if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks ||
     950           0 :         avctx->get_format == avcodec_default_get_format)
     951        1554 :         return ff_get_format(avctx, fmt);
     952           0 :     if (atomic_load(&p->state) != STATE_SETTING_UP) {
     953           0 :         av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n");
     954           0 :         return -1;
     955             :     }
     956           0 :     pthread_mutex_lock(&p->progress_mutex);
     957           0 :     p->available_formats = fmt;
     958           0 :     atomic_store(&p->state, STATE_GET_FORMAT);
     959           0 :     pthread_cond_broadcast(&p->progress_cond);
     960             : 
     961           0 :     while (atomic_load(&p->state) != STATE_SETTING_UP)
     962           0 :         pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
     963             : 
     964           0 :     res = p->result_format;
     965             : 
     966           0 :     pthread_mutex_unlock(&p->progress_mutex);
     967             : 
     968           0 :     return res;
     969             : }
     970             : 
     971       76055 : int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
     972             : {
     973       76055 :     int ret = thread_get_buffer_internal(avctx, f, flags);
     974       76055 :     if (ret < 0)
     975           0 :         av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
     976       76055 :     return ret;
     977             : }
     978             : 
     979      879975 : void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
     980             : {
     981      879975 :     PerThreadContext *p = avctx->internal->thread_ctx;
     982             :     FrameThreadContext *fctx;
     983             :     AVFrame *dst, *tmp;
     984     1760062 :     int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
     985      879975 :                           avctx->thread_safe_callbacks                   ||
     986           0 :                           avctx->get_buffer2 == avcodec_default_get_buffer2;
     987             : 
     988      879975 :     if (!f->f || !f->f->buf[0])
     989      687934 :         return;
     990             : 
     991      192041 :     if (avctx->debug & FF_DEBUG_BUFFERS)
     992           0 :         av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
     993             : 
     994      192041 :     av_buffer_unref(&f->progress);
     995      192041 :     f->owner[0] = f->owner[1] = NULL;
     996             : 
     997      192041 :     if (can_direct_free) {
     998      192041 :         av_frame_unref(f->f);
     999      192041 :         return;
    1000             :     }
    1001             : 
    1002           0 :     fctx = p->parent;
    1003           0 :     pthread_mutex_lock(&fctx->buffer_mutex);
    1004             : 
    1005           0 :     if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers))
    1006           0 :         goto fail;
    1007           0 :     tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
    1008           0 :                           (p->num_released_buffers + 1) *
    1009             :                           sizeof(*p->released_buffers));
    1010           0 :     if (!tmp)
    1011           0 :         goto fail;
    1012           0 :     p->released_buffers = tmp;
    1013             : 
    1014           0 :     dst = &p->released_buffers[p->num_released_buffers];
    1015           0 :     av_frame_move_ref(dst, f->f);
    1016             : 
    1017           0 :     p->num_released_buffers++;
    1018             : 
    1019           0 : fail:
    1020           0 :     pthread_mutex_unlock(&fctx->buffer_mutex);
    1021             : }

Generated by: LCOV version 1.13