FFmpeg
pthread_frame.c
Go to the documentation of this file.
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 "codec_internal.h"
32 #include "decode.h"
33 #include "hwconfig.h"
34 #include "internal.h"
35 #include "pthread_internal.h"
36 #include "thread.h"
37 #include "threadframe.h"
38 #include "version_major.h"
39 
40 #include "libavutil/avassert.h"
41 #include "libavutil/buffer.h"
42 #include "libavutil/common.h"
43 #include "libavutil/cpu.h"
44 #include "libavutil/frame.h"
45 #include "libavutil/internal.h"
46 #include "libavutil/log.h"
47 #include "libavutil/mem.h"
48 #include "libavutil/opt.h"
49 #include "libavutil/thread.h"
50 
51 enum {
52  ///< Set when the thread is awaiting a packet.
54  ///< Set before the codec has called ff_thread_finish_setup().
56  /**
57  * Set when the codec calls get_buffer().
58  * State is returned to STATE_SETTING_UP afterwards.
59  */
61  /**
62  * Set when the codec calls get_format().
63  * State is returned to STATE_SETTING_UP afterwards.
64  */
66  ///< Set after the codec has called ff_thread_finish_setup().
68 };
69 
70 enum {
71  UNINITIALIZED, ///< Thread has not been created, AVCodec->close mustn't be called
72  NEEDS_CLOSE, ///< FFCodec->close needs to be called
73  INITIALIZED, ///< Thread has been properly set up
74 };
75 
76 /**
77  * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
78  */
79 typedef struct PerThreadContext {
81 
84  unsigned pthread_init_cnt;///< Number of successfully initialized mutexes/conditions
85  pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread.
86  pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change.
87  pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish.
88 
89  pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext.
90  pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
91 
92  AVCodecContext *avctx; ///< Context used to decode packets passed to this thread.
93 
94  AVPacket *avpkt; ///< Input packet (for decoding) or output (for encoding).
95 
96  AVFrame *frame; ///< Output frame (for decoding) or input (for encoding).
97  int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
98  int result; ///< The result of the last codec decode/encode() call.
99 
101 
102 #if FF_API_THREAD_SAFE_CALLBACKS
103  /**
104  * Array of frames passed to ff_thread_release_buffer().
105  * Frames are released after all threads referencing them are finished.
106  */
110 
111  AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
112  int requested_flags; ///< flags passed to get_buffer() for requested_frame
113 
114  const enum AVPixelFormat *available_formats; ///< Format array for get_format()
115  enum AVPixelFormat result_format; ///< get_format() result
116 #endif
117 
118  int die; ///< Set when the thread should exit.
119 
122 
123  atomic_int debug_threads; ///< Set if the FF_DEBUG_THREADS option is set.
125 
126 /**
127  * Context stored in the client AVCodecInternal thread_ctx.
128  */
129 typedef struct FrameThreadContext {
130  PerThreadContext *threads; ///< The contexts for each thread.
131  PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
132 
133  unsigned pthread_init_cnt; ///< Number of successfully initialized mutexes/conditions
134  pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
135  /**
136  * This lock is used for ensuring threads run in serial when hwaccel
137  * is used.
138  */
143 
144  int next_decoding; ///< The next context to submit a packet to.
145  int next_finished; ///< The next context to return output from.
146 
147  int delaying; /**<
148  * Set for the first N packets, where N is the number of threads.
149  * While it is set, ff_thread_en/decode_frame won't return any results.
150  */
151 
152  /* hwaccel state is temporarily stored here in order to transfer its ownership
153  * to the next decoding thread without the need for extra synchronization */
158 
159 #if FF_API_THREAD_SAFE_CALLBACKS
160 #define THREAD_SAFE_CALLBACKS(avctx) \
161 ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2)
162 #endif
163 
164 static void async_lock(FrameThreadContext *fctx)
165 {
167  while (fctx->async_lock)
168  pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex);
169  fctx->async_lock = 1;
171 }
172 
174 {
176  av_assert0(fctx->async_lock);
177  fctx->async_lock = 0;
180 }
181 
183 {
184  AVCodecContext *avctx = p->avctx;
185  int idx = p - p->parent->threads;
186  char name[16];
187 
188  snprintf(name, sizeof(name), "av:%.7s:df%d", avctx->codec->name, idx);
189 
191 }
192 
193 /**
194  * Codec worker thread.
195  *
196  * Automatically calls ff_thread_finish_setup() if the codec does
197  * not provide an update_thread_context method, or if the codec returns
198  * before calling it.
199  */
200 static attribute_align_arg void *frame_worker_thread(void *arg)
201 {
202  PerThreadContext *p = arg;
203  AVCodecContext *avctx = p->avctx;
204  const FFCodec *codec = ffcodec(avctx->codec);
205 
206  thread_set_name(p);
207 
209  while (1) {
210  while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die)
212 
213  if (p->die) break;
214 
216  if (!codec->update_thread_context
218  && THREAD_SAFE_CALLBACKS(avctx)
219 #endif
220  )
221  ff_thread_finish_setup(avctx);
223 
224  /* If a decoder supports hwaccel, then it must call ff_get_format().
225  * Since that call must happen before ff_thread_finish_setup(), the
226  * decoder is required to implement update_thread_context() and call
227  * ff_thread_finish_setup() manually. Therefore the above
228  * ff_thread_finish_setup() call did not happen and hwaccel_serializing
229  * cannot be true here. */
231 
232  /* if the previous thread uses hwaccel then we take the lock to ensure
233  * the threads don't run concurrently */
234  if (avctx->hwaccel) {
236  p->hwaccel_serializing = 1;
237  }
238 
239  av_frame_unref(p->frame);
240  p->got_frame = 0;
241  p->result = codec->cb.decode(avctx, p->frame, &p->got_frame, p->avpkt);
242 
243  if ((p->result < 0 || !p->got_frame) && p->frame->buf[0])
244  ff_thread_release_buffer(avctx, p->frame);
245 
246  if (atomic_load(&p->state) == STATE_SETTING_UP)
247  ff_thread_finish_setup(avctx);
248 
249  if (p->hwaccel_serializing) {
250  /* wipe hwaccel state to avoid stale pointers lying around;
251  * the state was transferred to FrameThreadContext in
252  * ff_thread_finish_setup(), so nothing is leaked */
253  avctx->hwaccel = NULL;
254  avctx->hwaccel_context = NULL;
255  avctx->internal->hwaccel_priv_data = NULL;
256 
257  p->hwaccel_serializing = 0;
259  }
260  av_assert0(!avctx->hwaccel);
261 
262  if (p->async_serializing) {
263  p->async_serializing = 0;
264 
265  async_unlock(p->parent);
266  }
267 
269 
271 
275  }
277 
278  return NULL;
279 }
280 
281 /**
282  * Update the next thread's AVCodecContext with values from the reference thread's context.
283  *
284  * @param dst The destination context.
285  * @param src The source context.
286  * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
287  * @return 0 on success, negative error code on failure
288  */
290 {
291  const FFCodec *const codec = ffcodec(dst->codec);
292  int err = 0;
293 
294  if (dst != src && (for_user || codec->update_thread_context)) {
295  dst->time_base = src->time_base;
296  dst->framerate = src->framerate;
297  dst->width = src->width;
298  dst->height = src->height;
299  dst->pix_fmt = src->pix_fmt;
300  dst->sw_pix_fmt = src->sw_pix_fmt;
301 
302  dst->coded_width = src->coded_width;
303  dst->coded_height = src->coded_height;
304 
305  dst->has_b_frames = src->has_b_frames;
306  dst->idct_algo = src->idct_algo;
307  dst->properties = src->properties;
308 
309  dst->bits_per_coded_sample = src->bits_per_coded_sample;
310  dst->sample_aspect_ratio = src->sample_aspect_ratio;
311 
312  dst->profile = src->profile;
313  dst->level = src->level;
314 
315  dst->bits_per_raw_sample = src->bits_per_raw_sample;
316  dst->ticks_per_frame = src->ticks_per_frame;
317  dst->color_primaries = src->color_primaries;
318 
319  dst->color_trc = src->color_trc;
320  dst->colorspace = src->colorspace;
321  dst->color_range = src->color_range;
322  dst->chroma_sample_location = src->chroma_sample_location;
323 
324  dst->sample_rate = src->sample_rate;
325  dst->sample_fmt = src->sample_fmt;
326 #if FF_API_OLD_CHANNEL_LAYOUT
328  dst->channels = src->channels;
329  dst->channel_layout = src->channel_layout;
331 #endif
332  err = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
333  if (err < 0)
334  return err;
335 
336  if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
337  (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
339 
340  if (src->hw_frames_ctx) {
341  dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
342  if (!dst->hw_frames_ctx)
343  return AVERROR(ENOMEM);
344  }
345  }
346 
347  dst->hwaccel_flags = src->hwaccel_flags;
348 
349  err = av_buffer_replace(&dst->internal->pool, src->internal->pool);
350  if (err < 0)
351  return err;
352  }
353 
354  if (for_user) {
356  err = codec->update_thread_context_for_user(dst, src);
357  } else {
358  if (codec->update_thread_context)
359  err = codec->update_thread_context(dst, src);
360  }
361 
362  return err;
363 }
364 
365 /**
366  * Update the next thread's AVCodecContext with values set by the user.
367  *
368  * @param dst The destination context.
369  * @param src The source context.
370  * @return 0 on success, negative error code on failure
371  */
373 {
374  int err;
375 
376  dst->flags = src->flags;
377 
378  dst->draw_horiz_band= src->draw_horiz_band;
379  dst->get_buffer2 = src->get_buffer2;
380 
381  dst->opaque = src->opaque;
382  dst->debug = src->debug;
383 
384  dst->slice_flags = src->slice_flags;
385  dst->flags2 = src->flags2;
386  dst->export_side_data = src->export_side_data;
387 
388  dst->skip_loop_filter = src->skip_loop_filter;
389  dst->skip_idct = src->skip_idct;
390  dst->skip_frame = src->skip_frame;
391 
392  dst->frame_number = src->frame_number;
393  dst->reordered_opaque = src->reordered_opaque;
394 #if FF_API_THREAD_SAFE_CALLBACKS
396  dst->thread_safe_callbacks = src->thread_safe_callbacks;
398 #endif
399 
400  if (src->slice_count && src->slice_offset) {
401  if (dst->slice_count < src->slice_count) {
402  int err = av_reallocp_array(&dst->slice_offset, src->slice_count,
403  sizeof(*dst->slice_offset));
404  if (err < 0)
405  return err;
406  }
407  memcpy(dst->slice_offset, src->slice_offset,
408  src->slice_count * sizeof(*dst->slice_offset));
409  }
410  dst->slice_count = src->slice_count;
411 
413  err = av_packet_copy_props(dst->internal->last_pkt_props, src->internal->last_pkt_props);
414  if (err < 0)
415  return err;
416 
417  return 0;
418 }
419 
420 #if FF_API_THREAD_SAFE_CALLBACKS
421 /// Releases the buffers that this decoding thread was the last user of.
423 {
424  FrameThreadContext *fctx = p->parent;
425 
426  while (p->num_released_buffers > 0) {
427  AVFrame *f;
428 
430 
431  // fix extended data in case the caller screwed it up
435  f->extended_data = f->data;
436  av_frame_unref(f);
437 
439  }
440 }
441 #endif
442 
443 static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx,
444  AVPacket *avpkt)
445 {
446  FrameThreadContext *fctx = p->parent;
447  PerThreadContext *prev_thread = fctx->prev_thread;
448  const AVCodec *codec = p->avctx->codec;
449  int ret;
450 
451  if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY))
452  return 0;
453 
455 
456  ret = update_context_from_user(p->avctx, user_avctx);
457  if (ret) {
459  return ret;
460  }
462  (p->avctx->debug & FF_DEBUG_THREADS) != 0,
463  memory_order_relaxed);
464 
465 #if FF_API_THREAD_SAFE_CALLBACKS
467 #endif
468 
469  if (prev_thread) {
470  int err;
471  if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) {
472  pthread_mutex_lock(&prev_thread->progress_mutex);
473  while (atomic_load(&prev_thread->state) == STATE_SETTING_UP)
474  pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
475  pthread_mutex_unlock(&prev_thread->progress_mutex);
476  }
477 
478  err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
479  if (err) {
481  return err;
482  }
483  }
484 
485  /* transfer the stashed hwaccel state, if any */
486  av_assert0(!p->avctx->hwaccel);
487  FFSWAP(const AVHWAccel*, p->avctx->hwaccel, fctx->stash_hwaccel);
490 
492  ret = av_packet_ref(p->avpkt, avpkt);
493  if (ret < 0) {
495  av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n");
496  return ret;
497  }
498 
502 
503 #if FF_API_THREAD_SAFE_CALLBACKS
505  /*
506  * If the client doesn't have a thread-safe get_buffer(),
507  * then decoding threads call back to the main thread,
508  * and it calls back to the client here.
509  */
510 
511  if (!p->avctx->thread_safe_callbacks && (
515  int call_done = 1;
517  while (atomic_load(&p->state) == STATE_SETTING_UP)
519 
520  switch (atomic_load_explicit(&p->state, memory_order_acquire)) {
521  case STATE_GET_BUFFER:
523  break;
524  case STATE_GET_FORMAT:
526  break;
527  default:
528  call_done = 0;
529  break;
530  }
531  if (call_done) {
534  }
536  }
537  }
539 #endif
540 
541  fctx->prev_thread = p;
542  fctx->next_decoding++;
543 
544  return 0;
545 }
546 
548  AVFrame *picture, int *got_picture_ptr,
549  AVPacket *avpkt)
550 {
551  FrameThreadContext *fctx = avctx->internal->thread_ctx;
552  int finished = fctx->next_finished;
553  PerThreadContext *p;
554  int err;
555 
556  /* release the async lock, permitting blocked hwaccel threads to
557  * go forward while we are in this function */
558  async_unlock(fctx);
559 
560  /*
561  * Submit a packet to the next decoding thread.
562  */
563 
564  p = &fctx->threads[fctx->next_decoding];
565  err = submit_packet(p, avctx, avpkt);
566  if (err)
567  goto finish;
568 
569  /*
570  * If we're still receiving the initial packets, don't return a frame.
571  */
572 
573  if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
574  fctx->delaying = 0;
575 
576  if (fctx->delaying) {
577  *got_picture_ptr=0;
578  if (avpkt->size) {
579  err = avpkt->size;
580  goto finish;
581  }
582  }
583 
584  /*
585  * Return the next available frame from the oldest thread.
586  * If we're at the end of the stream, then we have to skip threads that
587  * didn't output a frame/error, because we don't want to accidentally signal
588  * EOF (avpkt->size == 0 && *got_picture_ptr == 0 && err >= 0).
589  */
590 
591  do {
592  p = &fctx->threads[finished++];
593 
594  if (atomic_load(&p->state) != STATE_INPUT_READY) {
596  while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY)
599  }
600 
601  av_frame_move_ref(picture, p->frame);
602  *got_picture_ptr = p->got_frame;
603  picture->pkt_dts = p->avpkt->dts;
604  err = p->result;
605 
606  /*
607  * A later call with avkpt->size == 0 may loop over all threads,
608  * including this one, searching for a frame/error to return before being
609  * stopped by the "finished != fctx->next_finished" condition.
610  * Make sure we don't mistakenly return the same frame/error again.
611  */
612  p->got_frame = 0;
613  p->result = 0;
614 
615  if (finished >= avctx->thread_count) finished = 0;
616  } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished);
617 
618  update_context_from_thread(avctx, p->avctx, 1);
619 
620  if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
621 
622  fctx->next_finished = finished;
623 
624  /* return the size of the consumed packet if no error occurred */
625  if (err >= 0)
626  err = avpkt->size;
627 finish:
628  async_lock(fctx);
629  return err;
630 }
631 
633 {
634  PerThreadContext *p;
635  atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
636 
637  if (!progress ||
638  atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
639  return;
640 
641  p = f->owner[field]->internal->thread_ctx;
642 
643  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
644  av_log(f->owner[field], AV_LOG_DEBUG,
645  "%p finished %d field %d\n", progress, n, field);
646 
648 
649  atomic_store_explicit(&progress[field], n, memory_order_release);
650 
653 }
654 
655 void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
656 {
657  PerThreadContext *p;
658  atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
659 
660  if (!progress ||
661  atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
662  return;
663 
664  p = f->owner[field]->internal->thread_ctx;
665 
666  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
667  av_log(f->owner[field], AV_LOG_DEBUG,
668  "thread awaiting %d field %d from %p\n", n, field, progress);
669 
671  while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n)
674 }
675 
677  PerThreadContext *p = avctx->internal->thread_ctx;
678 
679  if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
680 
681  if (avctx->hwaccel && !p->hwaccel_serializing) {
683  p->hwaccel_serializing = 1;
684  }
685 
686  /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */
687  if (avctx->hwaccel &&
689  p->async_serializing = 1;
690 
691  async_lock(p->parent);
692  }
693 
694  /* save hwaccel state for passing to the next thread;
695  * this is done here so that this worker thread can wipe its own hwaccel
696  * state after decoding, without requiring synchronization */
698  p->parent->stash_hwaccel = avctx->hwaccel;
701 
704  av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
705  }
706 
708 
711 }
712 
713 /// Waits for all threads to finish.
714 static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
715 {
716  int i;
717 
718  async_unlock(fctx);
719 
720  for (i = 0; i < thread_count; i++) {
721  PerThreadContext *p = &fctx->threads[i];
722 
723  if (atomic_load(&p->state) != STATE_INPUT_READY) {
725  while (atomic_load(&p->state) != STATE_INPUT_READY)
728  }
729  p->got_frame = 0;
730  }
731 
732  async_lock(fctx);
733 }
734 
735 #define OFF(member) offsetof(FrameThreadContext, member)
736 DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, pthread_init_cnt,
737  (OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),
738  (OFF(async_cond)));
739 #undef OFF
740 
741 #define OFF(member) offsetof(PerThreadContext, member)
742 DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread, pthread_init_cnt,
743  (OFF(progress_mutex), OFF(mutex)),
744  (OFF(input_cond), OFF(progress_cond), OFF(output_cond)));
745 #undef OFF
746 
747 void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
748 {
749  FrameThreadContext *fctx = avctx->internal->thread_ctx;
750  const FFCodec *codec = ffcodec(avctx->codec);
751  int i;
752 
753  park_frame_worker_threads(fctx, thread_count);
754 
755  for (i = 0; i < thread_count; i++) {
756  PerThreadContext *p = &fctx->threads[i];
757  AVCodecContext *ctx = p->avctx;
758 
759  if (ctx->internal) {
760  if (p->thread_init == INITIALIZED) {
762  p->die = 1;
765 
766  pthread_join(p->thread, NULL);
767  }
768  if (codec->close && p->thread_init != UNINITIALIZED)
769  codec->close(ctx);
770 
771 #if FF_API_THREAD_SAFE_CALLBACKS
773  for (int j = 0; j < p->released_buffers_allocated; j++)
776 #endif
777  if (ctx->priv_data) {
778  if (codec->p.priv_class)
781  }
782 
783  av_freep(&ctx->slice_offset);
784 
785  av_buffer_unref(&ctx->internal->pool);
786  av_packet_free(&ctx->internal->last_pkt_props);
787  av_freep(&ctx->internal);
788  av_buffer_unref(&ctx->hw_frames_ctx);
789  }
790 
791  av_frame_free(&p->frame);
792 
793  ff_pthread_free(p, per_thread_offsets);
794  av_packet_free(&p->avpkt);
795 
796  av_freep(&p->avctx);
797  }
798 
799  av_freep(&fctx->threads);
800  ff_pthread_free(fctx, thread_ctx_offsets);
801 
802  /* if we have stashed hwaccel state, move it to the user-facing context,
803  * so it will be freed in avcodec_close() */
804  av_assert0(!avctx->hwaccel);
805  FFSWAP(const AVHWAccel*, avctx->hwaccel, fctx->stash_hwaccel);
806  FFSWAP(void*, avctx->hwaccel_context, fctx->stash_hwaccel_context);
807  FFSWAP(void*, avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv);
808 
809  av_freep(&avctx->internal->thread_ctx);
810 }
811 
812 static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
813  FrameThreadContext *fctx, AVCodecContext *avctx,
814  const FFCodec *codec, int first)
815 {
817  int err;
818 
820 
821  copy = av_memdup(avctx, sizeof(*avctx));
822  if (!copy)
823  return AVERROR(ENOMEM);
824  copy->priv_data = NULL;
825 
826  /* From now on, this PerThreadContext will be cleaned up by
827  * ff_frame_thread_free in case of errors. */
828  (*threads_to_free)++;
829 
830  p->parent = fctx;
831  p->avctx = copy;
832 
833  copy->internal = av_mallocz(sizeof(*copy->internal));
834  if (!copy->internal)
835  return AVERROR(ENOMEM);
836  copy->internal->thread_ctx = p;
837 
838  copy->delay = avctx->delay;
839 
840  if (codec->priv_data_size) {
841  copy->priv_data = av_mallocz(codec->priv_data_size);
842  if (!copy->priv_data)
843  return AVERROR(ENOMEM);
844 
845  if (codec->p.priv_class) {
846  *(const AVClass **)copy->priv_data = codec->p.priv_class;
847  err = av_opt_copy(copy->priv_data, avctx->priv_data);
848  if (err < 0)
849  return err;
850  }
851  }
852 
853  err = ff_pthread_init(p, per_thread_offsets);
854  if (err < 0)
855  return err;
856 
857  if (!(p->frame = av_frame_alloc()) ||
858  !(p->avpkt = av_packet_alloc()))
859  return AVERROR(ENOMEM);
860 
861  if (!first)
862  copy->internal->is_copy = 1;
863 
864  copy->internal->last_pkt_props = av_packet_alloc();
865  if (!copy->internal->last_pkt_props)
866  return AVERROR(ENOMEM);
867 
868  if (codec->init) {
869  err = codec->init(copy);
870  if (err < 0) {
873  return err;
874  }
875  }
877 
878  if (first)
879  update_context_from_thread(avctx, copy, 1);
880 
881  atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
882 
884  if (err < 0)
885  return err;
887 
888  return 0;
889 }
890 
892 {
893  int thread_count = avctx->thread_count;
894  const FFCodec *codec = ffcodec(avctx->codec);
895  FrameThreadContext *fctx;
896  int err, i = 0;
897 
898  if (!thread_count) {
899  int nb_cpus = av_cpu_count();
900  // use number of cores + 1 as thread count if there is more than one
901  if (nb_cpus > 1)
902  thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
903  else
904  thread_count = avctx->thread_count = 1;
905  }
906 
907  if (thread_count <= 1) {
908  avctx->active_thread_type = 0;
909  return 0;
910  }
911 
912  avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
913  if (!fctx)
914  return AVERROR(ENOMEM);
915 
916  err = ff_pthread_init(fctx, thread_ctx_offsets);
917  if (err < 0) {
918  ff_pthread_free(fctx, thread_ctx_offsets);
919  av_freep(&avctx->internal->thread_ctx);
920  return err;
921  }
922 
923  fctx->async_lock = 1;
924  fctx->delaying = 1;
925 
926  if (codec->p.type == AVMEDIA_TYPE_VIDEO)
927  avctx->delay = avctx->thread_count - 1;
928 
929  fctx->threads = av_calloc(thread_count, sizeof(*fctx->threads));
930  if (!fctx->threads) {
931  err = AVERROR(ENOMEM);
932  goto error;
933  }
934 
935  for (; i < thread_count; ) {
936  PerThreadContext *p = &fctx->threads[i];
937  int first = !i;
938 
939  err = init_thread(p, &i, fctx, avctx, codec, first);
940  if (err < 0)
941  goto error;
942  }
943 
944  return 0;
945 
946 error:
947  ff_frame_thread_free(avctx, i);
948  return err;
949 }
950 
952 {
953  int i;
954  FrameThreadContext *fctx = avctx->internal->thread_ctx;
955 
956  if (!fctx) return;
957 
959  if (fctx->prev_thread) {
960  if (fctx->prev_thread != &fctx->threads[0])
962  }
963 
964  fctx->next_decoding = fctx->next_finished = 0;
965  fctx->delaying = 1;
966  fctx->prev_thread = NULL;
967  for (i = 0; i < avctx->thread_count; i++) {
968  PerThreadContext *p = &fctx->threads[i];
969  // Make sure decode flush calls with size=0 won't return old frames
970  p->got_frame = 0;
971  av_frame_unref(p->frame);
972  p->result = 0;
973 
974 #if FF_API_THREAD_SAFE_CALLBACKS
976 #endif
977 
978  if (ffcodec(avctx->codec)->flush)
979  ffcodec(avctx->codec)->flush(p->avctx);
980  }
981 }
982 
984 {
985  PerThreadContext *p = avctx->internal->thread_ctx;
990  || !THREAD_SAFE_CALLBACKS(avctx)
991 #endif
992  )) {
993  return 0;
994  }
996  return 1;
997 }
998 
1000 {
1001  PerThreadContext *p;
1002  int err;
1003 
1004  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
1005  return ff_get_buffer(avctx, f, flags);
1006 
1007  p = avctx->internal->thread_ctx;
1009  if (atomic_load(&p->state) != STATE_SETTING_UP &&
1012  || !THREAD_SAFE_CALLBACKS(avctx)
1013 #endif
1014  )) {
1016  av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
1017  return -1;
1018  }
1019 
1021 #if !FF_API_THREAD_SAFE_CALLBACKS
1022  err = ff_get_buffer(avctx, f, flags);
1023 #else
1025  if (THREAD_SAFE_CALLBACKS(avctx)) {
1026  err = ff_get_buffer(avctx, f, flags);
1027  } else {
1029  p->requested_frame = f;
1030  p->requested_flags = flags;
1031  atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release);
1033 
1034  while (atomic_load(&p->state) != STATE_SETTING_UP)
1036 
1037  err = p->result;
1038 
1040 
1041  }
1042  if (!THREAD_SAFE_CALLBACKS(avctx) && !ffcodec(avctx->codec)->update_thread_context)
1043  ff_thread_finish_setup(avctx);
1045 #endif
1046 
1048 
1049  return err;
1050 }
1051 
1052 #if FF_API_THREAD_SAFE_CALLBACKS
1055 {
1056  enum AVPixelFormat res;
1057  PerThreadContext *p;
1058  if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks ||
1060  return ff_get_format(avctx, fmt);
1061 
1062  p = avctx->internal->thread_ctx;
1063  if (atomic_load(&p->state) != STATE_SETTING_UP) {
1064  av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n");
1065  return -1;
1066  }
1068  p->available_formats = fmt;
1071 
1072  while (atomic_load(&p->state) != STATE_SETTING_UP)
1074 
1075  res = p->result_format;
1076 
1078 
1079  return res;
1080 }
1082 #endif
1083 
1085 {
1086  int ret = thread_get_buffer_internal(avctx, f, flags);
1087  if (ret < 0)
1088  av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
1089  return ret;
1090 }
1091 
1093 {
1094  int ret;
1095 
1096  f->owner[0] = f->owner[1] = avctx;
1097  /* Hint: It is possible for this function to be called with codecs
1098  * that don't support frame threading at all, namely in case
1099  * a frame-threaded decoder shares code with codecs that are not.
1100  * This currently affects non-MPEG-4 mpegvideo codecs and and VP7.
1101  * The following check will always be true for them. */
1102  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
1103  return ff_get_buffer(avctx, f->f, flags);
1104 
1106  atomic_int *progress;
1107  f->progress = av_buffer_alloc(2 * sizeof(*progress));
1108  if (!f->progress) {
1109  return AVERROR(ENOMEM);
1110  }
1111  progress = (atomic_int*)f->progress->data;
1112 
1113  atomic_init(&progress[0], -1);
1114  atomic_init(&progress[1], -1);
1115  }
1116 
1117  ret = ff_thread_get_buffer(avctx, f->f, flags);
1118  if (ret)
1119  av_buffer_unref(&f->progress);
1120  return ret;
1121 }
1122 
1124 {
1125 #if FF_API_THREAD_SAFE_CALLBACKS
1127  PerThreadContext *p;
1128  FrameThreadContext *fctx;
1129  AVFrame *dst;
1130  int ret = 0;
1131  int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
1132  THREAD_SAFE_CALLBACKS(avctx);
1134 #endif
1135 
1136  if (!f)
1137  return;
1138 
1139  if (avctx->debug & FF_DEBUG_BUFFERS)
1140  av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
1141 
1142 #if !FF_API_THREAD_SAFE_CALLBACKS
1143  av_frame_unref(f);
1144 #else
1145  // when the frame buffers are not allocated, just reset it to clean state
1146  if (can_direct_free || !f->buf[0]) {
1147  av_frame_unref(f);
1148  return;
1149  }
1150 
1151  p = avctx->internal->thread_ctx;
1152  fctx = p->parent;
1154 
1155  if (p->num_released_buffers == p->released_buffers_allocated) {
1156  AVFrame **tmp = av_realloc_array(p->released_buffers, p->released_buffers_allocated + 1,
1157  sizeof(*p->released_buffers));
1158  if (tmp) {
1159  tmp[p->released_buffers_allocated] = av_frame_alloc();
1160  p->released_buffers = tmp;
1161  }
1162 
1163  if (!tmp || !tmp[p->released_buffers_allocated]) {
1164  ret = AVERROR(ENOMEM);
1165  goto fail;
1166  }
1167  p->released_buffers_allocated++;
1168  }
1169 
1170  dst = p->released_buffers[p->num_released_buffers];
1171  av_frame_move_ref(dst, f);
1172 
1173  p->num_released_buffers++;
1174 
1175 fail:
1177 
1178  // make sure the frame is clean even if we fail to free it
1179  // this leaks, but it is better than crashing
1180  if (ret < 0) {
1181  av_log(avctx, AV_LOG_ERROR, "Could not queue a frame for freeing, this will leak\n");
1182  memset(f->buf, 0, sizeof(f->buf));
1183  if (f->extended_buf)
1184  memset(f->extended_buf, 0, f->nb_extended_buf * sizeof(*f->extended_buf));
1185  av_frame_unref(f);
1186  }
1187 #endif
1188 }
1189 
1191 {
1192  av_buffer_unref(&f->progress);
1193  f->owner[0] = f->owner[1] = NULL;
1194  ff_thread_release_buffer(avctx, f->f);
1195 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
hwconfig.h
FFCodec::update_thread_context
int(* update_thread_context)(struct AVCodecContext *dst, const struct AVCodecContext *src)
Copy necessary context variables from a previous thread context to the current one.
Definition: codec_internal.h:149
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:422
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1369
AVCodec
AVCodec.
Definition: codec.h:204
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:82
thread_set_name
static void thread_set_name(PerThreadContext *p)
Definition: pthread_frame.c:182
AVCodecContext::hwaccel_context
void * hwaccel_context
Legacy hardware accelerator context.
Definition: avcodec.h:1393
pthread_join
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
Definition: os2threads.h:94
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
PerThreadContext::input_cond
pthread_cond_t input_cond
Used to wait for a new packet from the main thread.
Definition: pthread_frame.c:85
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
NEEDS_CLOSE
@ NEEDS_CLOSE
FFCodec->close needs to be called.
Definition: pthread_frame.c:72
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AVCodecContext::get_format
enum AVPixelFormat(* get_format)(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
Callback to negotiate the pixel format.
Definition: avcodec.h:662
STATE_SETTING_UP
@ STATE_SETTING_UP
Definition: pthread_frame.c:55
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:975
ff_thread_release_ext_buffer
void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f)
Unref a ThreadFrame.
Definition: pthread_frame.c:1190
STATE_GET_FORMAT
@ STATE_GET_FORMAT
Set when the codec calls get_format().
Definition: pthread_frame.c:65
ff_get_format
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition: decode.c:1147
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1007
PerThreadContext::debug_threads
atomic_int debug_threads
Set if the FF_DEBUG_THREADS option is set.
Definition: pthread_frame.c:123
AVCodec::priv_class
const AVClass * priv_class
AVClass for the private context.
Definition: codec.h:236
FrameThreadContext::next_decoding
int next_decoding
The next context to submit a packet to.
Definition: pthread_frame.c:144
thread.h
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
ff_thread_flush
void ff_thread_flush(AVCodecContext *avctx)
Wait for decoding threads to finish and reset internal state.
Definition: pthread_frame.c:951
init_thread
static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, FrameThreadContext *fctx, AVCodecContext *avctx, const FFCodec *codec, int first)
Definition: pthread_frame.c:812
AVHWAccel::caps_internal
int caps_internal
Internal hwaccel capabilities.
Definition: avcodec.h:2207
ff_thread_can_start_frame
int ff_thread_can_start_frame(AVCodecContext *avctx)
Definition: pthread_frame.c:983
MAX_AUTO_THREADS
#define MAX_AUTO_THREADS
Definition: pthread_internal.h:26
PerThreadContext::state
atomic_int state
Definition: pthread_frame.c:100
FrameThreadContext
Context stored in the client AVCodecInternal thread_ctx.
Definition: pthread_frame.c:129
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:116
park_frame_worker_threads
static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
Waits for all threads to finish.
Definition: pthread_frame.c:714
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
THREAD_SAFE_CALLBACKS
#define THREAD_SAFE_CALLBACKS(avctx)
Definition: pthread_frame.c:160
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:968
AVCodecContext::slice_offset
int * slice_offset
slice offsets in the frame in bytes
Definition: avcodec.h:759
AVCodec::capabilities
int capabilities
Codec capabilities.
Definition: codec.h:223
internal.h
version_major.h
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
FFCodec
Definition: codec_internal.h:119
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
avcodec_default_get_format
enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
Definition: decode.c:935
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:530
FrameThreadContext::stash_hwaccel_context
void * stash_hwaccel_context
Definition: pthread_frame.c:155
AVCodecContext::delay
int delay
Codec delay.
Definition: avcodec.h:554
PerThreadContext::die
int die
Set when the thread should exit.
Definition: pthread_frame.c:118
thread.h
ff_pthread_free
av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
Definition: pthread.c:94
FrameThreadContext::next_finished
int next_finished
The next context to return output from.
Definition: pthread_frame.c:145
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:73
ff_thread_get_buffer
FF_ENABLE_DEPRECATION_WARNINGS int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1084
AVCodecInternal::pool
AVBufferRef * pool
Definition: internal.h:71
AVCodecContext::slice_count
int slice_count
slice count
Definition: avcodec.h:752
FrameThreadContext::buffer_mutex
pthread_mutex_t buffer_mutex
Mutex used to protect get/release_buffer().
Definition: pthread_frame.c:134
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:312
FFCodec::priv_data_size
int priv_data_size
Definition: codec_internal.h:137
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1735
ff_frame_thread_free
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
Definition: pthread_frame.c:747
AVHWAccel
Definition: avcodec.h:2070
AVCodecContext::skip_idct
enum AVDiscard skip_idct
Skip IDCT/dequantization for selected frames.
Definition: avcodec.h:1691
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:123
finish
static void finish(void)
Definition: movenc.c:342
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:407
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:2059
AVCodecContext::skip_frame
enum AVDiscard skip_frame
Skip decoding for selected frames.
Definition: avcodec.h:1698
fail
#define fail()
Definition: checkasm.h:134
PerThreadContext::available_formats
enum AVPixelFormat * available_formats
Format array for get_format()
Definition: pthread_frame.c:114
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1466
FrameThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:133
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:478
PerThreadContext
Context used by codec threads and stored in their AVCodecInternal thread_ctx.
Definition: pthread_frame.c:79
FF_API_THREAD_SAFE_CALLBACKS
#define FF_API_THREAD_SAFE_CALLBACKS
Definition: version_major.h:43
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:586
submit_packet
static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, AVPacket *avpkt)
Definition: pthread_frame.c:443
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:104
AVCodecContext::get_buffer2
int(* get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags)
This callback is called at the beginning of each frame to get data buffer(s) for it.
Definition: avcodec.h:1176
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
avassert.h
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:961
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
ff_thread_report_progress
void ff_thread_report_progress(ThreadFrame *f, int n, int field)
Notify later decoding threads when part of their reference picture is ready.
Definition: pthread_frame.c:632
FFCodec::update_thread_context_for_user
int(* update_thread_context_for_user)(struct AVCodecContext *dst, const struct AVCodecContext *src)
Copy variables back to the user-facing context.
Definition: codec_internal.h:154
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:694
FrameThreadContext::async_lock
int async_lock
Definition: pthread_frame.c:142
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:225
PerThreadContext::output_cond
pthread_cond_t output_cond
Used by the main thread to wait for frames to finish.
Definition: pthread_frame.c:87
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecContext::ticks_per_frame
int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:530
PerThreadContext::requested_flags
int requested_flags
flags passed to get_buffer() for requested_frame
Definition: pthread_frame.c:112
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1451
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
FFCodec::flush
void(* flush)(struct AVCodecContext *)
Flush buffers.
Definition: codec_internal.h:238
decode.h
update_context_from_user
static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
Update the next thread's AVCodecContext with values set by the user.
Definition: pthread_frame.c:372
field
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this field
Definition: writing_filters.txt:78
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
pthread_cond_broadcast
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
Definition: os2threads.h:162
FrameThreadContext::prev_thread
PerThreadContext * prev_thread
The last thread submit_packet() was called on.
Definition: pthread_frame.c:131
FFCodec::decode
int(* decode)(struct AVCodecContext *avctx, struct AVFrame *frame, int *got_frame_ptr, struct AVPacket *avpkt)
Decode to an AVFrame.
Definition: codec_internal.h:185
FFCodec::init
int(* init)(struct AVCodecContext *)
Definition: codec_internal.h:170
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:408
arg
const char * arg
Definition: jacosubdec.c:67
pthread_create
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
Definition: os2threads.h:80
if
if(ret)
Definition: filter_design.txt:179
PerThreadContext::got_frame
int got_frame
The output of got_picture_ptr from the last avcodec_decode_video() call.
Definition: pthread_frame.c:97
threadframe.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:982
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
ff_thread_await_progress
void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
Definition: pthread_frame.c:655
AVCodecContext::slice_flags
int slice_flags
slice flags
Definition: avcodec.h:861
thread_get_buffer_internal
static int thread_get_buffer_internal(AVCodecContext *avctx, AVFrame *f, int flags)
Definition: pthread_frame.c:999
AVCodec::type
enum AVMediaType type
Definition: codec.h:217
frame_worker_thread
static attribute_align_arg void * frame_worker_thread(void *arg)
Codec worker thread.
Definition: pthread_frame.c:200
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:433
PerThreadContext::released_buffers
AVFrame ** released_buffers
Array of frames passed to ff_thread_release_buffer().
Definition: pthread_frame.c:107
PerThreadContext::progress_mutex
pthread_mutex_t progress_mutex
Mutex used to protect frame progress values and progress_cond.
Definition: pthread_frame.c:90
FrameThreadContext::async_mutex
pthread_mutex_t async_mutex
Definition: pthread_frame.c:140
ff_thread_finish_setup
void ff_thread_finish_setup(AVCodecContext *avctx)
If the codec defines update_thread_context(), call this when they are ready for the next thread to st...
Definition: pthread_frame.c:676
FrameThreadContext::hwaccel_mutex
pthread_mutex_t hwaccel_mutex
This lock is used for ensuring threads run in serial when hwaccel is used.
Definition: pthread_frame.c:139
PerThreadContext::avctx
AVCodecContext * avctx
Context used to decode packets passed to this thread.
Definition: pthread_frame.c:92
pthread_internal.h
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1719
AVCodecContext::thread_safe_callbacks
attribute_deprecated int thread_safe_callbacks
Set by the client if its custom get_buffer() callback can be called synchronously from another thread...
Definition: avcodec.h:1505
AVFrame::pkt_dts
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
Definition: frame.h:444
STATE_GET_BUFFER
@ STATE_GET_BUFFER
Set when the codec calls get_buffer().
Definition: pthread_frame.c:60
FF_DEBUG_BUFFERS
#define FF_DEBUG_BUFFERS
Definition: avcodec.h:1339
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:430
AVCodecContext::level
int level
level
Definition: avcodec.h:1676
atomic_load_explicit
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:96
FF_DEBUG_THREADS
#define FF_DEBUG_THREADS
Definition: avcodec.h:1340
OFF
#define OFF(member)
Definition: pthread_frame.c:741
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:79
AVCodecInternal::last_pkt_props
AVPacket * last_pkt_props
Properties (timestamps+side data) extracted from the last packet passed for decoding.
Definition: internal.h:90
async_lock
static void async_lock(FrameThreadContext *fctx)
Definition: pthread_frame.c:164
PerThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:84
FFCodec::cb
union FFCodec::@50 cb
PerThreadContext::thread
pthread_t thread
Definition: pthread_frame.c:82
av_cpu_count
int av_cpu_count(void)
Definition: cpu.c:206
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:521
PerThreadContext::result
int result
The result of the last codec decode/encode() call.
Definition: pthread_frame.c:98
INITIALIZED
@ INITIALIZED
Thread has been properly set up.
Definition: pthread_frame.c:73
FrameThreadContext::stash_hwaccel
const AVHWAccel * stash_hwaccel
Definition: pthread_frame.c:154
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:85
f
f
Definition: af_crystalizer.c:122
AVCodecContext::flags2
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:485
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1461
AVPacket::size
int size
Definition: packet.h:375
ff_thread_decode_frame
int ff_thread_decode_frame(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt)
Submit a new frame to a decoding thread.
Definition: pthread_frame.c:547
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:187
codec_internal.h
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:137
cpu.h
PerThreadContext::avpkt
AVPacket * avpkt
Input packet (for decoding) or output (for encoding).
Definition: pthread_frame.c:94
async_unlock
static void async_unlock(FrameThreadContext *fctx)
Definition: pthread_frame.c:173
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1023
FrameThreadContext::async_cond
pthread_cond_t async_cond
Definition: pthread_frame.c:141
FF_CODEC_CAP_ALLOCATE_PROGRESS
#define FF_CODEC_CAP_ALLOCATE_PROGRESS
Definition: codec_internal.h:69
PerThreadContext::num_released_buffers
int num_released_buffers
Definition: pthread_frame.c:108
ffcodec
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
Definition: codec_internal.h:317
frame.h
buffer.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:373
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:233
PerThreadContext::parent
struct FrameThreadContext * parent
Definition: pthread_frame.c:80
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:62
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
AVCodecContext::skip_loop_filter
enum AVDiscard skip_loop_filter
Skip loop filtering for selected frames.
Definition: avcodec.h:1684
pthread_t
Definition: os2threads.h:44
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1477
ff_thread_release_buffer
void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
Wrapper around release_buffer() frame-for multithreaded codecs.
Definition: pthread_frame.c:1123
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1444
avcodec_default_get_buffer2
int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags)
The default callback for AVCodecContext.get_buffer2().
Definition: get_buffer.c:282
FFCodec::caps_internal
unsigned caps_internal
Internal codec capabilities FF_CODEC_CAP_*.
Definition: codec_internal.h:128
av_packet_copy_props
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
Copy only "properties" fields from src to dst.
Definition: avpacket.c:385
PerThreadContext::thread_init
int thread_init
Definition: pthread_frame.c:83
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVCodecContext::properties
unsigned properties
Properties of the stream that gets decoded.
Definition: avcodec.h:1847
internal.h
common.h
AVCodecContext::hwaccel_flags
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition: avcodec.h:1942
atomic_store_explicit
#define atomic_store_explicit(object, desired, order)
Definition: stdatomic.h:90
release_delayed_buffers
static void release_delayed_buffers(PerThreadContext *p)
Releases the buffers that this decoding thread was the last user of.
Definition: pthread_frame.c:422
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Definition: hwconfig.h:26
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_frame_move_ref
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition: frame.c:516
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:487
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:264
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1420
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:211
av_buffer_replace
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition: buffer.c:233
AVCodecContext::chroma_sample_location
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:989
pthread_cond_t
Definition: os2threads.h:58
AVCodecContext::height
int height
Definition: avcodec.h:571
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:608
ff_thread_get_ext_buffer
int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around ff_get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1092
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1883
avcodec.h
DEFINE_OFFSET_ARRAY
DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, pthread_init_cnt,(OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),(OFF(async_cond)))
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
ff_frame_thread_init
int ff_frame_thread_init(AVCodecContext *avctx)
Definition: pthread_frame.c:891
PerThreadContext::async_serializing
int async_serializing
Definition: pthread_frame.c:121
AVCodecContext::opaque
void * opaque
Private data of the user, can be used to carry app specific stuff.
Definition: avcodec.h:440
pthread_cond_signal
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:152
AVCodecContext::draw_horiz_band
void(* draw_horiz_band)(struct AVCodecContext *s, const AVFrame *src, int offset[AV_NUM_DATA_POINTERS], int y, int type, int height)
If non NULL, 'draw_horiz_band' is called by the libavcodec decoder to draw a horizontal band.
Definition: avcodec.h:633
AVCodecContext
main external API structure.
Definition: avcodec.h:398
AVCodecContext::active_thread_type
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1485
PerThreadContext::hwaccel_serializing
int hwaccel_serializing
Definition: pthread_frame.c:120
ThreadFrame
Definition: threadframe.h:27
UNINITIALIZED
@ UNINITIALIZED
Thread has not been created, AVCodec->close mustn't be called.
Definition: pthread_frame.c:71
PerThreadContext::frame
AVFrame * frame
Output frame (for decoding) or input (for encoding).
Definition: pthread_frame.c:96
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1550
ff_thread_get_format
FF_DISABLE_DEPRECATION_WARNINGS enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Wrapper around get_format() for frame-multithreaded codecs.
Definition: pthread_frame.c:1054
PerThreadContext::result_format
enum AVPixelFormat result_format
get_format() result
Definition: pthread_frame.c:115
AVCodecContext::export_side_data
int export_side_data
Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of metadata exported in frame,...
Definition: avcodec.h:2009
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: codec.h:82
STATE_SETUP_FINISHED
@ STATE_SETUP_FINISHED
Definition: pthread_frame.c:67
FFCodec::close
int(* close)(struct AVCodecContext *)
Definition: codec_internal.h:232
ff_pthread_init
av_cold int ff_pthread_init(void *obj, const unsigned offsets[])
Initialize/destroy a list of mutexes/conditions contained in a structure.
Definition: pthread.c:107
pthread_cond_wait
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:192
AVCodecContext::debug
int debug
debug
Definition: avcodec.h:1327
av_channel_layout_copy
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
Definition: channel_layout.c:639
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:81
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:586
AVCodecContext::codec_type
enum AVMediaType codec_type
Definition: avcodec.h:406
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FrameThreadContext::delaying
int delaying
Set for the first N packets, where N is the number of threads.
Definition: pthread_frame.c:147
mem.h
STATE_INPUT_READY
@ STATE_INPUT_READY
Set when the thread is awaiting a packet.
Definition: pthread_frame.c:53
AVCodecContext::frame_number
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:1046
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:1885
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:425
AVPacket
This structure stores compressed data.
Definition: packet.h:351
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AVCodecContext::reordered_opaque
int64_t reordered_opaque
opaque 64-bit number (generally a PTS) that will be reordered and output in AVFrame....
Definition: avcodec.h:1362
AVCodecInternal::thread_ctx
void * thread_ctx
Definition: internal.h:73
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:571
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
PerThreadContext::mutex
pthread_mutex_t mutex
Mutex used to protect the contents of the PerThreadContext.
Definition: pthread_frame.c:89
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
PerThreadContext::requested_frame
AVFrame * requested_frame
AVFrame the codec passed to get_buffer()
Definition: pthread_frame.c:111
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1742
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
snprintf
#define snprintf
Definition: snprintf.h:34
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1244
AVCodecContext::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition: avcodec.h:768
FrameThreadContext::stash_hwaccel_priv
void * stash_hwaccel_priv
Definition: pthread_frame.c:156
mutex
static AVMutex mutex
Definition: log.c:46
PerThreadContext::released_buffers_allocated
int released_buffers_allocated
Definition: pthread_frame.c:109
PerThreadContext::progress_cond
pthread_cond_t progress_cond
Used by child threads to wait for progress to change.
Definition: pthread_frame.c:86
FrameThreadContext::threads
PerThreadContext * threads
The contexts for each thread.
Definition: pthread_frame.c:130
update_context_from_thread
static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user)
Update the next thread's AVCodecContext with values from the reference thread's context.
Definition: pthread_frame.c:289
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:75
ff_thread_setname
static int ff_thread_setname(const char *name)
Definition: thread.h:195