FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 <stdatomic.h>
26 
27 #include "avcodec.h"
28 #include "avcodec_internal.h"
29 #include "codec_desc.h"
30 #include "codec_internal.h"
31 #include "decode.h"
32 #include "hwaccel_internal.h"
33 #include "hwconfig.h"
34 #include "internal.h"
35 #include "packet_internal.h"
36 #include "pthread_internal.h"
37 #include "libavutil/refstruct.h"
38 #include "thread.h"
39 #include "threadframe.h"
40 #include "version_major.h"
41 
42 #include "libavutil/avassert.h"
43 #include "libavutil/buffer.h"
44 #include "libavutil/common.h"
45 #include "libavutil/cpu.h"
46 #include "libavutil/frame.h"
47 #include "libavutil/internal.h"
48 #include "libavutil/log.h"
49 #include "libavutil/mem.h"
50 #include "libavutil/opt.h"
51 #include "libavutil/thread.h"
52 
53 enum {
54  /// Set when the thread is awaiting a packet.
56  /// Set before the codec has called ff_thread_finish_setup().
58  /// Set after the codec has called ff_thread_finish_setup().
60 };
61 
62 enum {
63  UNINITIALIZED, ///< Thread has not been created, AVCodec->close mustn't be called
64  NEEDS_CLOSE, ///< FFCodec->close needs to be called
65  INITIALIZED, ///< Thread has been properly set up
66 };
67 
68 typedef struct DecodedFrames {
70  size_t nb_f;
73 
74 typedef struct ThreadFrameProgress {
77 
78 /**
79  * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
80  */
81 typedef struct PerThreadContext {
83 
86  unsigned pthread_init_cnt;///< Number of successfully initialized mutexes/conditions
87  pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread.
88  pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change.
89  pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish.
90 
91  pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext.
92  pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
93 
94  AVCodecContext *avctx; ///< Context used to decode packets passed to this thread.
95 
96  AVPacket *avpkt; ///< Input packet (for decoding) or output (for encoding).
97 
98  /**
99  * Decoded frames from a single decode iteration.
100  */
102  int result; ///< The result of the last codec decode/encode() call.
103 
105 
106  int die; ///< Set when the thread should exit.
107 
110 
111  // set to 1 in ff_thread_finish_setup() when a threadsafe hwaccel is used;
112  // cannot check hwaccel caps directly, because
113  // worked threads clear hwaccel state for thread-unsafe hwaccels
114  // after each decode call
116 
117  atomic_int debug_threads; ///< Set if the FF_DEBUG_THREADS option is set.
118 
119  /// The following two fields have the same semantics as the DecodeContext field
123 
124 /**
125  * Context stored in the client AVCodecInternal thread_ctx.
126  */
127 typedef struct FrameThreadContext {
128  PerThreadContext *threads; ///< The contexts for each thread.
129  PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
130 
131  unsigned pthread_init_cnt; ///< Number of successfully initialized mutexes/conditions
132  pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
133  /**
134  * This lock is used for ensuring threads run in serial when thread-unsafe
135  * hwaccel is used.
136  */
141 
143  int result;
144 
145  /**
146  * Packet to be submitted to the next thread for decoding.
147  */
149 
150  int next_decoding; ///< The next context to submit a packet to.
151  int next_finished; ///< The next context to return output from.
152 
153  /* hwaccel state for thread-unsafe hwaccels is temporarily stored here in
154  * order to transfer its ownership to the next decoding thread without the
155  * need for extra synchronization */
160 
161 static int hwaccel_serial(const AVCodecContext *avctx)
162 {
163  return avctx->hwaccel && !(ffhwaccel(avctx->hwaccel)->caps_internal & HWACCEL_CAP_THREAD_SAFE);
164 }
165 
166 static void async_lock(FrameThreadContext *fctx)
167 {
169  while (fctx->async_lock)
170  pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex);
171  fctx->async_lock = 1;
173 }
174 
176 {
178  av_assert0(fctx->async_lock);
179  fctx->async_lock = 0;
182 }
183 
185 {
186  AVCodecContext *avctx = p->avctx;
187  int idx = p - p->parent->threads;
188  char name[16];
189 
190  snprintf(name, sizeof(name), "av:%.7s:df%d", avctx->codec->name, idx);
191 
193 }
194 
195 // get a free frame to decode into
197 {
198  if (df->nb_f == df->nb_f_allocated) {
199  AVFrame **tmp = av_realloc_array(df->f, df->nb_f + 1,
200  sizeof(*df->f));
201  if (!tmp)
202  return NULL;
203  df->f = tmp;
204 
205  df->f[df->nb_f] = av_frame_alloc();
206  if (!df->f[df->nb_f])
207  return NULL;
208 
209  df->nb_f_allocated++;
210  }
211 
212  av_assert0(!df->f[df->nb_f]->buf[0]);
213 
214  return df->f[df->nb_f];
215 }
216 
218 {
219  AVFrame *tmp_frame = df->f[0];
220  av_frame_move_ref(dst, tmp_frame);
221  memmove(df->f, df->f + 1, (df->nb_f - 1) * sizeof(*df->f));
222  df->f[--df->nb_f] = tmp_frame;
223 }
224 
226 {
227  for (size_t i = 0; i < df->nb_f; i++)
228  av_frame_unref(df->f[i]);
229  df->nb_f = 0;
230 }
231 
233 {
234  for (size_t i = 0; i < df->nb_f_allocated; i++)
235  av_frame_free(&df->f[i]);
236  av_freep(&df->f);
237  df->nb_f = 0;
238  df->nb_f_allocated = 0;
239 }
240 
241 /**
242  * Codec worker thread.
243  *
244  * Automatically calls ff_thread_finish_setup() if the codec does
245  * not provide an update_thread_context method, or if the codec returns
246  * before calling it.
247  */
249 {
250  PerThreadContext *p = arg;
251  AVCodecContext *avctx = p->avctx;
252  const FFCodec *codec = ffcodec(avctx->codec);
253 
254  thread_set_name(p);
255 
257  while (1) {
258  int ret;
259 
260  while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die)
262 
263  if (p->die) break;
264 
265  if (!codec->update_thread_context)
266  ff_thread_finish_setup(avctx);
267 
268  /* If a decoder supports hwaccel, then it must call ff_get_format().
269  * Since that call must happen before ff_thread_finish_setup(), the
270  * decoder is required to implement update_thread_context() and call
271  * ff_thread_finish_setup() manually. Therefore the above
272  * ff_thread_finish_setup() call did not happen and hwaccel_serializing
273  * cannot be true here. */
275 
276  /* if the previous thread uses thread-unsafe hwaccel then we take the
277  * lock to ensure the threads don't run concurrently */
278  if (hwaccel_serial(avctx)) {
280  p->hwaccel_serializing = 1;
281  }
282 
283  ret = 0;
284  while (ret >= 0) {
285  AVFrame *frame;
286 
287  /* get the frame which will store the output */
289  if (!frame) {
290  p->result = AVERROR(ENOMEM);
291  goto alloc_fail;
292  }
293 
294  /* do the actual decoding */
296  if (ret == 0)
297  p->df.nb_f++;
298  else if (ret < 0 && frame->buf[0])
300 
301  p->result = (ret == AVERROR(EAGAIN)) ? 0 : ret;
302  }
303 
304  if (atomic_load(&p->state) == STATE_SETTING_UP)
305  ff_thread_finish_setup(avctx);
306 
307 alloc_fail:
308  if (p->hwaccel_serializing) {
309  /* wipe hwaccel state for thread-unsafe hwaccels to avoid stale
310  * pointers lying around;
311  * the state was transferred to FrameThreadContext in
312  * ff_thread_finish_setup(), so nothing is leaked */
313  avctx->hwaccel = NULL;
314  avctx->hwaccel_context = NULL;
315  avctx->internal->hwaccel_priv_data = NULL;
316 
317  p->hwaccel_serializing = 0;
319  }
320  av_assert0(!avctx->hwaccel ||
322 
323  if (p->async_serializing) {
324  p->async_serializing = 0;
325 
326  async_unlock(p->parent);
327  }
328 
330 
332 
336  }
338 
339  return NULL;
340 }
341 
342 /**
343  * Update the next thread's AVCodecContext with values from the reference thread's context.
344  *
345  * @param dst The destination context.
346  * @param src The source context.
347  * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
348  * @return 0 on success, negative error code on failure
349  */
351 {
352  const FFCodec *const codec = ffcodec(dst->codec);
353  int err = 0;
354 
355  if (dst != src && (for_user || codec->update_thread_context)) {
356  dst->time_base = src->time_base;
357  dst->framerate = src->framerate;
358  dst->width = src->width;
359  dst->height = src->height;
360  dst->pix_fmt = src->pix_fmt;
361  dst->sw_pix_fmt = src->sw_pix_fmt;
362 
363  dst->coded_width = src->coded_width;
364  dst->coded_height = src->coded_height;
365 
366  dst->has_b_frames = src->has_b_frames;
367  dst->idct_algo = src->idct_algo;
368 #if FF_API_CODEC_PROPS
370  dst->properties = src->properties;
372 #endif
373 
374  dst->bits_per_coded_sample = src->bits_per_coded_sample;
375  dst->sample_aspect_ratio = src->sample_aspect_ratio;
376 
377  dst->profile = src->profile;
378  dst->level = src->level;
379 
380  dst->bits_per_raw_sample = src->bits_per_raw_sample;
381  dst->color_primaries = src->color_primaries;
382 
383  dst->color_trc = src->color_trc;
384  dst->colorspace = src->colorspace;
385  dst->color_range = src->color_range;
386  dst->chroma_sample_location = src->chroma_sample_location;
387 
388  dst->sample_rate = src->sample_rate;
389  dst->sample_fmt = src->sample_fmt;
390  err = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
391  if (err < 0)
392  return err;
393 
394  if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
395  (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
396  av_buffer_unref(&dst->hw_frames_ctx);
397 
398  if (src->hw_frames_ctx) {
399  dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
400  if (!dst->hw_frames_ctx)
401  return AVERROR(ENOMEM);
402  }
403  }
404 
405  dst->hwaccel_flags = src->hwaccel_flags;
406 
407  av_refstruct_replace(&dst->internal->pool, src->internal->pool);
409  }
410 
411  if (for_user) {
413  err = codec->update_thread_context_for_user(dst, src);
414  } else {
415  const PerThreadContext *p_src = src->internal->thread_ctx;
416  PerThreadContext *p_dst = dst->internal->thread_ctx;
417 
418  if (codec->update_thread_context) {
419  err = codec->update_thread_context(dst, src);
420  if (err < 0)
421  return err;
422  }
423 
424  // reset dst hwaccel state if needed
426  (!dst->hwaccel && !dst->internal->hwaccel_priv_data));
427  if (p_dst->hwaccel_threadsafe &&
428  (!p_src->hwaccel_threadsafe || dst->hwaccel != src->hwaccel)) {
430  p_dst->hwaccel_threadsafe = 0;
431  }
432 
433  // propagate hwaccel state for threadsafe hwaccels
434  if (p_src->hwaccel_threadsafe) {
435  const FFHWAccel *hwaccel = ffhwaccel(src->hwaccel);
436  if (!dst->hwaccel) {
437  if (hwaccel->priv_data_size) {
438  av_assert0(hwaccel->update_thread_context);
439 
440  dst->internal->hwaccel_priv_data =
441  av_mallocz(hwaccel->priv_data_size);
442  if (!dst->internal->hwaccel_priv_data)
443  return AVERROR(ENOMEM);
444  }
445  dst->hwaccel = src->hwaccel;
446  }
447  av_assert0(dst->hwaccel == src->hwaccel);
448 
449  if (hwaccel->update_thread_context) {
450  err = hwaccel->update_thread_context(dst, src);
451  if (err < 0) {
452  av_log(dst, AV_LOG_ERROR, "Error propagating hwaccel state\n");
454  return err;
455  }
456  }
457  p_dst->hwaccel_threadsafe = 1;
458  }
459  }
460 
461  return err;
462 }
463 
464 /**
465  * Update the next thread's AVCodecContext with values set by the user.
466  *
467  * @param dst The destination context.
468  * @param src The source context.
469  * @return 0 on success, negative error code on failure
470  */
472 {
473  int err;
474 
475  dst->flags = src->flags;
476 
477  dst->draw_horiz_band= src->draw_horiz_band;
478  dst->get_buffer2 = src->get_buffer2;
479 
480  dst->opaque = src->opaque;
481  dst->debug = src->debug;
482 
483  dst->slice_flags = src->slice_flags;
484  dst->flags2 = src->flags2;
485  dst->export_side_data = src->export_side_data;
486 
487  dst->skip_loop_filter = src->skip_loop_filter;
488  dst->skip_idct = src->skip_idct;
489  dst->skip_frame = src->skip_frame;
490 
491  dst->frame_num = src->frame_num;
492 
493  av_packet_unref(dst->internal->last_pkt_props);
494  err = av_packet_copy_props(dst->internal->last_pkt_props, src->internal->last_pkt_props);
495  if (err < 0)
496  return err;
497 
498  return 0;
499 }
500 
501 static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx,
502  AVPacket *in_pkt)
503 {
504  FrameThreadContext *fctx = p->parent;
505  PerThreadContext *prev_thread = fctx->prev_thread;
506  const AVCodec *codec = p->avctx->codec;
507  int ret;
508 
510 
512  av_packet_move_ref(p->avpkt, in_pkt);
513 
514  if (AVPACKET_IS_EMPTY(p->avpkt))
515  p->avctx->internal->draining = 1;
516 
517  ret = update_context_from_user(p->avctx, user_avctx);
518  if (ret) {
520  return ret;
521  }
523  (p->avctx->debug & FF_DEBUG_THREADS) != 0,
524  memory_order_relaxed);
525 
526  if (prev_thread) {
527  if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) {
528  pthread_mutex_lock(&prev_thread->progress_mutex);
529  while (atomic_load(&prev_thread->state) == STATE_SETTING_UP)
530  pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
531  pthread_mutex_unlock(&prev_thread->progress_mutex);
532  }
533 
534  /* codecs without delay might not be prepared to be called repeatedly here during
535  * flushing (vp3/theora), and also don't need to be, since from this point on, they
536  * will always return EOF anyway */
537  if (!p->avctx->internal->draining ||
538  (codec->capabilities & AV_CODEC_CAP_DELAY)) {
539  ret = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
540  if (ret) {
542  return ret;
543  }
544  }
545  }
546 
547  /* transfer the stashed hwaccel state, if any */
549  if (!p->hwaccel_threadsafe) {
550  FFSWAP(const AVHWAccel*, p->avctx->hwaccel, fctx->stash_hwaccel);
553  }
554 
558 
559  fctx->prev_thread = p;
560  fctx->next_decoding = (fctx->next_decoding + 1) % p->avctx->thread_count;
561 
562  return 0;
563 }
564 
566 {
567  FrameThreadContext *fctx = avctx->internal->thread_ctx;
568  int ret = 0;
569 
570  /* release the async lock, permitting blocked hwaccel threads to
571  * go forward while we are in this function */
572  async_unlock(fctx);
573 
574  /* submit packets to threads while there are no buffered results to return */
575  while (!fctx->df.nb_f && !fctx->result) {
576  PerThreadContext *p;
577 
578  /* get a packet to be submitted to the next thread */
579  av_packet_unref(fctx->next_pkt);
580  ret = ff_decode_get_packet(avctx, fctx->next_pkt);
581  if (ret < 0 && ret != AVERROR_EOF)
582  goto finish;
583 
584  ret = submit_packet(&fctx->threads[fctx->next_decoding], avctx,
585  fctx->next_pkt);
586  if (ret < 0)
587  goto finish;
588 
589  /* do not return any frames until all threads have something to do */
590  if (fctx->next_decoding != fctx->next_finished &&
591  !avctx->internal->draining)
592  continue;
593 
594  p = &fctx->threads[fctx->next_finished];
595  fctx->next_finished = (fctx->next_finished + 1) % avctx->thread_count;
596 
599  while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY)
602  }
603 
604  update_context_from_thread(avctx, p->avctx, 1);
605  fctx->result = p->result;
606  p->result = 0;
607  if (p->df.nb_f)
608  FFSWAP(DecodedFrames, fctx->df, p->df);
609  }
610 
611  /* a thread may return multiple frames AND an error
612  * we first return all the frames, then the error */
613  if (fctx->df.nb_f) {
614  decoded_frames_pop(&fctx->df, frame);
615  ret = 0;
616  } else {
617  ret = fctx->result;
618  fctx->result = 0;
619  }
620 
621 finish:
622  async_lock(fctx);
623  return ret;
624 }
625 
627 {
628  PerThreadContext *p;
629  atomic_int *progress = f->progress ? f->progress->progress : NULL;
630 
631  if (!progress ||
632  atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
633  return;
634 
635  p = f->owner[field]->internal->thread_ctx;
636 
637  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
638  av_log(f->owner[field], AV_LOG_DEBUG,
639  "%p finished %d field %d\n", progress, n, field);
640 
642 
643  atomic_store_explicit(&progress[field], n, memory_order_release);
644 
647 }
648 
649 void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
650 {
651  PerThreadContext *p;
652  atomic_int *progress = f->progress ? f->progress->progress : NULL;
653 
654  if (!progress ||
655  atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
656  return;
657 
658  p = f->owner[field]->internal->thread_ctx;
659 
660  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
661  av_log(f->owner[field], AV_LOG_DEBUG,
662  "thread awaiting %d field %d from %p\n", n, field, progress);
663 
665  while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n)
668 }
669 
671  PerThreadContext *p;
672 
673  if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
674 
675  p = avctx->internal->thread_ctx;
676 
677  p->hwaccel_threadsafe = avctx->hwaccel &&
679 
680  if (hwaccel_serial(avctx) && !p->hwaccel_serializing) {
682  p->hwaccel_serializing = 1;
683  }
684 
685  /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */
686  if (avctx->hwaccel &&
688  p->async_serializing = 1;
689 
690  async_lock(p->parent);
691  }
692 
693  /* thread-unsafe hwaccels share a single private data instance, so we
694  * save hwaccel state for passing to the next thread;
695  * this is done here so that this worker thread can wipe its own hwaccel
696  * state after decoding, without requiring synchronization */
698  if (hwaccel_serial(avctx)) {
699  p->parent->stash_hwaccel = avctx->hwaccel;
702  }
703 
706  av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
707  }
708 
710 
713 }
714 
715 /// Waits for all threads to finish.
716 static av_cold void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
717 {
718  int i;
719 
720  async_unlock(fctx);
721 
722  for (i = 0; i < thread_count; i++) {
723  PerThreadContext *p = &fctx->threads[i];
724 
725  if (atomic_load(&p->state) != STATE_INPUT_READY) {
727  while (atomic_load(&p->state) != STATE_INPUT_READY)
730  }
731  }
732 
733  async_lock(fctx);
734 }
735 
736 #define OFF(member) offsetof(FrameThreadContext, member)
737 DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, pthread_init_cnt,
738  (OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),
739  (OFF(async_cond)));
740 #undef OFF
741 
742 #define OFF(member) offsetof(PerThreadContext, member)
743 DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread, pthread_init_cnt,
744  (OFF(progress_mutex), OFF(mutex)),
745  (OFF(input_cond), OFF(progress_cond), OFF(output_cond)));
746 #undef OFF
747 
748 av_cold void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
749 {
750  FrameThreadContext *fctx = avctx->internal->thread_ctx;
751  const FFCodec *codec = ffcodec(avctx->codec);
752  int i;
753 
754  park_frame_worker_threads(fctx, thread_count);
755 
756  for (i = 0; i < thread_count; i++) {
757  PerThreadContext *p = &fctx->threads[i];
758  AVCodecContext *ctx = p->avctx;
759 
760  if (ctx->internal) {
761  if (p->thread_init == INITIALIZED) {
763  p->die = 1;
766 
767  pthread_join(p->thread, NULL);
768  }
769  if (codec->close && p->thread_init != UNINITIALIZED)
770  codec->close(ctx);
771 
772  /* When using a threadsafe hwaccel, this is where
773  * each thread's context is uninit'd and freed. */
775 
776  if (ctx->priv_data) {
777  if (codec->p.priv_class)
780  }
781 
782  av_refstruct_unref(&ctx->internal->pool);
783  av_packet_free(&ctx->internal->in_pkt);
784  av_packet_free(&ctx->internal->last_pkt_props);
786  av_freep(&ctx->internal);
787  av_buffer_unref(&ctx->hw_frames_ctx);
788  av_frame_side_data_free(&ctx->decoded_side_data,
789  &ctx->nb_decoded_side_data);
790  }
791 
792  decoded_frames_free(&p->df);
793 
794  ff_pthread_free(p, per_thread_offsets);
795  av_packet_free(&p->avpkt);
796 
797  av_freep(&p->avctx);
798  }
799 
800  decoded_frames_free(&fctx->df);
801  av_packet_free(&fctx->next_pkt);
802 
803  av_freep(&fctx->threads);
804  ff_pthread_free(fctx, thread_ctx_offsets);
805 
806  /* if we have stashed hwaccel state, move it to the user-facing context,
807  * so it will be freed in ff_codec_close() */
808  av_assert0(!avctx->hwaccel);
809  FFSWAP(const AVHWAccel*, avctx->hwaccel, fctx->stash_hwaccel);
810  FFSWAP(void*, avctx->hwaccel_context, fctx->stash_hwaccel_context);
811  FFSWAP(void*, avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv);
812 
813  av_freep(&avctx->internal->thread_ctx);
814 }
815 
816 static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
817  FrameThreadContext *fctx, AVCodecContext *avctx,
818  const FFCodec *codec, int first)
819 {
821  int err;
822 
826  if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
828  }
829 
831 
832  copy = av_memdup(avctx, sizeof(*avctx));
833  if (!copy)
834  return AVERROR(ENOMEM);
835  copy->priv_data = NULL;
836  copy->decoded_side_data = NULL;
837  copy->nb_decoded_side_data = 0;
838 
839  /* From now on, this PerThreadContext will be cleaned up by
840  * ff_frame_thread_free in case of errors. */
841  (*threads_to_free)++;
842 
843  p->parent = fctx;
844  p->avctx = copy;
845 
846  copy->internal = ff_decode_internal_alloc();
847  if (!copy->internal)
848  return AVERROR(ENOMEM);
850  copy->internal->thread_ctx = p;
851  copy->internal->progress_frame_pool = avctx->internal->progress_frame_pool;
852 
853  copy->delay = avctx->delay;
854 
855  if (codec->priv_data_size) {
856  copy->priv_data = av_mallocz(codec->priv_data_size);
857  if (!copy->priv_data)
858  return AVERROR(ENOMEM);
859 
860  if (codec->p.priv_class) {
861  *(const AVClass **)copy->priv_data = codec->p.priv_class;
862  err = av_opt_copy(copy->priv_data, avctx->priv_data);
863  if (err < 0)
864  return err;
865  }
866  }
867 
868  err = ff_pthread_init(p, per_thread_offsets);
869  if (err < 0)
870  return err;
871 
872  if (!(p->avpkt = av_packet_alloc()))
873  return AVERROR(ENOMEM);
874 
875  copy->internal->is_frame_mt = 1;
876  if (!first)
877  copy->internal->is_copy = 1;
878 
879  copy->internal->in_pkt = av_packet_alloc();
880  if (!copy->internal->in_pkt)
881  return AVERROR(ENOMEM);
882 
883  copy->internal->last_pkt_props = av_packet_alloc();
884  if (!copy->internal->last_pkt_props)
885  return AVERROR(ENOMEM);
886 
887  if (codec->init) {
888  err = codec->init(copy);
889  if (err < 0) {
892  return err;
893  }
894  }
896 
897  if (first) {
898  update_context_from_thread(avctx, copy, 1);
899 
901  for (int i = 0; i < copy->nb_decoded_side_data; i++) {
903  &avctx->nb_decoded_side_data,
904  copy->decoded_side_data[i], 0);
905  if (err < 0)
906  return err;
907  }
908  }
909 
910  atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
911 
913  if (err < 0)
914  return err;
916 
917  return 0;
918 }
919 
921 {
922  int thread_count = avctx->thread_count;
923  const FFCodec *codec = ffcodec(avctx->codec);
924  FrameThreadContext *fctx;
925  int err, i = 0;
926 
927  if (!thread_count) {
928  int nb_cpus = av_cpu_count();
929  // use number of cores + 1 as thread count if there is more than one
930  if (nb_cpus > 1)
931  thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
932  else
933  thread_count = avctx->thread_count = 1;
934  }
935 
936  if (thread_count <= 1) {
937  avctx->active_thread_type = 0;
938  return 0;
939  }
940 
941  avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
942  if (!fctx)
943  return AVERROR(ENOMEM);
944 
945  err = ff_pthread_init(fctx, thread_ctx_offsets);
946  if (err < 0) {
947  ff_pthread_free(fctx, thread_ctx_offsets);
948  av_freep(&avctx->internal->thread_ctx);
949  return err;
950  }
951 
952  fctx->next_pkt = av_packet_alloc();
953  if (!fctx->next_pkt)
954  return AVERROR(ENOMEM);
955 
956  fctx->async_lock = 1;
957 
958  if (codec->p.type == AVMEDIA_TYPE_VIDEO)
959  avctx->delay = avctx->thread_count - 1;
960 
961  fctx->threads = av_calloc(thread_count, sizeof(*fctx->threads));
962  if (!fctx->threads) {
963  err = AVERROR(ENOMEM);
964  goto error;
965  }
966 
967  for (; i < thread_count; ) {
968  PerThreadContext *p = &fctx->threads[i];
969  int first = !i;
970 
971  err = init_thread(p, &i, fctx, avctx, codec, first);
972  if (err < 0)
973  goto error;
974  }
975 
976  return 0;
977 
978 error:
979  ff_frame_thread_free(avctx, i);
980  return err;
981 }
982 
984 {
985  int i;
986  FrameThreadContext *fctx = avctx->internal->thread_ctx;
987 
988  if (!fctx) return;
989 
991  if (fctx->prev_thread) {
992  if (fctx->prev_thread != &fctx->threads[0])
994  }
995 
996  fctx->next_decoding = fctx->next_finished = 0;
997  fctx->prev_thread = NULL;
998 
999  decoded_frames_flush(&fctx->df);
1000  fctx->result = 0;
1001 
1002  for (i = 0; i < avctx->thread_count; i++) {
1003  PerThreadContext *p = &fctx->threads[i];
1004 
1005  decoded_frames_flush(&p->df);
1006  p->result = 0;
1007 
1009  }
1010 }
1011 
1013 {
1014  if ((avctx->active_thread_type & FF_THREAD_FRAME) &&
1015  ffcodec(avctx->codec)->update_thread_context) {
1016  PerThreadContext *p = avctx->internal->thread_ctx;
1017 
1018  if (atomic_load(&p->state) != STATE_SETTING_UP)
1019  return 0;
1020  }
1021 
1022  return 1;
1023 }
1024 
1026 {
1027  PerThreadContext *p;
1028  int err;
1029 
1030  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
1031  return ff_get_buffer(avctx, f, flags);
1032 
1033  p = avctx->internal->thread_ctx;
1034  if (atomic_load(&p->state) != STATE_SETTING_UP &&
1035  ffcodec(avctx->codec)->update_thread_context) {
1036  av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
1037  return -1;
1038  }
1039 
1041  err = ff_get_buffer(avctx, f, flags);
1042 
1044 
1045  return err;
1046 }
1047 
1049 {
1050  int ret = thread_get_buffer_internal(avctx, f, flags);
1051  if (ret < 0)
1052  av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
1053  return ret;
1054 }
1055 
1057 {
1058  int ret;
1059 
1060  f->owner[0] = f->owner[1] = avctx;
1061  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
1062  return ff_get_buffer(avctx, f->f, flags);
1063 
1064  f->progress = av_refstruct_allocz(sizeof(*f->progress));
1065  if (!f->progress)
1066  return AVERROR(ENOMEM);
1067 
1068  atomic_init(&f->progress->progress[0], -1);
1069  atomic_init(&f->progress->progress[1], -1);
1070 
1071  ret = ff_thread_get_buffer(avctx, f->f, flags);
1072  if (ret)
1073  av_refstruct_unref(&f->progress);
1074  return ret;
1075 }
1076 
1078 {
1079  av_refstruct_unref(&f->progress);
1080  f->owner[0] = f->owner[1] = NULL;
1081  if (f->f)
1082  av_frame_unref(f->f);
1083 }
1084 
1086 {
1087  PerThreadContext *p;
1088  const void *ref;
1089 
1090  if (!avctx->internal->is_copy)
1091  return avctx->active_thread_type & FF_THREAD_FRAME ?
1093 
1094  p = avctx->internal->thread_ctx;
1095 
1096  av_assert1(memcpy(&ref, (char*)avctx->priv_data + offset, sizeof(ref)) && ref == NULL);
1097 
1098  memcpy(&ref, (const char*)p->parent->threads[0].avctx->priv_data + offset, sizeof(ref));
1099  av_assert1(ref);
1100  av_refstruct_replace((char*)avctx->priv_data + offset, ref);
1101 
1102  return FF_THREAD_IS_COPY;
1103 }
1104 
1106 {
1107  PerThreadContext *p = avctx->internal->thread_ctx;
1108 
1109  if (!AVPACKET_IS_EMPTY(p->avpkt)) {
1111  return 0;
1112  }
1113 
1114  return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN);
1115 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
flags
const SwsFlags flags[]
Definition: swscale.c:61
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
hwconfig.h
FFCodec::update_thread_context
int(* update_thread_context)(struct AVCodecContext *dst, const struct AVCodecContext *src)
Copy necessary context variables from a previous thread context to the current one.
Definition: codec_internal.h:168
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:430
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1408
AVCodec
AVCodec.
Definition: codec.h:172
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
thread_set_name
static void thread_set_name(PerThreadContext *p)
Definition: pthread_frame.c:184
AVCodecContext::hwaccel_context
void * hwaccel_context
Legacy hardware accelerator context.
Definition: avcodec.h:1432
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:215
ff_decode_get_packet
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition: decode.c:244
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
PerThreadContext::input_cond
pthread_cond_t input_cond
Used to wait for a new packet from the main thread.
Definition: pthread_frame.c:87
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
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
INITIALIZED
@ INITIALIZED
Thread has been properly set up.
Definition: pthread_frame.c:65
PerThreadContext::initial_pict_type
enum AVPictureType initial_pict_type
Definition: pthread_frame.c:121
hwaccel_serial
static int hwaccel_serial(const AVCodecContext *avctx)
Definition: pthread_frame.c:161
AVCodecContext::decoded_side_data
AVFrameSideData ** decoded_side_data
Array containing static side data, such as HDR10 CLL / MDCV structures.
Definition: avcodec.h:1930
PerThreadContext::debug_threads
atomic_int debug_threads
Set if the FF_DEBUG_THREADS option is set.
Definition: pthread_frame.c:117
df
#define df(A, B)
Definition: vf_xbr.c:91
AVCodec::priv_class
const AVClass * priv_class
AVClass for the private context.
Definition: codec.h:206
FrameThreadContext::next_decoding
int next_decoding
The next context to submit a packet to.
Definition: pthread_frame.c:150
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
ThreadFrameProgress
Definition: pthread_frame.c:74
init_thread
static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, FrameThreadContext *fctx, AVCodecContext *avctx, const FFCodec *codec, int first)
Definition: pthread_frame.c:816
ff_thread_can_start_frame
int ff_thread_can_start_frame(AVCodecContext *avctx)
Definition: pthread_frame.c:1012
decoded_frames_free
static void decoded_frames_free(DecodedFrames *df)
Definition: pthread_frame.c:232
AVPictureType
AVPictureType
Definition: avutil.h:277
AVCodecContext::codec_descriptor
const struct AVCodecDescriptor * codec_descriptor
AVCodecDescriptor.
Definition: avcodec.h:1707
MAX_AUTO_THREADS
#define MAX_AUTO_THREADS
Definition: pthread_internal.h:26
PerThreadContext::state
atomic_int state
Definition: pthread_frame.c:104
FF_THREAD_IS_FIRST_THREAD
@ FF_THREAD_IS_FIRST_THREAD
Definition: thread.h:62
FrameThreadContext
Context stored in the client AVCodecInternal thread_ctx.
Definition: pthread_frame.c:127
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
AVCodec::capabilities
int capabilities
Codec capabilities.
Definition: codec.h:191
internal.h
pthread_mutex_lock
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition: os2threads.h:119
ff_thread_sync_ref
av_cold enum ThreadingStatus ff_thread_sync_ref(AVCodecContext *avctx, size_t offset)
Allows to synchronize objects whose lifetime is the whole decoding process among all frame threads.
Definition: pthread_frame.c:1085
version_major.h
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
FFCodec
Definition: codec_internal.h:127
FrameThreadContext::next_pkt
AVPacket * next_pkt
Packet to be submitted to the next thread for decoding.
Definition: pthread_frame.c:148
DecodedFrames::nb_f
size_t nb_f
Definition: pthread_frame.c:70
ff_thread_receive_frame
int ff_thread_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Submit available packets for decoding to worker threads, return a decoded frame if available.
Definition: pthread_frame.c:565
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
av_frame_side_data_clone
int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, const AVFrameSideData *src, unsigned int flags)
Add a new side data entry to an array based on existing side data, taking a reference towards the con...
Definition: side_data.c:246
STATE_SETTING_UP
@ STATE_SETTING_UP
Set before the codec has called ff_thread_finish_setup().
Definition: pthread_frame.c:57
FrameThreadContext::stash_hwaccel_context
void * stash_hwaccel_context
Definition: pthread_frame.c:157
AVCodecContext::delay
int delay
Codec delay.
Definition: avcodec.h:578
PerThreadContext::die
int die
Set when the thread should exit.
Definition: pthread_frame.c:106
thread.h
ff_pthread_free
av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
Definition: pthread.c:92
FrameThreadContext::next_finished
int next_finished
The next context to return output from.
Definition: pthread_frame.c:151
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:75
FrameThreadContext::buffer_mutex
pthread_mutex_t buffer_mutex
Mutex used to protect get/release_buffer().
Definition: pthread_frame.c:132
STATE_INPUT_READY
@ STATE_INPUT_READY
Set when the thread is awaiting a packet.
Definition: pthread_frame.c:55
ff_hwaccel_uninit
void ff_hwaccel_uninit(AVCodecContext *avctx)
Definition: decode.c:1188
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
FFCodec::priv_data_size
int priv_data_size
Definition: codec_internal.h:156
AVCodecInternal::is_copy
int is_copy
When using frame-threaded decoding, this field is set for the first worker thread (e....
Definition: internal.h:54
AVHWAccel
Definition: avcodec.h:1942
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
finish
static void finish(void)
Definition: movenc.c:374
FFHWAccel
Definition: hwaccel_internal.h:34
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:440
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1564
update_context_from_user
static int update_context_from_user(AVCodecContext *dst, const AVCodecContext *src)
Update the next thread's AVCodecContext with values set by the user.
Definition: pthread_frame.c:471
FrameThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:131
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1949
HWACCEL_CAP_THREAD_SAFE
#define HWACCEL_CAP_THREAD_SAFE
Definition: hwaccel_internal.h:32
PerThreadContext
Context used by codec threads and stored in their AVCodecInternal thread_ctx.
Definition: pthread_frame.c:81
refstruct.h
av_refstruct_allocz
static void * av_refstruct_allocz(size_t size)
Equivalent to av_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:51
park_frame_worker_threads
static av_cold void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
Waits for all threads to finish.
Definition: pthread_frame.c:716
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
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
av_cold
#define av_cold
Definition: attributes.h:90
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:625
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:626
FFCodec::update_thread_context_for_user
int(* update_thread_context_for_user)(struct AVCodecContext *dst, const struct AVCodecContext *src)
Copy variables back to the user-facing context.
Definition: codec_internal.h:173
FrameThreadContext::async_lock
int async_lock
Definition: pthread_frame.c:140
STATE_SETUP_FINISHED
@ STATE_SETUP_FINISHED
Set after the codec has called ff_thread_finish_setup().
Definition: pthread_frame.c:59
pthread_mutex_unlock
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition: os2threads.h:126
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVCodecContext::nb_decoded_side_data
int nb_decoded_side_data
Definition: avcodec.h:1931
PerThreadContext::output_cond
pthread_cond_t output_cond
Used by the main thread to wait for frames to finish.
Definition: pthread_frame.c:89
ff_thread_get_buffer
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1048
ff_thread_flush
av_cold void ff_thread_flush(AVCodecContext *avctx)
Wait for decoding threads to finish and reset internal state.
Definition: pthread_frame.c:983
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
decode.h
PerThreadContext::hwaccel_threadsafe
int hwaccel_threadsafe
Definition: pthread_frame.c:115
field
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this field
Definition: writing_filters.txt:78
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
pthread_cond_broadcast
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
Definition: os2threads.h:162
FrameThreadContext::prev_thread
PerThreadContext * prev_thread
The last thread submit_packet() was called on.
Definition: pthread_frame.c:129
FFCodec::init
int(* init)(struct AVCodecContext *)
Definition: codec_internal.h:181
ff_decode_internal_sync
void ff_decode_internal_sync(struct AVCodecContext *dst, const struct AVCodecContext *src)
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
AVCodecDescriptor::props
int props
Codec properties, a combination of AV_CODEC_PROP_* flags.
Definition: codec_desc.h:54
if
if(ret)
Definition: filter_design.txt:179
threadframe.h
AV_CODEC_PROP_INTRA_ONLY
#define AV_CODEC_PROP_INTRA_ONLY
Codec uses only intra compression.
Definition: codec_desc.h:72
AVCodecInternal::progress_frame_pool
struct AVRefStructPool * progress_frame_pool
Definition: internal.h:71
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Definition: hwaccel_internal.h:31
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
NULL
#define NULL
Definition: coverity.c:32
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
hwaccel_internal.h
ff_thread_await_progress
void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
Definition: pthread_frame.c:649
thread_get_buffer_internal
static int thread_get_buffer_internal(AVCodecContext *avctx, AVFrame *f, int flags)
Definition: pthread_frame.c:1025
AVCodec::type
enum AVMediaType type
Definition: codec.h:185
frame_worker_thread
static attribute_align_arg void * frame_worker_thread(void *arg)
Codec worker thread.
Definition: pthread_frame.c:248
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:466
PerThreadContext::progress_mutex
pthread_mutex_t progress_mutex
Mutex used to protect frame progress values and progress_cond.
Definition: pthread_frame.c:92
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
FrameThreadContext::async_mutex
pthread_mutex_t async_mutex
Definition: pthread_frame.c:138
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:670
ff_thread_release_ext_buffer
void ff_thread_release_ext_buffer(ThreadFrame *f)
Unref a ThreadFrame.
Definition: pthread_frame.c:1077
FrameThreadContext::hwaccel_mutex
pthread_mutex_t hwaccel_mutex
This lock is used for ensuring threads run in serial when thread-unsafe hwaccel is used.
Definition: pthread_frame.c:137
PerThreadContext::avctx
AVCodecContext * avctx
Context used to decode packets passed to this thread.
Definition: pthread_frame.c:94
pthread_internal.h
FF_THREAD_IS_COPY
@ FF_THREAD_IS_COPY
Definition: thread.h:61
DecodedFrames
Definition: pthread_frame.c:68
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: packet.c:487
AVPACKET_IS_EMPTY
#define AVPACKET_IS_EMPTY(pkt)
Definition: packet_internal.h:26
atomic_load_explicit
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:96
FF_DEBUG_THREADS
#define FF_DEBUG_THREADS
Definition: avcodec.h:1390
OFF
#define OFF(member)
Definition: pthread_frame.c:742
PerThreadContext::df
DecodedFrames df
Decoded frames from a single decode iteration.
Definition: pthread_frame.c:101
async_lock
static void async_lock(FrameThreadContext *fctx)
Definition: pthread_frame.c:166
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:2151
PerThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:86
PerThreadContext::thread
pthread_t thread
Definition: pthread_frame.c:84
av_cpu_count
int av_cpu_count(void)
Definition: cpu.c:221
attribute_align_arg
#define attribute_align_arg
Definition: internal.h:50
PerThreadContext::result
int result
The result of the last codec decode/encode() call.
Definition: pthread_frame.c:102
FrameThreadContext::stash_hwaccel
const AVHWAccel * stash_hwaccel
Definition: pthread_frame.c:156
ff_frame_thread_free
av_cold void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
Definition: pthread_frame.c:748
f
f
Definition: af_crystalizer.c:122
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1608
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
codec_internal.h
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:130
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
cpu.h
PerThreadContext::intra_only_flag
int intra_only_flag
The following two fields have the same semantics as the DecodeContext field.
Definition: pthread_frame.c:120
PerThreadContext::avpkt
AVPacket * avpkt
Input packet (for decoding) or output (for encoding).
Definition: pthread_frame.c:96
async_unlock
static void async_unlock(FrameThreadContext *fctx)
Definition: pthread_frame.c:175
FrameThreadContext::async_cond
pthread_cond_t async_cond
Definition: pthread_frame.c:139
ffcodec
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
Definition: codec_internal.h:284
decoded_frames_pop
static void decoded_frames_pop(DecodedFrames *df, AVFrame *dst)
Definition: pthread_frame.c:217
AV_PICTURE_TYPE_NONE
@ AV_PICTURE_TYPE_NONE
Undefined.
Definition: avutil.h:278
frame.h
buffer.h
FrameThreadContext::df
DecodedFrames df
Definition: pthread_frame.c:142
PerThreadContext::parent
struct FrameThreadContext * parent
Definition: pthread_frame.c:82
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:64
FF_THREAD_NO_FRAME_THREADING
@ FF_THREAD_NO_FRAME_THREADING
Definition: thread.h:63
ff_thread_get_packet
int ff_thread_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Get a packet for decoding.
Definition: pthread_frame.c:1105
pthread_t
Definition: os2threads.h:44
ff_decode_receive_frame_internal
int ff_decode_receive_frame_internal(struct AVCodecContext *avctx, AVFrame *frame)
Do the actual decoding and obtain a decoded frame from the decoder, if available.
Definition: decode.c:605
decoded_frames_flush
static void decoded_frames_flush(DecodedFrames *df)
Definition: pthread_frame.c:225
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1575
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
FFCodec::caps_internal
unsigned caps_internal
Internal codec capabilities FF_CODEC_CAP_*.
Definition: codec_internal.h:136
av_packet_copy_props
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
Copy only "properties" fields from src to dst.
Definition: packet.c:393
PerThreadContext::thread_init
int thread_init
Definition: pthread_frame.c:85
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_frame_side_data_free
void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
Free all side data entries and their contents, then zeroes out the values which the pointers are poin...
Definition: side_data.c:131
internal.h
common.h
FrameThreadContext::result
int result
Definition: pthread_frame.c:143
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
DecodedFrames::f
AVFrame ** f
Definition: pthread_frame.c:69
atomic_store_explicit
#define atomic_store_explicit(object, desired, order)
Definition: stdatomic.h:90
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_frame_move_ref
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition: frame.c:525
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:498
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:256
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
pthread_cond_t
Definition: os2threads.h:58
ff_thread_get_ext_buffer
int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around ff_get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1056
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
avcodec.h
DEFINE_OFFSET_ARRAY
DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, pthread_init_cnt,(OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),(OFF(async_cond)))
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
avcodec_flush_buffers
void avcodec_flush_buffers(AVCodecContext *avctx)
Reset the internal codec state / flush internal buffers.
Definition: avcodec.c:374
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
ff_decode_internal_alloc
struct AVCodecInternal * ff_decode_internal_alloc(void)
Definition: decode.c:2204
decoded_frames_get_free
static AVFrame * decoded_frames_get_free(DecodedFrames *df)
Definition: pthread_frame.c:196
PerThreadContext::async_serializing
int async_serializing
Definition: pthread_frame.c:109
hwaccel
static const char * hwaccel
Definition: ffplay.c:353
pthread_cond_signal
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:152
AVCodecContext
main external API structure.
Definition: avcodec.h:431
AVCodecContext::active_thread_type
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1583
PerThreadContext::hwaccel_serializing
int hwaccel_serializing
Definition: pthread_frame.c:108
ThreadFrame
Definition: threadframe.h:27
NEEDS_CLOSE
@ NEEDS_CLOSE
FFCodec->close needs to be called.
Definition: pthread_frame.c:64
avcodec_internal.h
av_refstruct_replace
void av_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
Definition: refstruct.c:160
ffhwaccel
static const FFHWAccel * ffhwaccel(const AVHWAccel *codec)
Definition: hwaccel_internal.h:168
submit_packet
static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, AVPacket *in_pkt)
Definition: pthread_frame.c:501
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
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:76
FFCodec::close
int(* close)(struct AVCodecContext *)
Definition: codec_internal.h:243
ff_pthread_init
av_cold int ff_pthread_init(void *obj, const unsigned offsets[])
Initialize/destroy a list of mutexes/conditions contained in a structure.
Definition: pthread.c:105
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:1377
UNINITIALIZED
@ UNINITIALIZED
Thread has not been created, AVCodec->close mustn't be called.
Definition: pthread_frame.c:63
av_channel_layout_copy
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
Definition: channel_layout.c:449
AVCodecInternal::draining
int draining
decoding: AVERROR_EOF has been returned from ff_decode_get_packet(); must not be used by decoders tha...
Definition: internal.h:139
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
AVCodecContext::codec_type
enum AVMediaType codec_type
Definition: avcodec.h:439
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
packet_internal.h
ff_frame_thread_init
av_cold int ff_frame_thread_init(AVCodecContext *avctx)
Definition: pthread_frame.c:920
ThreadingStatus
ThreadingStatus
Definition: thread.h:60
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
AVPacket
This structure stores compressed data.
Definition: packet.h:512
DecodedFrames::nb_f_allocated
size_t nb_f_allocated
Definition: pthread_frame.c:71
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVCodecInternal::thread_ctx
void * thread_ctx
Definition: internal.h:73
PerThreadContext::mutex
pthread_mutex_t mutex
Mutex used to protect the contents of the PerThreadContext.
Definition: pthread_frame.c:91
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_decode_internal_uninit
void ff_decode_internal_uninit(struct AVCodecContext *avctx)
Definition: decode.c:2217
update_context_from_thread
static int update_context_from_thread(AVCodecContext *dst, const AVCodecContext *src, int for_user)
Update the next thread's AVCodecContext with values from the reference thread's context.
Definition: pthread_frame.c:350
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
codec_desc.h
FFHWAccel::caps_internal
int caps_internal
Internal hwaccel capabilities.
Definition: hwaccel_internal.h:119
snprintf
#define snprintf
Definition: snprintf.h:34
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1293
ThreadFrameProgress::progress
atomic_int progress[2]
Definition: pthread_frame.c:75
FrameThreadContext::stash_hwaccel_priv
void * stash_hwaccel_priv
Definition: pthread_frame.c:158
src
#define src
Definition: vp8dsp.c:248
mutex
static AVMutex mutex
Definition: log.c:48
PerThreadContext::progress_cond
pthread_cond_t progress_cond
Used by child threads to wait for progress to change.
Definition: pthread_frame.c:88
FrameThreadContext::threads
PerThreadContext * threads
The contexts for each thread.
Definition: pthread_frame.c:128
ff_thread_setname
static int ff_thread_setname(const char *name)
Definition: thread.h:216