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 "hwconfig.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.
51  ///< Set before the codec has called ff_thread_finish_setup().
53  /**
54  * Set when the codec calls get_buffer().
55  * State is returned to STATE_SETTING_UP afterwards.
56  */
58  /**
59  * Set when the codec calls get_format().
60  * State is returned to STATE_SETTING_UP afterwards.
61  */
63  ///< Set after the codec has called ff_thread_finish_setup().
65 };
66 
67 enum {
68  UNINITIALIZED, ///< Thread has not been created, AVCodec->close mustn't be called
69  NEEDS_CLOSE, ///< AVCodec->close needs to be called
70  INITIALIZED, ///< Thread has been properly set up
71 };
72 
73 /**
74  * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
75  */
76 typedef struct PerThreadContext {
78 
81  unsigned pthread_init_cnt;///< Number of successfully initialized mutexes/conditions
82  pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread.
83  pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change.
84  pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish.
85 
86  pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext.
87  pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
88 
89  AVCodecContext *avctx; ///< Context used to decode packets passed to this thread.
90 
91  AVPacket *avpkt; ///< Input packet (for decoding) or output (for encoding).
92 
93  AVFrame *frame; ///< Output frame (for decoding) or input (for encoding).
94  int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
95  int result; ///< The result of the last codec decode/encode() call.
96 
98 
99 #if FF_API_THREAD_SAFE_CALLBACKS
100  /**
101  * Array of frames passed to ff_thread_release_buffer().
102  * Frames are released after all threads referencing them are finished.
103  */
107 
108  AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
109  int requested_flags; ///< flags passed to get_buffer() for requested_frame
110 
111  const enum AVPixelFormat *available_formats; ///< Format array for get_format()
112  enum AVPixelFormat result_format; ///< get_format() result
113 #endif
114 
115  int die; ///< Set when the thread should exit.
116 
119 
120  atomic_int debug_threads; ///< Set if the FF_DEBUG_THREADS option is set.
122 
123 /**
124  * Context stored in the client AVCodecInternal thread_ctx.
125  */
126 typedef struct FrameThreadContext {
127  PerThreadContext *threads; ///< The contexts for each thread.
128  PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
129 
130  unsigned pthread_init_cnt; ///< Number of successfully initialized mutexes/conditions
131  pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
132  /**
133  * This lock is used for ensuring threads run in serial when hwaccel
134  * is used.
135  */
140 
141  int next_decoding; ///< The next context to submit a packet to.
142  int next_finished; ///< The next context to return output from.
143 
144  int delaying; /**<
145  * Set for the first N packets, where N is the number of threads.
146  * While it is set, ff_thread_en/decode_frame won't return any results.
147  */
149 
150 #if FF_API_THREAD_SAFE_CALLBACKS
151 #define THREAD_SAFE_CALLBACKS(avctx) \
152 ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2)
153 #endif
154 
155 static void async_lock(FrameThreadContext *fctx)
156 {
158  while (fctx->async_lock)
159  pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex);
160  fctx->async_lock = 1;
162 }
163 
165 {
167  av_assert0(fctx->async_lock);
168  fctx->async_lock = 0;
171 }
172 
173 /**
174  * Codec worker thread.
175  *
176  * Automatically calls ff_thread_finish_setup() if the codec does
177  * not provide an update_thread_context method, or if the codec returns
178  * before calling it.
179  */
180 static attribute_align_arg void *frame_worker_thread(void *arg)
181 {
182  PerThreadContext *p = arg;
183  AVCodecContext *avctx = p->avctx;
184  const AVCodec *codec = avctx->codec;
185 
187  while (1) {
188  while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die)
190 
191  if (p->die) break;
192 
194  if (!codec->update_thread_context
196  && THREAD_SAFE_CALLBACKS(avctx)
197 #endif
198  )
199  ff_thread_finish_setup(avctx);
201 
202  /* If a decoder supports hwaccel, then it must call ff_get_format().
203  * Since that call must happen before ff_thread_finish_setup(), the
204  * decoder is required to implement update_thread_context() and call
205  * ff_thread_finish_setup() manually. Therefore the above
206  * ff_thread_finish_setup() call did not happen and hwaccel_serializing
207  * cannot be true here. */
209 
210  /* if the previous thread uses hwaccel then we take the lock to ensure
211  * the threads don't run concurrently */
212  if (avctx->hwaccel) {
214  p->hwaccel_serializing = 1;
215  }
216 
217  av_frame_unref(p->frame);
218  p->got_frame = 0;
219  p->result = codec->decode(avctx, p->frame, &p->got_frame, p->avpkt);
220 
221  if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) {
223  av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not "
224  "free the frame on failure. This is a bug, please report it.\n");
225  av_frame_unref(p->frame);
226  }
227 
228  if (atomic_load(&p->state) == STATE_SETTING_UP)
229  ff_thread_finish_setup(avctx);
230 
231  if (p->hwaccel_serializing) {
232  p->hwaccel_serializing = 0;
234  }
235 
236  if (p->async_serializing) {
237  p->async_serializing = 0;
238 
239  async_unlock(p->parent);
240  }
241 
243 
245 
249  }
251 
252  return NULL;
253 }
254 
255 /**
256  * Update the next thread's AVCodecContext with values from the reference thread's context.
257  *
258  * @param dst The destination context.
259  * @param src The source context.
260  * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
261  * @return 0 on success, negative error code on failure
262  */
264 {
265  int err = 0;
266 
267  if (dst != src && (for_user || src->codec->update_thread_context)) {
268  dst->time_base = src->time_base;
269  dst->framerate = src->framerate;
270  dst->width = src->width;
271  dst->height = src->height;
272  dst->pix_fmt = src->pix_fmt;
273  dst->sw_pix_fmt = src->sw_pix_fmt;
274 
275  dst->coded_width = src->coded_width;
276  dst->coded_height = src->coded_height;
277 
278  dst->has_b_frames = src->has_b_frames;
279  dst->idct_algo = src->idct_algo;
280 
281  dst->bits_per_coded_sample = src->bits_per_coded_sample;
282  dst->sample_aspect_ratio = src->sample_aspect_ratio;
283 
284  dst->profile = src->profile;
285  dst->level = src->level;
286 
287  dst->bits_per_raw_sample = src->bits_per_raw_sample;
288  dst->ticks_per_frame = src->ticks_per_frame;
289  dst->color_primaries = src->color_primaries;
290 
291  dst->color_trc = src->color_trc;
292  dst->colorspace = src->colorspace;
293  dst->color_range = src->color_range;
294  dst->chroma_sample_location = src->chroma_sample_location;
295 
296  dst->hwaccel = src->hwaccel;
297  dst->hwaccel_context = src->hwaccel_context;
298 
299  dst->channels = src->channels;
300  dst->sample_rate = src->sample_rate;
301  dst->sample_fmt = src->sample_fmt;
302  dst->channel_layout = src->channel_layout;
303  dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
304 
305  if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
306  (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
308 
309  if (src->hw_frames_ctx) {
310  dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
311  if (!dst->hw_frames_ctx)
312  return AVERROR(ENOMEM);
313  }
314  }
315 
316  dst->hwaccel_flags = src->hwaccel_flags;
317 
318  err = av_buffer_replace(&dst->internal->pool, src->internal->pool);
319  if (err < 0)
320  return err;
321  }
322 
323  if (for_user) {
325  err = dst->codec->update_thread_context_for_user(dst, src);
326  } else {
327  if (dst->codec->update_thread_context)
328  err = dst->codec->update_thread_context(dst, src);
329  }
330 
331  return err;
332 }
333 
334 /**
335  * Update the next thread's AVCodecContext with values set by the user.
336  *
337  * @param dst The destination context.
338  * @param src The source context.
339  * @return 0 on success, negative error code on failure
340  */
342 {
343  dst->flags = src->flags;
344 
345  dst->draw_horiz_band= src->draw_horiz_band;
346  dst->get_buffer2 = src->get_buffer2;
347 
348  dst->opaque = src->opaque;
349  dst->debug = src->debug;
350 
351  dst->slice_flags = src->slice_flags;
352  dst->flags2 = src->flags2;
353  dst->export_side_data = src->export_side_data;
354 
355  dst->skip_loop_filter = src->skip_loop_filter;
356  dst->skip_idct = src->skip_idct;
357  dst->skip_frame = src->skip_frame;
358 
359  dst->frame_number = src->frame_number;
360  dst->reordered_opaque = src->reordered_opaque;
361 #if FF_API_THREAD_SAFE_CALLBACKS
363  dst->thread_safe_callbacks = src->thread_safe_callbacks;
365 #endif
366 
367  if (src->slice_count && src->slice_offset) {
368  if (dst->slice_count < src->slice_count) {
369  int err = av_reallocp_array(&dst->slice_offset, src->slice_count,
370  sizeof(*dst->slice_offset));
371  if (err < 0)
372  return err;
373  }
374  memcpy(dst->slice_offset, src->slice_offset,
375  src->slice_count * sizeof(*dst->slice_offset));
376  }
377  dst->slice_count = src->slice_count;
378  return 0;
379 }
380 
381 #if FF_API_THREAD_SAFE_CALLBACKS
382 /// Releases the buffers that this decoding thread was the last user of.
384 {
385  FrameThreadContext *fctx = p->parent;
386 
387  while (p->num_released_buffers > 0) {
388  AVFrame *f;
389 
391 
392  // fix extended data in case the caller screwed it up
396  f->extended_data = f->data;
397  av_frame_unref(f);
398 
400  }
401 }
402 #endif
403 
404 static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx,
405  AVPacket *avpkt)
406 {
407  FrameThreadContext *fctx = p->parent;
408  PerThreadContext *prev_thread = fctx->prev_thread;
409  const AVCodec *codec = p->avctx->codec;
410  int ret;
411 
412  if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY))
413  return 0;
414 
416 
417  ret = update_context_from_user(p->avctx, user_avctx);
418  if (ret) {
420  return ret;
421  }
423  (p->avctx->debug & FF_DEBUG_THREADS) != 0,
424  memory_order_relaxed);
425 
426 #if FF_API_THREAD_SAFE_CALLBACKS
428 #endif
429 
430  if (prev_thread) {
431  int err;
432  if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) {
433  pthread_mutex_lock(&prev_thread->progress_mutex);
434  while (atomic_load(&prev_thread->state) == STATE_SETTING_UP)
435  pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
436  pthread_mutex_unlock(&prev_thread->progress_mutex);
437  }
438 
439  err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
440  if (err) {
442  return err;
443  }
444  }
445 
447  ret = av_packet_ref(p->avpkt, avpkt);
448  if (ret < 0) {
450  av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n");
451  return ret;
452  }
453 
457 
458 #if FF_API_THREAD_SAFE_CALLBACKS
460  /*
461  * If the client doesn't have a thread-safe get_buffer(),
462  * then decoding threads call back to the main thread,
463  * and it calls back to the client here.
464  */
465 
466  if (!p->avctx->thread_safe_callbacks && (
470  int call_done = 1;
472  while (atomic_load(&p->state) == STATE_SETTING_UP)
474 
475  switch (atomic_load_explicit(&p->state, memory_order_acquire)) {
476  case STATE_GET_BUFFER:
478  break;
479  case STATE_GET_FORMAT:
481  break;
482  default:
483  call_done = 0;
484  break;
485  }
486  if (call_done) {
489  }
491  }
492  }
494 #endif
495 
496  fctx->prev_thread = p;
497  fctx->next_decoding++;
498 
499  return 0;
500 }
501 
503  AVFrame *picture, int *got_picture_ptr,
504  AVPacket *avpkt)
505 {
506  FrameThreadContext *fctx = avctx->internal->thread_ctx;
507  int finished = fctx->next_finished;
508  PerThreadContext *p;
509  int err;
510 
511  /* release the async lock, permitting blocked hwaccel threads to
512  * go forward while we are in this function */
513  async_unlock(fctx);
514 
515  /*
516  * Submit a packet to the next decoding thread.
517  */
518 
519  p = &fctx->threads[fctx->next_decoding];
520  err = submit_packet(p, avctx, avpkt);
521  if (err)
522  goto finish;
523 
524  /*
525  * If we're still receiving the initial packets, don't return a frame.
526  */
527 
528  if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
529  fctx->delaying = 0;
530 
531  if (fctx->delaying) {
532  *got_picture_ptr=0;
533  if (avpkt->size) {
534  err = avpkt->size;
535  goto finish;
536  }
537  }
538 
539  /*
540  * Return the next available frame from the oldest thread.
541  * If we're at the end of the stream, then we have to skip threads that
542  * didn't output a frame/error, because we don't want to accidentally signal
543  * EOF (avpkt->size == 0 && *got_picture_ptr == 0 && err >= 0).
544  */
545 
546  do {
547  p = &fctx->threads[finished++];
548 
549  if (atomic_load(&p->state) != STATE_INPUT_READY) {
551  while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY)
554  }
555 
556  av_frame_move_ref(picture, p->frame);
557  *got_picture_ptr = p->got_frame;
558  picture->pkt_dts = p->avpkt->dts;
559  err = p->result;
560 
561  /*
562  * A later call with avkpt->size == 0 may loop over all threads,
563  * including this one, searching for a frame/error to return before being
564  * stopped by the "finished != fctx->next_finished" condition.
565  * Make sure we don't mistakenly return the same frame/error again.
566  */
567  p->got_frame = 0;
568  p->result = 0;
569 
570  if (finished >= avctx->thread_count) finished = 0;
571  } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished);
572 
573  update_context_from_thread(avctx, p->avctx, 1);
574 
575  if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
576 
577  fctx->next_finished = finished;
578 
579  /* return the size of the consumed packet if no error occurred */
580  if (err >= 0)
581  err = avpkt->size;
582 finish:
583  async_lock(fctx);
584  return err;
585 }
586 
588 {
589  PerThreadContext *p;
590  atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
591 
592  if (!progress ||
593  atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
594  return;
595 
596  p = f->owner[field]->internal->thread_ctx;
597 
598  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
599  av_log(f->owner[field], AV_LOG_DEBUG,
600  "%p finished %d field %d\n", progress, n, field);
601 
603 
604  atomic_store_explicit(&progress[field], n, memory_order_release);
605 
608 }
609 
611 {
612  PerThreadContext *p;
613  atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
614 
615  if (!progress ||
616  atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
617  return;
618 
619  p = f->owner[field]->internal->thread_ctx;
620 
621  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
622  av_log(f->owner[field], AV_LOG_DEBUG,
623  "thread awaiting %d field %d from %p\n", n, field, progress);
624 
626  while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n)
629 }
630 
632  PerThreadContext *p = avctx->internal->thread_ctx;
633 
634  if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
635 
636  if (avctx->hwaccel && !p->hwaccel_serializing) {
638  p->hwaccel_serializing = 1;
639  }
640 
641  /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */
642  if (avctx->hwaccel &&
644  p->async_serializing = 1;
645 
646  async_lock(p->parent);
647  }
648 
651  av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
652  }
653 
655 
658 }
659 
660 /// Waits for all threads to finish.
661 static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
662 {
663  int i;
664 
665  async_unlock(fctx);
666 
667  for (i = 0; i < thread_count; i++) {
668  PerThreadContext *p = &fctx->threads[i];
669 
670  if (atomic_load(&p->state) != STATE_INPUT_READY) {
672  while (atomic_load(&p->state) != STATE_INPUT_READY)
675  }
676  p->got_frame = 0;
677  }
678 
679  async_lock(fctx);
680 }
681 
682 #define SENTINEL 0 // This forbids putting a mutex/condition variable at the front.
683 #define OFFSET_ARRAY(...) __VA_ARGS__, SENTINEL
684 #define DEFINE_OFFSET_ARRAY(type, name, mutexes, conds) \
685 static const unsigned name ## _offsets[] = { offsetof(type, pthread_init_cnt),\
686  OFFSET_ARRAY mutexes, \
687  OFFSET_ARRAY conds }
688 
689 #define OFF(member) offsetof(FrameThreadContext, member)
691  (OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),
692  (OFF(async_cond)));
693 #undef OFF
694 
695 #define OFF(member) offsetof(PerThreadContext, member)
697  (OFF(progress_mutex), OFF(mutex)),
698  (OFF(input_cond), OFF(progress_cond), OFF(output_cond)));
699 #undef OFF
700 
701 static av_cold void free_pthread(void *obj, const unsigned offsets[])
702 {
703  unsigned cnt = *(unsigned*)((char*)obj + offsets[0]);
704  const unsigned *cur_offset = offsets;
705 
706  for (; *(++cur_offset) != SENTINEL && cnt; cnt--)
707  pthread_mutex_destroy((pthread_mutex_t*)((char*)obj + *cur_offset));
708  for (; *(++cur_offset) != SENTINEL && cnt; cnt--)
709  pthread_cond_destroy ((pthread_cond_t *)((char*)obj + *cur_offset));
710 }
711 
712 static av_cold int init_pthread(void *obj, const unsigned offsets[])
713 {
714  const unsigned *cur_offset = offsets;
715  unsigned cnt = 0;
716  int err;
717 
718 #define PTHREAD_INIT_LOOP(type) \
719  for (; *(++cur_offset) != SENTINEL; cnt++) { \
720  pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset); \
721  err = pthread_ ## type ## _init(dst, NULL); \
722  if (err) { \
723  err = AVERROR(err); \
724  goto fail; \
725  } \
726  }
729 
730 fail:
731  *(unsigned*)((char*)obj + offsets[0]) = cnt;
732  return err;
733 }
734 
735 void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
736 {
737  FrameThreadContext *fctx = avctx->internal->thread_ctx;
738  const AVCodec *codec = avctx->codec;
739  int i;
740 
741  park_frame_worker_threads(fctx, thread_count);
742 
743  if (fctx->prev_thread && avctx->internal->hwaccel_priv_data !=
745  if (update_context_from_thread(avctx, fctx->prev_thread->avctx, 1) < 0) {
746  av_log(avctx, AV_LOG_ERROR, "Failed to update user thread.\n");
747  }
748  }
749 
750  if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
751  if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
752  av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
754  fctx->threads->avctx->internal->is_copy = 1;
755  }
756 
757  for (i = 0; i < thread_count; i++) {
758  PerThreadContext *p = &fctx->threads[i];
759  AVCodecContext *ctx = p->avctx;
760 
761  if (ctx->internal) {
762  if (p->thread_init == INITIALIZED) {
764  p->die = 1;
767 
768  pthread_join(p->thread, NULL);
769  }
770  if (codec->close && p->thread_init != UNINITIALIZED)
771  codec->close(ctx);
772 
773 #if FF_API_THREAD_SAFE_CALLBACKS
775  for (int j = 0; j < p->released_buffers_allocated; j++)
778 #endif
779  if (ctx->priv_data) {
780  if (codec->priv_class)
783  }
784 
785  av_freep(&ctx->slice_offset);
786 
787  av_buffer_unref(&ctx->internal->pool);
788  av_freep(&ctx->internal);
789  av_buffer_unref(&ctx->hw_frames_ctx);
790  }
791 
792  av_frame_free(&p->frame);
793 
794  free_pthread(p, per_thread_offsets);
795  av_packet_free(&p->avpkt);
796 
797  av_freep(&p->avctx);
798  }
799 
800  av_freep(&fctx->threads);
801  free_pthread(fctx, thread_ctx_offsets);
802 
803  av_freep(&avctx->internal->thread_ctx);
804 }
805 
806 static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
807  FrameThreadContext *fctx, AVCodecContext *avctx,
808  AVCodecContext *src, const AVCodec *codec, int first)
809 {
811  int err;
812 
814 
815  copy = av_memdup(src, sizeof(*src));
816  if (!copy)
817  return AVERROR(ENOMEM);
818  copy->priv_data = NULL;
819 
820  /* From now on, this PerThreadContext will be cleaned up by
821  * ff_frame_thread_free in case of errors. */
822  (*threads_to_free)++;
823 
824  p->parent = fctx;
825  p->avctx = copy;
826 
827  copy->internal = av_memdup(src->internal, sizeof(*src->internal));
828  if (!copy->internal)
829  return AVERROR(ENOMEM);
830  copy->internal->thread_ctx = p;
831 
832  copy->delay = avctx->delay;
833 
834  if (codec->priv_data_size) {
835  copy->priv_data = av_mallocz(codec->priv_data_size);
836  if (!copy->priv_data)
837  return AVERROR(ENOMEM);
838 
839  if (codec->priv_class) {
840  *(const AVClass **)copy->priv_data = codec->priv_class;
841  err = av_opt_copy(copy->priv_data, src->priv_data);
842  if (err < 0)
843  return err;
844  }
845  }
846 
847  err = init_pthread(p, per_thread_offsets);
848  if (err < 0)
849  return err;
850 
851  if (!(p->frame = av_frame_alloc()) ||
852  !(p->avpkt = av_packet_alloc()))
853  return AVERROR(ENOMEM);
854  copy->internal->last_pkt_props = p->avpkt;
855 
856  if (!first)
857  copy->internal->is_copy = 1;
858 
859  if (codec->init) {
860  err = codec->init(copy);
861  if (err < 0) {
864  return err;
865  }
866  }
868 
869  if (first)
870  update_context_from_thread(avctx, copy, 1);
871 
872  atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
873 
875  if (err < 0)
876  return err;
878 
879  return 0;
880 }
881 
883 {
884  int thread_count = avctx->thread_count;
885  const AVCodec *codec = avctx->codec;
886  AVCodecContext *src = avctx;
887  FrameThreadContext *fctx;
888  int err, i = 0;
889 
890  if (!thread_count) {
891  int nb_cpus = av_cpu_count();
892  // use number of cores + 1 as thread count if there is more than one
893  if (nb_cpus > 1)
894  thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
895  else
896  thread_count = avctx->thread_count = 1;
897  }
898 
899  if (thread_count <= 1) {
900  avctx->active_thread_type = 0;
901  return 0;
902  }
903 
904  avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
905  if (!fctx)
906  return AVERROR(ENOMEM);
907 
908  err = init_pthread(fctx, thread_ctx_offsets);
909  if (err < 0) {
910  free_pthread(fctx, thread_ctx_offsets);
911  av_freep(&avctx->internal->thread_ctx);
912  return err;
913  }
914 
915  fctx->async_lock = 1;
916  fctx->delaying = 1;
917 
918  if (codec->type == AVMEDIA_TYPE_VIDEO)
919  avctx->delay = src->thread_count - 1;
920 
921  fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext));
922  if (!fctx->threads) {
923  err = AVERROR(ENOMEM);
924  goto error;
925  }
926 
927  for (; i < thread_count; ) {
928  PerThreadContext *p = &fctx->threads[i];
929  int first = !i;
930 
931  err = init_thread(p, &i, fctx, avctx, src, codec, first);
932  if (err < 0)
933  goto error;
934  }
935 
936  return 0;
937 
938 error:
939  ff_frame_thread_free(avctx, i);
940  return err;
941 }
942 
944 {
945  int i;
946  FrameThreadContext *fctx = avctx->internal->thread_ctx;
947 
948  if (!fctx) return;
949 
951  if (fctx->prev_thread) {
952  if (fctx->prev_thread != &fctx->threads[0])
954  }
955 
956  fctx->next_decoding = fctx->next_finished = 0;
957  fctx->delaying = 1;
958  fctx->prev_thread = NULL;
959  for (i = 0; i < avctx->thread_count; i++) {
960  PerThreadContext *p = &fctx->threads[i];
961  // Make sure decode flush calls with size=0 won't return old frames
962  p->got_frame = 0;
963  av_frame_unref(p->frame);
964  p->result = 0;
965 
966 #if FF_API_THREAD_SAFE_CALLBACKS
968 #endif
969 
970  if (avctx->codec->flush)
971  avctx->codec->flush(p->avctx);
972  }
973 }
974 
976 {
977  PerThreadContext *p = avctx->internal->thread_ctx;
982  || !THREAD_SAFE_CALLBACKS(avctx)
983 #endif
984  )) {
985  return 0;
986  }
988  return 1;
989 }
990 
992 {
993  PerThreadContext *p = avctx->internal->thread_ctx;
994  int err;
995 
996  f->owner[0] = f->owner[1] = avctx;
997 
998  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
999  return ff_get_buffer(avctx, f->f, flags);
1000 
1002  if (atomic_load(&p->state) != STATE_SETTING_UP &&
1003  (avctx->codec->update_thread_context
1005  || !THREAD_SAFE_CALLBACKS(avctx)
1006 #endif
1007  )) {
1009  av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
1010  return -1;
1011  }
1012 
1014  atomic_int *progress;
1015  f->progress = av_buffer_alloc(2 * sizeof(*progress));
1016  if (!f->progress) {
1017  return AVERROR(ENOMEM);
1018  }
1019  progress = (atomic_int*)f->progress->data;
1020 
1021  atomic_init(&progress[0], -1);
1022  atomic_init(&progress[1], -1);
1023  }
1024 
1026 #if !FF_API_THREAD_SAFE_CALLBACKS
1027  err = ff_get_buffer(avctx, f->f, flags);
1028 #else
1030  if (THREAD_SAFE_CALLBACKS(avctx)) {
1031  err = ff_get_buffer(avctx, f->f, flags);
1032  } else {
1034  p->requested_frame = f->f;
1035  p->requested_flags = flags;
1036  atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release);
1038 
1039  while (atomic_load(&p->state) != STATE_SETTING_UP)
1041 
1042  err = p->result;
1043 
1045 
1046  }
1047  if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context)
1048  ff_thread_finish_setup(avctx);
1050 #endif
1051  if (err)
1052  av_buffer_unref(&f->progress);
1053 
1055 
1056  return err;
1057 }
1058 
1059 #if FF_API_THREAD_SAFE_CALLBACKS
1062 {
1063  enum AVPixelFormat res;
1064  PerThreadContext *p = avctx->internal->thread_ctx;
1065  if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks ||
1067  return ff_get_format(avctx, fmt);
1068  if (atomic_load(&p->state) != STATE_SETTING_UP) {
1069  av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n");
1070  return -1;
1071  }
1073  p->available_formats = fmt;
1076 
1077  while (atomic_load(&p->state) != STATE_SETTING_UP)
1079 
1080  res = p->result_format;
1081 
1083 
1084  return res;
1085 }
1087 #endif
1088 
1090 {
1091  int ret = thread_get_buffer_internal(avctx, f, flags);
1092  if (ret < 0)
1093  av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
1094  return ret;
1095 }
1096 
1098 {
1099 #if FF_API_THREAD_SAFE_CALLBACKS
1101  PerThreadContext *p = avctx->internal->thread_ctx;
1102  FrameThreadContext *fctx;
1103  AVFrame *dst;
1104  int ret = 0;
1105  int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
1106  THREAD_SAFE_CALLBACKS(avctx);
1108 #endif
1109 
1110  if (!f->f)
1111  return;
1112 
1113  if (avctx->debug & FF_DEBUG_BUFFERS)
1114  av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
1115 
1116  av_buffer_unref(&f->progress);
1117  f->owner[0] = f->owner[1] = NULL;
1118 
1119 #if !FF_API_THREAD_SAFE_CALLBACKS
1120  av_frame_unref(f->f);
1121 #else
1122  // when the frame buffers are not allocated, just reset it to clean state
1123  if (can_direct_free || !f->f->buf[0]) {
1124  av_frame_unref(f->f);
1125  return;
1126  }
1127 
1128  fctx = p->parent;
1130 
1131  if (p->num_released_buffers == p->released_buffers_allocated) {
1132  AVFrame **tmp = av_realloc_array(p->released_buffers, p->released_buffers_allocated + 1,
1133  sizeof(*p->released_buffers));
1134  if (tmp) {
1135  tmp[p->released_buffers_allocated] = av_frame_alloc();
1136  p->released_buffers = tmp;
1137  }
1138 
1139  if (!tmp || !tmp[p->released_buffers_allocated]) {
1140  ret = AVERROR(ENOMEM);
1141  goto fail;
1142  }
1143  p->released_buffers_allocated++;
1144  }
1145 
1146  dst = p->released_buffers[p->num_released_buffers];
1147  av_frame_move_ref(dst, f->f);
1148 
1149  p->num_released_buffers++;
1150 
1151 fail:
1153 
1154  // make sure the frame is clean even if we fail to free it
1155  // this leaks, but it is better than crashing
1156  if (ret < 0) {
1157  av_log(avctx, AV_LOG_ERROR, "Could not queue a frame for freeing, this will leak\n");
1158  memset(f->f->buf, 0, sizeof(f->f->buf));
1159  if (f->f->extended_buf)
1160  memset(f->f->extended_buf, 0, f->f->nb_extended_buf * sizeof(*f->f->extended_buf));
1161  av_frame_unref(f->f);
1162  }
1163 #endif
1164 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:30
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
hwconfig.h
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:403
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1348
AVCodec
AVCodec.
Definition: codec.h:197
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
AVCodecContext::hwaccel_context
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:1359
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:187
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
PerThreadContext::input_cond
pthread_cond_t input_cond
Used to wait for a new packet from the main thread.
Definition: pthread_frame.c:82
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
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 pixelFormat
Definition: avcodec.h:636
FF_API_THREAD_SAFE_CALLBACKS
#define FF_API_THREAD_SAFE_CALLBACKS
Definition: version.h:64
AVCodecContext::channel_layout
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:1032
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:949
ff_get_format
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition: decode.c:1081
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:981
PerThreadContext::debug_threads
atomic_int debug_threads
Set if the FF_DEBUG_THREADS option is set.
Definition: pthread_frame.c:120
AVCodec::priv_class
const AVClass * priv_class
AVClass for the private context.
Definition: codec.h:223
AVCodec::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.h:257
FrameThreadContext::next_decoding
int next_decoding
The next context to submit a packet to.
Definition: pthread_frame.c:141
thread.h
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:92
ff_thread_flush
void ff_thread_flush(AVCodecContext *avctx)
Wait for decoding threads to finish and reset internal state.
Definition: pthread_frame.c:943
AVHWAccel::caps_internal
int caps_internal
Internal hwaccel capabilities.
Definition: avcodec.h:2175
ff_thread_can_start_frame
int ff_thread_can_start_frame(AVCodecContext *avctx)
Definition: pthread_frame.c:975
MAX_AUTO_THREADS
#define MAX_AUTO_THREADS
Definition: pthread_internal.h:26
PerThreadContext::state
atomic_int state
Definition: pthread_frame.c:97
FrameThreadContext
Context stored in the client AVCodecInternal thread_ctx.
Definition: pthread_frame.c:126
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:111
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:661
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:27
THREAD_SAFE_CALLBACKS
#define THREAD_SAFE_CALLBACKS(avctx)
Definition: pthread_frame.c:151
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:942
AVCodecContext::slice_offset
int * slice_offset
slice offsets in the frame in bytes
Definition: avcodec.h:733
AVCodec::capabilities
int capabilities
Codec capabilities.
Definition: codec.h:216
internal.h
INITIALIZED
@ INITIALIZED
Thread has been properly set up.
Definition: pthread_frame.c:70
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
version.h
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:197
avcodec_default_get_format
enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
Definition: decode.c:869
AVCodec::flush
void(* flush)(struct AVCodecContext *)
Flush buffers.
Definition: codec.h:325
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:477
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1555
AVCodecContext::delay
int delay
Codec delay.
Definition: avcodec.h:540
PerThreadContext::die
int die
Set when the thread should exit.
Definition: pthread_frame.c:115
thread.h
free_pthread
static av_cold void free_pthread(void *obj, const unsigned offsets[])
Definition: pthread_frame.c:701
FrameThreadContext::next_finished
int next_finished
The next context to return output from.
Definition: pthread_frame.c:142
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:70
AVCodecInternal::pool
AVBufferRef * pool
Definition: internal.h:144
AVCodecContext::slice_count
int slice_count
slice count
Definition: avcodec.h:726
FrameThreadContext::buffer_mutex
pthread_mutex_t buffer_mutex
Mutex used to protect get/release_buffer().
Definition: pthread_frame.c:131
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:292
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1699
AVCodecInternal::is_copy
int is_copy
Whether the parent AVCodecContext is a copy of the context which had init() called on it.
Definition: internal.h:136
ff_frame_thread_free
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
Definition: pthread_frame.c:735
AVCodecContext::skip_idct
enum AVDiscard skip_idct
Skip IDCT/dequantization for selected frames.
Definition: avcodec.h:1655
finish
static void finish(void)
Definition: movenc.c:342
init_pthread
static av_cold int init_pthread(void *obj, const unsigned offsets[])
Definition: pthread_frame.c:712
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:393
AVCodecContext::skip_frame
enum AVDiscard skip_frame
Skip decoding for selected frames.
Definition: avcodec.h:1662
fail
#define fail()
Definition: checkasm.h:134
PerThreadContext::available_formats
enum AVPixelFormat * available_formats
Format array for get_format()
Definition: pthread_frame.c:111
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1429
FrameThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:130
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:464
PerThreadContext
Context used by codec threads and stored in their AVCodecInternal thread_ctx.
Definition: pthread_frame.c:76
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:572
submit_packet
static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, AVPacket *avpkt)
Definition: pthread_frame.c:404
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:98
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:1136
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:935
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:181
av_cold
#define av_cold
Definition: attributes.h:90
ff_thread_await_progress
void ff_thread_await_progress(ThreadFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
Definition: pthread_frame.c:610
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:587
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:668
FrameThreadContext::async_lock
int async_lock
Definition: pthread_frame.c:139
offsets
static const int offsets[]
Definition: hevc_pel.c:34
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:205
PerThreadContext::output_cond
pthread_cond_t output_cond
Used by the main thread to wait for frames to finish.
Definition: pthread_frame.c:84
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:516
PerThreadContext::requested_flags
int requested_flags
flags passed to get_buffer() for requested_frame
Definition: pthread_frame.c:109
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:1414
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:202
STATE_SETUP_FINISHED
@ STATE_SETUP_FINISHED
Definition: pthread_frame.c:64
ctx
AVFormatContext * ctx
Definition: movenc.c:48
STATE_GET_BUFFER
@ STATE_GET_BUFFER
Set when the codec calls get_buffer().
Definition: pthread_frame.c:57
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:341
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
f
#define f(width, name)
Definition: cbs_vp9.c:255
FrameThreadContext::prev_thread
PerThreadContext * prev_thread
The last thread submit_packet() was called on.
Definition: pthread_frame.c:128
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:394
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:94
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
STATE_SETTING_UP
@ STATE_SETTING_UP
Definition: pthread_frame.c:52
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:956
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:125
AVCodecContext::slice_flags
int slice_flags
slice flags
Definition: avcodec.h:835
AVCodec::type
enum AVMediaType type
Definition: codec.h:210
frame_worker_thread
static attribute_align_arg void * frame_worker_thread(void *arg)
Codec worker thread.
Definition: pthread_frame.c:180
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:419
PerThreadContext::released_buffers
AVFrame ** released_buffers
Array of frames passed to ff_thread_release_buffer().
Definition: pthread_frame.c:104
PerThreadContext::progress_mutex
pthread_mutex_t progress_mutex
Mutex used to protect frame progress values and progress_cond.
Definition: pthread_frame.c:87
src
#define src
Definition: vp8dsp.c:255
FrameThreadContext::async_mutex
pthread_mutex_t async_mutex
Definition: pthread_frame.c:137
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:631
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:136
PerThreadContext::avctx
AVCodecContext * avctx
Context used to decode packets passed to this thread.
Definition: pthread_frame.c:89
pthread_internal.h
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1611
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:1468
AVFrame::pkt_dts
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
Definition: frame.h:403
FF_DEBUG_BUFFERS
#define FF_DEBUG_BUFFERS
Definition: avcodec.h:1303
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:410
AVCodecContext::level
int level
level
Definition: avcodec.h:1640
atomic_load_explicit
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:96
FF_DEBUG_THREADS
#define FF_DEBUG_THREADS
Definition: avcodec.h:1304
OFF
#define OFF(member)
Definition: pthread_frame.c:695
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:67
async_lock
static void async_lock(FrameThreadContext *fctx)
Definition: pthread_frame.c:155
PerThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:81
ff_thread_release_buffer
void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
Wrapper around release_buffer() frame-for multithreaded codecs.
Definition: pthread_frame.c:1097
PerThreadContext::thread
pthread_t thread
Definition: pthread_frame.c:79
av_cpu_count
int av_cpu_count(void)
Definition: cpu.c:184
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:507
PerThreadContext::result
int result
The result of the last codec decode/encode() call.
Definition: pthread_frame.c:95
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:83
AVCodecContext::flags2
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:471
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1645
AVPacket::size
int size
Definition: packet.h:366
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:502
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:194
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:182
AVCodec::close
int(* close)(struct AVCodecContext *)
Definition: codec.h:307
AVCodec::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.h:262
cpu.h
PerThreadContext::avpkt
AVPacket * avpkt
Input packet (for decoding) or output (for encoding).
Definition: pthread_frame.c:91
async_unlock
static void async_unlock(FrameThreadContext *fctx)
Definition: pthread_frame.c:164
DEFINE_OFFSET_ARRAY
#define DEFINE_OFFSET_ARRAY(type, name, mutexes, conds)
Definition: pthread_frame.c:684
init_thread
static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, FrameThreadContext *fctx, AVCodecContext *avctx, AVCodecContext *src, const AVCodec *codec, int first)
Definition: pthread_frame.c:806
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:989
FrameThreadContext::async_cond
pthread_cond_t async_cond
Definition: pthread_frame.c:138
PerThreadContext::num_released_buffers
int num_released_buffers
Definition: pthread_frame.c:105
STATE_INPUT_READY
@ STATE_INPUT_READY
Set when the thread is awaiting a packet.
Definition: pthread_frame.c:50
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:364
SENTINEL
#define SENTINEL
Definition: pthread_frame.c:682
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array through a pointer to a pointer.
Definition: mem.c:213
PerThreadContext::parent
struct FrameThreadContext * parent
Definition: pthread_frame.c:77
STATE_GET_FORMAT
@ STATE_GET_FORMAT
Set when the codec calls get_format().
Definition: pthread_frame.c:62
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:59
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:67
AVCodecContext::skip_loop_filter
enum AVDiscard skip_loop_filter
Skip loop filtering for selected frames.
Definition: avcodec.h:1648
pthread_t
Definition: os2threads.h:44
pthread_cond_destroy
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition: os2threads.h:144
UNINITIALIZED
@ UNINITIALIZED
Thread has not been created, AVCodec->close mustn't be called.
Definition: pthread_frame.c:68
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1440
AVCodecContext::channels
int channels
number of audio channels
Definition: avcodec.h:982
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1407
avcodec_default_get_buffer2
int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags)
The default callback for AVCodecContext.get_buffer2().
Definition: decode.c:1447
PerThreadContext::thread_init
int thread_init
Definition: pthread_frame.c:80
i
int i
Definition: input.c:407
log.h
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: internal.h:49
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:1904
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:383
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Definition: hwconfig.h:26
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:460
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:436
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:244
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1386
AVCodecContext::chroma_sample_location
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:963
pthread_cond_t
Definition: os2threads.h:58
AVCodecContext::height
int height
Definition: avcodec.h:557
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:594
AVCodec::priv_data_size
int priv_data_size
Definition: codec.h:245
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:1846
avcodec.h
PTHREAD_INIT_LOOP
#define PTHREAD_INIT_LOOP(type)
ret
ret
Definition: filter_design.txt:187
AVCodec::caps_internal
int caps_internal
Internal codec capabilities.
Definition: codec.h:330
ff_frame_thread_init
int ff_frame_thread_init(AVCodecContext *avctx)
Definition: pthread_frame.c:882
PerThreadContext::async_serializing
int async_serializing
Definition: pthread_frame.c:118
AVCodecContext::opaque
void * opaque
Private data of the user, can be used to carry app specific stuff.
Definition: avcodec.h:426
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:619
thread_get_buffer_internal
static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)
Definition: pthread_frame.c:991
AVCodecContext
main external API structure.
Definition: avcodec.h:384
AVCodecContext::active_thread_type
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1448
PerThreadContext::hwaccel_serializing
int hwaccel_serializing
Definition: pthread_frame.c:117
ThreadFrame
Definition: thread.h:34
av_buffer_replace
int av_buffer_replace(AVBufferRef **pdst, AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition: buffer.c:219
PerThreadContext::frame
AVFrame * frame
Output frame (for decoding) or input (for encoding).
Definition: pthread_frame.c:93
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1514
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:1061
PerThreadContext::result_format
enum AVPixelFormat result_format
get_format() result
Definition: pthread_frame.c:112
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:1971
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:77
av_buffer_ref
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
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:1291
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:83
ff_thread_get_buffer
FF_ENABLE_DEPRECATION_WARNINGS int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1089
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:572
AVCodecContext::codec_type
enum AVMediaType codec_type
Definition: avcodec.h:392
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:144
mem.h
FF_CODEC_CAP_ALLOCATE_PROGRESS
#define FF_CODEC_CAP_ALLOCATE_PROGRESS
Definition: internal.h:76
AVCodecContext::frame_number
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:1012
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:1770
AVPacket
This structure stores compressed data.
Definition: packet.h:342
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:1341
AVCodec::init
int(* init)(struct AVCodecContext *)
Definition: codec.h:278
AVCodecInternal::thread_ctx
void * thread_ctx
Definition: internal.h:146
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:557
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:86
AVCodec::decode
int(* decode)(struct AVCodecContext *avctx, void *outdata, int *got_frame_ptr, struct AVPacket *avpkt)
Decode picture or subtitle data.
Definition: codec.h:305
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
PerThreadContext::requested_frame
AVFrame * requested_frame
AVFrame the codec passed to get_buffer()
Definition: pthread_frame.c:108
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1706
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1125
cond
int(* cond)(enum AVPixelFormat pix_fmt)
Definition: pixdesc_query.c:28
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:742
NEEDS_CLOSE
@ NEEDS_CLOSE
AVCodec->close needs to be called.
Definition: pthread_frame.c:69
mutex
static AVMutex mutex
Definition: log.c:44
PerThreadContext::released_buffers_allocated
int released_buffers_allocated
Definition: pthread_frame.c:106
PerThreadContext::progress_cond
pthread_cond_t progress_cond
Used by child threads to wait for progress to change.
Definition: pthread_frame.c:83
FrameThreadContext::threads
PerThreadContext * threads
The contexts for each thread.
Definition: pthread_frame.c:127
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:263
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:63