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) {
324 #if FF_API_CODED_FRAME
326  dst->coded_frame = src->coded_frame;
328 #endif
329  } else {
330  if (dst->codec->update_thread_context)
331  err = dst->codec->update_thread_context(dst, src);
332  }
333 
334  return err;
335 }
336 
337 /**
338  * Update the next thread's AVCodecContext with values set by the user.
339  *
340  * @param dst The destination context.
341  * @param src The source context.
342  * @return 0 on success, negative error code on failure
343  */
345 {
346  dst->flags = src->flags;
347 
348  dst->draw_horiz_band= src->draw_horiz_band;
349  dst->get_buffer2 = src->get_buffer2;
350 
351  dst->opaque = src->opaque;
352  dst->debug = src->debug;
353 
354  dst->slice_flags = src->slice_flags;
355  dst->flags2 = src->flags2;
356  dst->export_side_data = src->export_side_data;
357 
358  dst->skip_loop_filter = src->skip_loop_filter;
359  dst->skip_idct = src->skip_idct;
360  dst->skip_frame = src->skip_frame;
361 
362  dst->frame_number = src->frame_number;
363  dst->reordered_opaque = src->reordered_opaque;
364 #if FF_API_THREAD_SAFE_CALLBACKS
366  dst->thread_safe_callbacks = src->thread_safe_callbacks;
368 #endif
369 
370  if (src->slice_count && src->slice_offset) {
371  if (dst->slice_count < src->slice_count) {
372  int err = av_reallocp_array(&dst->slice_offset, src->slice_count,
373  sizeof(*dst->slice_offset));
374  if (err < 0)
375  return err;
376  }
377  memcpy(dst->slice_offset, src->slice_offset,
378  src->slice_count * sizeof(*dst->slice_offset));
379  }
380  dst->slice_count = src->slice_count;
381  return 0;
382 }
383 
384 #if FF_API_THREAD_SAFE_CALLBACKS
385 /// Releases the buffers that this decoding thread was the last user of.
387 {
388  FrameThreadContext *fctx = p->parent;
389 
390  while (p->num_released_buffers > 0) {
391  AVFrame *f;
392 
394 
395  // fix extended data in case the caller screwed it up
399  f->extended_data = f->data;
400  av_frame_unref(f);
401 
403  }
404 }
405 #endif
406 
407 static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx,
408  AVPacket *avpkt)
409 {
410  FrameThreadContext *fctx = p->parent;
411  PerThreadContext *prev_thread = fctx->prev_thread;
412  const AVCodec *codec = p->avctx->codec;
413  int ret;
414 
415  if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY))
416  return 0;
417 
419 
420  ret = update_context_from_user(p->avctx, user_avctx);
421  if (ret) {
423  return ret;
424  }
426  (p->avctx->debug & FF_DEBUG_THREADS) != 0,
427  memory_order_relaxed);
428 
429 #if FF_API_THREAD_SAFE_CALLBACKS
431 #endif
432 
433  if (prev_thread) {
434  int err;
435  if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) {
436  pthread_mutex_lock(&prev_thread->progress_mutex);
437  while (atomic_load(&prev_thread->state) == STATE_SETTING_UP)
438  pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
439  pthread_mutex_unlock(&prev_thread->progress_mutex);
440  }
441 
442  err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
443  if (err) {
445  return err;
446  }
447  }
448 
450  ret = av_packet_ref(p->avpkt, avpkt);
451  if (ret < 0) {
453  av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n");
454  return ret;
455  }
456 
460 
461 #if FF_API_THREAD_SAFE_CALLBACKS
463  /*
464  * If the client doesn't have a thread-safe get_buffer(),
465  * then decoding threads call back to the main thread,
466  * and it calls back to the client here.
467  */
468 
469  if (!p->avctx->thread_safe_callbacks && (
473  int call_done = 1;
475  while (atomic_load(&p->state) == STATE_SETTING_UP)
477 
478  switch (atomic_load_explicit(&p->state, memory_order_acquire)) {
479  case STATE_GET_BUFFER:
481  break;
482  case STATE_GET_FORMAT:
484  break;
485  default:
486  call_done = 0;
487  break;
488  }
489  if (call_done) {
492  }
494  }
495  }
497 #endif
498 
499  fctx->prev_thread = p;
500  fctx->next_decoding++;
501 
502  return 0;
503 }
504 
506  AVFrame *picture, int *got_picture_ptr,
507  AVPacket *avpkt)
508 {
509  FrameThreadContext *fctx = avctx->internal->thread_ctx;
510  int finished = fctx->next_finished;
511  PerThreadContext *p;
512  int err;
513 
514  /* release the async lock, permitting blocked hwaccel threads to
515  * go forward while we are in this function */
516  async_unlock(fctx);
517 
518  /*
519  * Submit a packet to the next decoding thread.
520  */
521 
522  p = &fctx->threads[fctx->next_decoding];
523  err = submit_packet(p, avctx, avpkt);
524  if (err)
525  goto finish;
526 
527  /*
528  * If we're still receiving the initial packets, don't return a frame.
529  */
530 
531  if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
532  fctx->delaying = 0;
533 
534  if (fctx->delaying) {
535  *got_picture_ptr=0;
536  if (avpkt->size) {
537  err = avpkt->size;
538  goto finish;
539  }
540  }
541 
542  /*
543  * Return the next available frame from the oldest thread.
544  * If we're at the end of the stream, then we have to skip threads that
545  * didn't output a frame/error, because we don't want to accidentally signal
546  * EOF (avpkt->size == 0 && *got_picture_ptr == 0 && err >= 0).
547  */
548 
549  do {
550  p = &fctx->threads[finished++];
551 
552  if (atomic_load(&p->state) != STATE_INPUT_READY) {
554  while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY)
557  }
558 
559  av_frame_move_ref(picture, p->frame);
560  *got_picture_ptr = p->got_frame;
561  picture->pkt_dts = p->avpkt->dts;
562  err = p->result;
563 
564  /*
565  * A later call with avkpt->size == 0 may loop over all threads,
566  * including this one, searching for a frame/error to return before being
567  * stopped by the "finished != fctx->next_finished" condition.
568  * Make sure we don't mistakenly return the same frame/error again.
569  */
570  p->got_frame = 0;
571  p->result = 0;
572 
573  if (finished >= avctx->thread_count) finished = 0;
574  } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished);
575 
576  update_context_from_thread(avctx, p->avctx, 1);
577 
578  if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
579 
580  fctx->next_finished = finished;
581 
582  /* return the size of the consumed packet if no error occurred */
583  if (err >= 0)
584  err = avpkt->size;
585 finish:
586  async_lock(fctx);
587  return err;
588 }
589 
591 {
592  PerThreadContext *p;
593  atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
594 
595  if (!progress ||
596  atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
597  return;
598 
599  p = f->owner[field]->internal->thread_ctx;
600 
601  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
602  av_log(f->owner[field], AV_LOG_DEBUG,
603  "%p finished %d field %d\n", progress, n, field);
604 
606 
607  atomic_store_explicit(&progress[field], n, memory_order_release);
608 
611 }
612 
614 {
615  PerThreadContext *p;
616  atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;
617 
618  if (!progress ||
619  atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
620  return;
621 
622  p = f->owner[field]->internal->thread_ctx;
623 
624  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
625  av_log(f->owner[field], AV_LOG_DEBUG,
626  "thread awaiting %d field %d from %p\n", n, field, progress);
627 
629  while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n)
632 }
633 
635  PerThreadContext *p = avctx->internal->thread_ctx;
636 
637  if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
638 
639  if (avctx->hwaccel && !p->hwaccel_serializing) {
641  p->hwaccel_serializing = 1;
642  }
643 
644  /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */
645  if (avctx->hwaccel &&
647  p->async_serializing = 1;
648 
649  async_lock(p->parent);
650  }
651 
654  av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
655  }
656 
658 
661 }
662 
663 /// Waits for all threads to finish.
664 static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
665 {
666  int i;
667 
668  async_unlock(fctx);
669 
670  for (i = 0; i < thread_count; i++) {
671  PerThreadContext *p = &fctx->threads[i];
672 
673  if (atomic_load(&p->state) != STATE_INPUT_READY) {
675  while (atomic_load(&p->state) != STATE_INPUT_READY)
678  }
679  p->got_frame = 0;
680  }
681 
682  async_lock(fctx);
683 }
684 
685 #define SENTINEL 0 // This forbids putting a mutex/condition variable at the front.
686 #define OFFSET_ARRAY(...) __VA_ARGS__, SENTINEL
687 #define DEFINE_OFFSET_ARRAY(type, name, mutexes, conds) \
688 static const unsigned name ## _offsets[] = { offsetof(type, pthread_init_cnt),\
689  OFFSET_ARRAY mutexes, \
690  OFFSET_ARRAY conds }
691 
692 #define OFF(member) offsetof(FrameThreadContext, member)
694  (OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),
695  (OFF(async_cond)));
696 #undef OFF
697 
698 #define OFF(member) offsetof(PerThreadContext, member)
700  (OFF(progress_mutex), OFF(mutex)),
701  (OFF(input_cond), OFF(progress_cond), OFF(output_cond)));
702 #undef OFF
703 
704 static av_cold void free_pthread(void *obj, const unsigned offsets[])
705 {
706  unsigned cnt = *(unsigned*)((char*)obj + offsets[0]);
707  const unsigned *cur_offset = offsets;
708 
709  for (; *(++cur_offset) != SENTINEL && cnt; cnt--)
710  pthread_mutex_destroy((pthread_mutex_t*)((char*)obj + *cur_offset));
711  for (; *(++cur_offset) != SENTINEL && cnt; cnt--)
712  pthread_cond_destroy ((pthread_cond_t *)((char*)obj + *cur_offset));
713 }
714 
715 static av_cold int init_pthread(void *obj, const unsigned offsets[])
716 {
717  const unsigned *cur_offset = offsets;
718  unsigned cnt = 0;
719  int err;
720 
721 #define PTHREAD_INIT_LOOP(type) \
722  for (; *(++cur_offset) != SENTINEL; cnt++) { \
723  pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset); \
724  err = pthread_ ## type ## _init(dst, NULL); \
725  if (err) { \
726  err = AVERROR(err); \
727  goto fail; \
728  } \
729  }
732 
733 fail:
734  *(unsigned*)((char*)obj + offsets[0]) = cnt;
735  return err;
736 }
737 
738 void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
739 {
740  FrameThreadContext *fctx = avctx->internal->thread_ctx;
741  const AVCodec *codec = avctx->codec;
742  int i;
743 
744  park_frame_worker_threads(fctx, thread_count);
745 
746  if (fctx->prev_thread && avctx->internal->hwaccel_priv_data !=
748  if (update_context_from_thread(avctx, fctx->prev_thread->avctx, 1) < 0) {
749  av_log(avctx, AV_LOG_ERROR, "Failed to update user thread.\n");
750  }
751  }
752 
753  if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
754  if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
755  av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
757  fctx->threads->avctx->internal->is_copy = 1;
758  }
759 
760  for (i = 0; i < thread_count; i++) {
761  PerThreadContext *p = &fctx->threads[i];
762  AVCodecContext *ctx = p->avctx;
763 
764  if (ctx->internal) {
765  if (p->thread_init == INITIALIZED) {
767  p->die = 1;
770 
771  pthread_join(p->thread, NULL);
772  }
773  if (codec->close && p->thread_init != UNINITIALIZED)
774  codec->close(ctx);
775 
776 #if FF_API_THREAD_SAFE_CALLBACKS
778  for (int j = 0; j < p->released_buffers_allocated; j++)
781 #endif
782  if (ctx->priv_data) {
783  if (codec->priv_class)
786  }
787 
788  av_freep(&ctx->slice_offset);
789 
790  av_buffer_unref(&ctx->internal->pool);
791  av_freep(&ctx->internal);
792  av_buffer_unref(&ctx->hw_frames_ctx);
793  }
794 
795  av_frame_free(&p->frame);
796 
797  free_pthread(p, per_thread_offsets);
798  av_packet_free(&p->avpkt);
799 
800  av_freep(&p->avctx);
801  }
802 
803  av_freep(&fctx->threads);
804  free_pthread(fctx, thread_ctx_offsets);
805 
806  av_freep(&avctx->internal->thread_ctx);
807 
808  if (avctx->priv_data && avctx->codec && avctx->codec->priv_class)
809  av_opt_free(avctx->priv_data);
810  avctx->codec = NULL;
811 }
812 
813 static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
814  FrameThreadContext *fctx, AVCodecContext *avctx,
815  AVCodecContext *src, const AVCodec *codec, int first)
816 {
818  int err;
819 
821 
822  copy = av_memdup(src, sizeof(*src));
823  if (!copy)
824  return AVERROR(ENOMEM);
825  copy->priv_data = NULL;
826 
827  /* From now on, this PerThreadContext will be cleaned up by
828  * ff_frame_thread_free in case of errors. */
829  (*threads_to_free)++;
830 
831  p->parent = fctx;
832  p->avctx = copy;
833 
834  copy->internal = av_memdup(src->internal, sizeof(*src->internal));
835  if (!copy->internal)
836  return AVERROR(ENOMEM);
837  copy->internal->thread_ctx = p;
838 
839  copy->delay = avctx->delay;
840 
841  if (codec->priv_data_size) {
842  copy->priv_data = av_mallocz(codec->priv_data_size);
843  if (!copy->priv_data)
844  return AVERROR(ENOMEM);
845 
846  if (codec->priv_class) {
847  *(const AVClass **)copy->priv_data = codec->priv_class;
848  err = av_opt_copy(copy->priv_data, src->priv_data);
849  if (err < 0)
850  return err;
851  }
852  }
853 
854  err = init_pthread(p, per_thread_offsets);
855  if (err < 0)
856  return err;
857 
858  if (!(p->frame = av_frame_alloc()) ||
859  !(p->avpkt = av_packet_alloc()))
860  return AVERROR(ENOMEM);
861  copy->internal->last_pkt_props = p->avpkt;
862 
863  if (!first)
864  copy->internal->is_copy = 1;
865 
866  if (codec->init) {
867  err = codec->init(copy);
868  if (err < 0) {
871  return err;
872  }
873  }
875 
876  if (first)
877  update_context_from_thread(avctx, copy, 1);
878 
879  atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
880 
882  if (err < 0)
883  return err;
885 
886  return 0;
887 }
888 
890 {
891  int thread_count = avctx->thread_count;
892  const AVCodec *codec = avctx->codec;
893  AVCodecContext *src = avctx;
894  FrameThreadContext *fctx;
895  int err, i = 0;
896 
897  if (!thread_count) {
898  int nb_cpus = av_cpu_count();
899  // use number of cores + 1 as thread count if there is more than one
900  if (nb_cpus > 1)
901  thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
902  else
903  thread_count = avctx->thread_count = 1;
904  }
905 
906  if (thread_count <= 1) {
907  avctx->active_thread_type = 0;
908  return 0;
909  }
910 
911  avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
912  if (!fctx)
913  return AVERROR(ENOMEM);
914 
915  err = init_pthread(fctx, thread_ctx_offsets);
916  if (err < 0) {
917  free_pthread(fctx, thread_ctx_offsets);
918  av_freep(&avctx->internal->thread_ctx);
919  return err;
920  }
921 
922  fctx->async_lock = 1;
923  fctx->delaying = 1;
924 
925  if (codec->type == AVMEDIA_TYPE_VIDEO)
926  avctx->delay = src->thread_count - 1;
927 
928  fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext));
929  if (!fctx->threads) {
930  err = AVERROR(ENOMEM);
931  goto error;
932  }
933 
934  for (; i < thread_count; ) {
935  PerThreadContext *p = &fctx->threads[i];
936  int first = !i;
937 
938  err = init_thread(p, &i, fctx, avctx, src, codec, first);
939  if (err < 0)
940  goto error;
941  }
942 
943  return 0;
944 
945 error:
946  ff_frame_thread_free(avctx, i);
947  return err;
948 }
949 
951 {
952  int i;
953  FrameThreadContext *fctx = avctx->internal->thread_ctx;
954 
955  if (!fctx) return;
956 
958  if (fctx->prev_thread) {
959  if (fctx->prev_thread != &fctx->threads[0])
961  }
962 
963  fctx->next_decoding = fctx->next_finished = 0;
964  fctx->delaying = 1;
965  fctx->prev_thread = NULL;
966  for (i = 0; i < avctx->thread_count; i++) {
967  PerThreadContext *p = &fctx->threads[i];
968  // Make sure decode flush calls with size=0 won't return old frames
969  p->got_frame = 0;
970  av_frame_unref(p->frame);
971  p->result = 0;
972 
973 #if FF_API_THREAD_SAFE_CALLBACKS
975 #endif
976 
977  if (avctx->codec->flush)
978  avctx->codec->flush(p->avctx);
979  }
980 }
981 
983 {
984  PerThreadContext *p = avctx->internal->thread_ctx;
989  || !THREAD_SAFE_CALLBACKS(avctx)
990 #endif
991  )) {
992  return 0;
993  }
995  return 1;
996 }
997 
999 {
1000  PerThreadContext *p = avctx->internal->thread_ctx;
1001  int err;
1002 
1003  f->owner[0] = f->owner[1] = avctx;
1004 
1005  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
1006  return ff_get_buffer(avctx, f->f, flags);
1007 
1009  if (atomic_load(&p->state) != STATE_SETTING_UP &&
1010  (avctx->codec->update_thread_context
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  atomic_int *progress;
1022  f->progress = av_buffer_alloc(2 * sizeof(*progress));
1023  if (!f->progress) {
1024  return AVERROR(ENOMEM);
1025  }
1026  progress = (atomic_int*)f->progress->data;
1027 
1028  atomic_init(&progress[0], -1);
1029  atomic_init(&progress[1], -1);
1030  }
1031 
1033 #if !FF_API_THREAD_SAFE_CALLBACKS
1034  err = ff_get_buffer(avctx, f->f, flags);
1035 #else
1037  if (THREAD_SAFE_CALLBACKS(avctx)) {
1038  err = ff_get_buffer(avctx, f->f, flags);
1039  } else {
1041  p->requested_frame = f->f;
1042  p->requested_flags = flags;
1043  atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release);
1045 
1046  while (atomic_load(&p->state) != STATE_SETTING_UP)
1048 
1049  err = p->result;
1050 
1052 
1053  }
1054  if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context)
1055  ff_thread_finish_setup(avctx);
1057 #endif
1058  if (err)
1059  av_buffer_unref(&f->progress);
1060 
1062 
1063  return err;
1064 }
1065 
1066 #if FF_API_THREAD_SAFE_CALLBACKS
1069 {
1070  enum AVPixelFormat res;
1071  PerThreadContext *p = avctx->internal->thread_ctx;
1072  if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks ||
1074  return ff_get_format(avctx, fmt);
1075  if (atomic_load(&p->state) != STATE_SETTING_UP) {
1076  av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n");
1077  return -1;
1078  }
1080  p->available_formats = fmt;
1083 
1084  while (atomic_load(&p->state) != STATE_SETTING_UP)
1086 
1087  res = p->result_format;
1088 
1090 
1091  return res;
1092 }
1094 #endif
1095 
1097 {
1098  int ret = thread_get_buffer_internal(avctx, f, flags);
1099  if (ret < 0)
1100  av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
1101  return ret;
1102 }
1103 
1105 {
1106 #if FF_API_THREAD_SAFE_CALLBACKS
1108  PerThreadContext *p = avctx->internal->thread_ctx;
1109  FrameThreadContext *fctx;
1110  AVFrame *dst;
1111  int ret = 0;
1112  int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
1113  THREAD_SAFE_CALLBACKS(avctx);
1115 #endif
1116 
1117  if (!f->f)
1118  return;
1119 
1120  if (avctx->debug & FF_DEBUG_BUFFERS)
1121  av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
1122 
1123  av_buffer_unref(&f->progress);
1124  f->owner[0] = f->owner[1] = NULL;
1125 
1126 #if !FF_API_THREAD_SAFE_CALLBACKS
1127  av_frame_unref(f->f);
1128 #else
1129  // when the frame buffers are not allocated, just reset it to clean state
1130  if (can_direct_free || !f->f->buf[0]) {
1131  av_frame_unref(f->f);
1132  return;
1133  }
1134 
1135  fctx = p->parent;
1137 
1138  if (p->num_released_buffers == p->released_buffers_allocated) {
1139  AVFrame **tmp = av_realloc_array(p->released_buffers, p->released_buffers_allocated + 1,
1140  sizeof(*p->released_buffers));
1141  if (tmp) {
1142  tmp[p->released_buffers_allocated] = av_frame_alloc();
1143  p->released_buffers = tmp;
1144  }
1145 
1146  if (!tmp || !tmp[p->released_buffers_allocated]) {
1147  ret = AVERROR(ENOMEM);
1148  goto fail;
1149  }
1150  p->released_buffers_allocated++;
1151  }
1152 
1153  dst = p->released_buffers[p->num_released_buffers];
1154  av_frame_move_ref(dst, f->f);
1155 
1156  p->num_released_buffers++;
1157 
1158 fail:
1160 
1161  // make sure the frame is clean even if we fail to free it
1162  // this leaks, but it is better than crashing
1163  if (ret < 0) {
1164  av_log(avctx, AV_LOG_ERROR, "Could not queue a frame for freeing, this will leak\n");
1165  memset(f->f->buf, 0, sizeof(f->f->buf));
1166  if (f->f->extended_buf)
1167  memset(f->f->extended_buf, 0, f->f->nb_extended_buf * sizeof(*f->f->extended_buf));
1168  av_frame_unref(f->f);
1169  }
1170 #endif
1171 }
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:634
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1680
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:1692
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:200
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
av_buffer_alloc
AVBufferRef * av_buffer_alloc(buffer_size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:67
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:788
FF_API_THREAD_SAFE_CALLBACKS
#define FF_API_THREAD_SAFE_CALLBACKS
Definition: version.h:157
AVCodecContext::channel_layout
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:1247
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1164
ff_get_format
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition: decode.c:1326
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1196
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:260
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:950
AVHWAccel::caps_internal
int caps_internal
Internal hwaccel capabilities.
Definition: avcodec.h:2587
ff_thread_can_start_frame
int ff_thread_can_start_frame(AVCodecContext *avctx)
Definition: pthread_frame.c:982
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:203
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:664
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
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:1157
AVCodecContext::slice_offset
int * slice_offset
slice offsets in the frame in bytes
Definition: avcodec.h:906
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:190
avcodec_default_get_format
enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
Definition: decode.c:1114
AVCodec::flush
void(* flush)(struct AVCodecContext *)
Flush buffers.
Definition: codec.h:323
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:509
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1699
AVCodecContext::delay
int delay
Codec delay.
Definition: avcodec.h:692
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:704
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:75
AVCodecInternal::pool
AVBufferRef * pool
Definition: internal.h:148
AVCodecContext::slice_count
int slice_count
slice count
Definition: avcodec.h:890
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:285
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:2071
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:738
AVCodecContext::skip_idct
enum AVDiscard skip_idct
Skip IDCT/dequantization for selected frames.
Definition: avcodec.h:1999
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:715
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:545
AVCodecContext::skip_frame
enum AVDiscard skip_frame
Skip decoding for selected frames.
Definition: avcodec.h:2006
fail
#define fail()
Definition: checkasm.h:133
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:1773
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:616
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:724
submit_packet
static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, AVPacket *avpkt)
Definition: pthread_frame.c:407
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
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:1351
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:1150
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
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:613
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:590
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:826
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:198
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:668
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:1747
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
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:344
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:546
arg
const char * arg
Definition: jacosubdec.c:66
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:1171
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:1014
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:571
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:634
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:1812
AVFrame::pkt_dts
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
Definition: frame.h:427
FF_DEBUG_BUFFERS
#define FF_DEBUG_BUFFERS
Definition: avcodec.h:1635
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:641
AVCodecContext::level
int level
level
Definition: avcodec.h:1984
atomic_load_explicit
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:96
FF_DEBUG_THREADS
#define FF_DEBUG_THREADS
Definition: avcodec.h:1636
OFF
#define OFF(member)
Definition: pthread_frame.c:698
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:1104
PerThreadContext::thread
pthread_t thread
Definition: pthread_frame.c:79
av_cpu_count
int av_cpu_count(void)
Definition: cpu.c:275
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:659
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:82
AVCodecContext::flags2
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:623
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1900
AVPacket::size
int size
Definition: packet.h:370
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:505
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:180
AVCodec::close
int(* close)(struct AVCodecContext *)
Definition: codec.h:305
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:687
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:813
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1204
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:368
SENTINEL
#define SENTINEL
Definition: pthread_frame.c:685
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:206
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:64
AVCodecContext::skip_loop_filter
enum AVDiscard skip_loop_filter
Skip loop filtering for selected frames.
Definition: avcodec.h:1992
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:1784
AVCodecContext::channels
int channels
number of audio channels
Definition: avcodec.h:1197
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:1740
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:1695
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:2279
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:386
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:582
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
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:237
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1719
AVCodecContext::chroma_sample_location
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:1178
pthread_cond_t
Definition: os2threads.h:58
AVCodecContext::height
int height
Definition: avcodec.h:709
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
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:2218
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:328
ff_frame_thread_init
int ff_frame_thread_init(AVCodecContext *avctx)
Definition: pthread_frame.c:889
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:578
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:771
thread_get_buffer_internal
static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)
Definition: pthread_frame.c:998
AVCodecContext::coded_frame
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:1764
AVCodecContext
main external API structure.
Definition: avcodec.h:536
AVCodecContext::active_thread_type
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1792
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:1858
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:1068
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:2346
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:1623
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:1096
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:724
AVCodecContext::codec_type
enum AVMediaType codec_type
Definition: avcodec.h:544
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:1227
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:1789
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:563
AVPacket
This structure stores compressed data.
Definition: packet.h:346
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:1673
AVCodec::init
int(* init)(struct AVCodecContext *)
Definition: codec.h:276
AVCodecInternal::thread_ctx
void * thread_ctx
Definition: internal.h:150
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:709
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:303
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:2078
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1260
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:915
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