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 <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.
119 
120 /**
121  * Context stored in the client AVCodecInternal thread_ctx.
122  */
123 typedef struct FrameThreadContext {
124  PerThreadContext *threads; ///< The contexts for each thread.
125  PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
126 
127  unsigned pthread_init_cnt; ///< Number of successfully initialized mutexes/conditions
128  pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
129  /**
130  * This lock is used for ensuring threads run in serial when thread-unsafe
131  * hwaccel is used.
132  */
137 
139  int result;
140 
141  /**
142  * Packet to be submitted to the next thread for decoding.
143  */
145 
146  int next_decoding; ///< The next context to submit a packet to.
147  int next_finished; ///< The next context to return output from.
148 
149  /* hwaccel state for thread-unsafe hwaccels is temporarily stored here in
150  * order to transfer its ownership to the next decoding thread without the
151  * need for extra synchronization */
156 
157 static int hwaccel_serial(const AVCodecContext *avctx)
158 {
159  return avctx->hwaccel && !(ffhwaccel(avctx->hwaccel)->caps_internal & HWACCEL_CAP_THREAD_SAFE);
160 }
161 
162 static void async_lock(FrameThreadContext *fctx)
163 {
165  while (fctx->async_lock)
166  pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex);
167  fctx->async_lock = 1;
169 }
170 
172 {
174  av_assert0(fctx->async_lock);
175  fctx->async_lock = 0;
178 }
179 
181 {
182  AVCodecContext *avctx = p->avctx;
183  int idx = p - p->parent->threads;
184  char name[16];
185 
186  snprintf(name, sizeof(name), "av:%.7s:df%d", avctx->codec->name, idx);
187 
189 }
190 
191 // get a free frame to decode into
193 {
194  if (df->nb_f == df->nb_f_allocated) {
195  AVFrame **tmp = av_realloc_array(df->f, df->nb_f + 1,
196  sizeof(*df->f));
197  if (!tmp)
198  return NULL;
199  df->f = tmp;
200 
201  df->f[df->nb_f] = av_frame_alloc();
202  if (!df->f[df->nb_f])
203  return NULL;
204 
205  df->nb_f_allocated++;
206  }
207 
208  av_assert0(!df->f[df->nb_f]->buf[0]);
209 
210  return df->f[df->nb_f];
211 }
212 
214 {
215  AVFrame *tmp_frame = df->f[0];
216  av_frame_move_ref(dst, tmp_frame);
217  memmove(df->f, df->f + 1, (df->nb_f - 1) * sizeof(*df->f));
218  df->f[--df->nb_f] = tmp_frame;
219 }
220 
222 {
223  for (size_t i = 0; i < df->nb_f; i++)
224  av_frame_unref(df->f[i]);
225  df->nb_f = 0;
226 }
227 
229 {
230  for (size_t i = 0; i < df->nb_f_allocated; i++)
231  av_frame_free(&df->f[i]);
232  av_freep(&df->f);
233  df->nb_f = 0;
234  df->nb_f_allocated = 0;
235 }
236 
237 /**
238  * Codec worker thread.
239  *
240  * Automatically calls ff_thread_finish_setup() if the codec does
241  * not provide an update_thread_context method, or if the codec returns
242  * before calling it.
243  */
245 {
247  AVCodecContext *avctx = p->avctx;
248  const FFCodec *codec = ffcodec(avctx->codec);
249 
251 
252  pthread_mutex_lock(&p->mutex);
253  while (1) {
254  int ret;
255 
256  while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die)
257  pthread_cond_wait(&p->input_cond, &p->mutex);
258 
259  if (p->die) break;
260 
261  if (!codec->update_thread_context)
262  ff_thread_finish_setup(avctx);
263 
264  /* If a decoder supports hwaccel, then it must call ff_get_format().
265  * Since that call must happen before ff_thread_finish_setup(), the
266  * decoder is required to implement update_thread_context() and call
267  * ff_thread_finish_setup() manually. Therefore the above
268  * ff_thread_finish_setup() call did not happen and hwaccel_serializing
269  * cannot be true here. */
270  av_assert0(!p->hwaccel_serializing);
271 
272  /* if the previous thread uses thread-unsafe hwaccel then we take the
273  * lock to ensure the threads don't run concurrently */
274  if (hwaccel_serial(avctx)) {
275  pthread_mutex_lock(&p->parent->hwaccel_mutex);
276  p->hwaccel_serializing = 1;
277  }
278 
279  ret = 0;
280  while (ret >= 0) {
281  AVFrame *frame;
282 
283  /* get the frame which will store the output */
285  if (!frame) {
286  p->result = AVERROR(ENOMEM);
287  goto alloc_fail;
288  }
289 
290  /* do the actual decoding */
292  if (ret == 0)
293  p->df.nb_f++;
294  else if (ret < 0 && frame->buf[0])
296 
297  p->result = (ret == AVERROR(EAGAIN)) ? 0 : ret;
298  }
299 
300  if (atomic_load(&p->state) == STATE_SETTING_UP)
301  ff_thread_finish_setup(avctx);
302 
303 alloc_fail:
304  if (p->hwaccel_serializing) {
305  /* wipe hwaccel state for thread-unsafe hwaccels to avoid stale
306  * pointers lying around;
307  * the state was transferred to FrameThreadContext in
308  * ff_thread_finish_setup(), so nothing is leaked */
309  avctx->hwaccel = NULL;
310  avctx->hwaccel_context = NULL;
311  avctx->internal->hwaccel_priv_data = NULL;
312 
313  p->hwaccel_serializing = 0;
314  pthread_mutex_unlock(&p->parent->hwaccel_mutex);
315  }
316  av_assert0(!avctx->hwaccel ||
318 
319  if (p->async_serializing) {
320  p->async_serializing = 0;
321 
322  async_unlock(p->parent);
323  }
324 
325  pthread_mutex_lock(&p->progress_mutex);
326 
327  atomic_store(&p->state, STATE_INPUT_READY);
328 
329  pthread_cond_broadcast(&p->progress_cond);
330  pthread_cond_signal(&p->output_cond);
331  pthread_mutex_unlock(&p->progress_mutex);
332  }
333  pthread_mutex_unlock(&p->mutex);
334 
335  return NULL;
336 }
337 
338 /**
339  * Update the next thread's AVCodecContext with values from the reference thread's context.
340  *
341  * @param dst The destination context.
342  * @param src The source context.
343  * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
344  * @return 0 on success, negative error code on failure
345  */
347 {
348  const FFCodec *const codec = ffcodec(dst->codec);
349  int err = 0;
350 
351  if (dst != src && (for_user || codec->update_thread_context)) {
352  dst->time_base = src->time_base;
353  dst->framerate = src->framerate;
354  dst->width = src->width;
355  dst->height = src->height;
356  dst->pix_fmt = src->pix_fmt;
357  dst->sw_pix_fmt = src->sw_pix_fmt;
358 
359  dst->coded_width = src->coded_width;
360  dst->coded_height = src->coded_height;
361 
362  dst->has_b_frames = src->has_b_frames;
363  dst->idct_algo = src->idct_algo;
364 #if FF_API_CODEC_PROPS
366  dst->properties = src->properties;
368 #endif
369 
370  dst->bits_per_coded_sample = src->bits_per_coded_sample;
371  dst->sample_aspect_ratio = src->sample_aspect_ratio;
372 
373  dst->profile = src->profile;
374  dst->level = src->level;
375 
376  dst->bits_per_raw_sample = src->bits_per_raw_sample;
377  dst->color_primaries = src->color_primaries;
378 
379  dst->alpha_mode = src->alpha_mode;
380 
381  dst->color_trc = src->color_trc;
382  dst->colorspace = src->colorspace;
383  dst->color_range = src->color_range;
384  dst->chroma_sample_location = src->chroma_sample_location;
385 
386  dst->sample_rate = src->sample_rate;
387  dst->sample_fmt = src->sample_fmt;
388  err = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
389  if (err < 0)
390  return err;
391 
392  if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
393  (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
394  av_buffer_unref(&dst->hw_frames_ctx);
395 
396  if (src->hw_frames_ctx) {
397  dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
398  if (!dst->hw_frames_ctx)
399  return AVERROR(ENOMEM);
400  }
401  }
402 
403  dst->hwaccel_flags = src->hwaccel_flags;
404 
405  av_refstruct_replace(&dst->internal->pool, src->internal->pool);
407  }
408 
409  if (for_user) {
411  err = codec->update_thread_context_for_user(dst, src);
412  } else {
413  const PerThreadContext *p_src = src->internal->thread_ctx;
414  PerThreadContext *p_dst = dst->internal->thread_ctx;
415 
416  if (codec->update_thread_context) {
417  err = codec->update_thread_context(dst, src);
418  if (err < 0)
419  return err;
420  }
421 
422  // reset dst hwaccel state if needed
424  (!dst->hwaccel && !dst->internal->hwaccel_priv_data));
425  if (p_dst->hwaccel_threadsafe &&
426  (!p_src->hwaccel_threadsafe || dst->hwaccel != src->hwaccel)) {
428  p_dst->hwaccel_threadsafe = 0;
429  }
430 
431  // propagate hwaccel state for threadsafe hwaccels
432  if (p_src->hwaccel_threadsafe) {
433  const FFHWAccel *hwaccel = ffhwaccel(src->hwaccel);
434  if (!dst->hwaccel) {
435  if (hwaccel->priv_data_size) {
436  av_assert0(hwaccel->update_thread_context);
437 
438  dst->internal->hwaccel_priv_data =
439  av_mallocz(hwaccel->priv_data_size);
440  if (!dst->internal->hwaccel_priv_data)
441  return AVERROR(ENOMEM);
442  }
443  dst->hwaccel = src->hwaccel;
444  }
445  av_assert0(dst->hwaccel == src->hwaccel);
446 
447  if (hwaccel->update_thread_context) {
448  err = hwaccel->update_thread_context(dst, src);
449  if (err < 0) {
450  av_log(dst, AV_LOG_ERROR, "Error propagating hwaccel state\n");
452  return err;
453  }
454  }
455  p_dst->hwaccel_threadsafe = 1;
456  }
457  }
458 
459  return err;
460 }
461 
462 /**
463  * Update the next thread's AVCodecContext with values set by the user.
464  *
465  * @param dst The destination context.
466  * @param src The source context.
467  * @return 0 on success, negative error code on failure
468  */
470 {
471  int err;
472 
473  dst->flags = src->flags;
474 
475  dst->draw_horiz_band= src->draw_horiz_band;
476  dst->get_buffer2 = src->get_buffer2;
477 
478  dst->opaque = src->opaque;
479  dst->debug = src->debug;
480 
481  dst->slice_flags = src->slice_flags;
482  dst->flags2 = src->flags2;
483  dst->export_side_data = src->export_side_data;
484 
485  dst->skip_loop_filter = src->skip_loop_filter;
486  dst->skip_idct = src->skip_idct;
487  dst->skip_frame = src->skip_frame;
488 
489  dst->frame_num = src->frame_num;
490 
491  av_packet_unref(dst->internal->last_pkt_props);
492  err = av_packet_copy_props(dst->internal->last_pkt_props, src->internal->last_pkt_props);
493  if (err < 0)
494  return err;
495 
496  return 0;
497 }
498 
500  AVPacket *in_pkt)
501 {
502  FrameThreadContext *fctx = p->parent;
503  PerThreadContext *prev_thread = fctx->prev_thread;
504  const AVCodec *codec = p->avctx->codec;
505  int ret;
506 
507  pthread_mutex_lock(&p->mutex);
508 
509  av_packet_unref(p->avpkt);
510  av_packet_move_ref(p->avpkt, in_pkt);
511 
512  if (AVPACKET_IS_EMPTY(p->avpkt))
513  p->avctx->internal->draining = 1;
514 
515  ret = update_context_from_user(p->avctx, user_avctx);
516  if (ret) {
517  pthread_mutex_unlock(&p->mutex);
518  return ret;
519  }
520  atomic_store_explicit(&p->debug_threads,
521  (p->avctx->debug & FF_DEBUG_THREADS) != 0,
522  memory_order_relaxed);
523 
524  if (prev_thread) {
525  if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) {
526  pthread_mutex_lock(&prev_thread->progress_mutex);
527  while (atomic_load(&prev_thread->state) == STATE_SETTING_UP)
528  pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
529  pthread_mutex_unlock(&prev_thread->progress_mutex);
530  }
531 
532  /* codecs without delay might not be prepared to be called repeatedly here during
533  * flushing (vp3/theora), and also don't need to be, since from this point on, they
534  * will always return EOF anyway */
535  if (!p->avctx->internal->draining ||
536  (codec->capabilities & AV_CODEC_CAP_DELAY)) {
537  ret = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
538  if (ret) {
539  pthread_mutex_unlock(&p->mutex);
540  return ret;
541  }
542  }
543  }
544 
545  /* transfer the stashed hwaccel state, if any */
546  av_assert0(!p->avctx->hwaccel || p->hwaccel_threadsafe);
547  if (!p->hwaccel_threadsafe) {
548  FFSWAP(const AVHWAccel*, p->avctx->hwaccel, fctx->stash_hwaccel);
549  FFSWAP(void*, p->avctx->hwaccel_context, fctx->stash_hwaccel_context);
550  FFSWAP(void*, p->avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv);
551  }
552 
553  atomic_store(&p->state, STATE_SETTING_UP);
554  pthread_cond_signal(&p->input_cond);
555  pthread_mutex_unlock(&p->mutex);
556 
557  fctx->prev_thread = p;
558  fctx->next_decoding = (fctx->next_decoding + 1) % p->avctx->thread_count;
559 
560  return 0;
561 }
562 
564 {
565  FrameThreadContext *fctx = avctx->internal->thread_ctx;
566  int ret = 0;
567 
568  /* release the async lock, permitting blocked hwaccel threads to
569  * go forward while we are in this function */
570  async_unlock(fctx);
571 
572  /* submit packets to threads while there are no buffered results to return */
573  while (!fctx->df.nb_f && !fctx->result) {
575 
576  if (fctx->next_decoding != fctx->next_finished &&
578  goto wait_for_result;
579 
580  /* get a packet to be submitted to the next thread */
581  av_packet_unref(fctx->next_pkt);
582  ret = ff_decode_get_packet(avctx, fctx->next_pkt);
583  if (ret < 0 && ret != AVERROR_EOF)
584  goto finish;
585 
586  ret = submit_packet(&fctx->threads[fctx->next_decoding], avctx,
587  fctx->next_pkt);
588  if (ret < 0)
589  goto finish;
590 
591  /* do not return any frames until all threads have something to do */
592  if (fctx->next_decoding != fctx->next_finished &&
593  !avctx->internal->draining)
594  continue;
595 
596  wait_for_result:
597  p = &fctx->threads[fctx->next_finished];
598  fctx->next_finished = (fctx->next_finished + 1) % avctx->thread_count;
599 
600  if (atomic_load(&p->state) != STATE_INPUT_READY) {
601  pthread_mutex_lock(&p->progress_mutex);
602  while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY)
603  pthread_cond_wait(&p->output_cond, &p->progress_mutex);
604  pthread_mutex_unlock(&p->progress_mutex);
605  }
606 
607  update_context_from_thread(avctx, p->avctx, 1);
608  fctx->result = p->result;
609  p->result = 0;
610  if (p->df.nb_f)
611  FFSWAP(DecodedFrames, fctx->df, p->df);
612  }
613 
614  /* a thread may return multiple frames AND an error
615  * we first return all the frames, then the error */
616  if (fctx->df.nb_f) {
617  decoded_frames_pop(&fctx->df, frame);
618  ret = 0;
619  } else {
620  ret = fctx->result;
621  fctx->result = 0;
622  }
623 
624 finish:
625  async_lock(fctx);
626  return ret;
627 }
628 
630 {
632  atomic_int *progress = f->progress ? f->progress->progress : NULL;
633 
634  if (!progress ||
635  atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
636  return;
637 
638  p = f->owner[field]->internal->thread_ctx;
639 
640  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
641  av_log(f->owner[field], AV_LOG_DEBUG,
642  "%p finished %d field %d\n", progress, n, field);
643 
644  pthread_mutex_lock(&p->progress_mutex);
645 
646  atomic_store_explicit(&progress[field], n, memory_order_release);
647 
648  pthread_cond_broadcast(&p->progress_cond);
649  pthread_mutex_unlock(&p->progress_mutex);
650 }
651 
652 void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
653 {
655  atomic_int *progress = f->progress ? f->progress->progress : NULL;
656 
657  if (!progress ||
658  atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
659  return;
660 
661  p = f->owner[field]->internal->thread_ctx;
662 
663  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
664  av_log(f->owner[field], AV_LOG_DEBUG,
665  "thread awaiting %d field %d from %p\n", n, field, progress);
666 
667  pthread_mutex_lock(&p->progress_mutex);
668  while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n)
669  pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
670  pthread_mutex_unlock(&p->progress_mutex);
671 }
672 
675 
676  if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
677 
678  p = avctx->internal->thread_ctx;
679 
680  p->hwaccel_threadsafe = avctx->hwaccel &&
682 
683  if (hwaccel_serial(avctx) && !p->hwaccel_serializing) {
684  pthread_mutex_lock(&p->parent->hwaccel_mutex);
685  p->hwaccel_serializing = 1;
686  }
687 
688  /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */
689  if (avctx->hwaccel &&
691  p->async_serializing = 1;
692 
693  async_lock(p->parent);
694  }
695 
696  /* thread-unsafe hwaccels share a single private data instance, so we
697  * save hwaccel state for passing to the next thread;
698  * this is done here so that this worker thread can wipe its own hwaccel
699  * state after decoding, without requiring synchronization */
700  av_assert0(!p->parent->stash_hwaccel);
701  if (hwaccel_serial(avctx)) {
702  p->parent->stash_hwaccel = avctx->hwaccel;
703  p->parent->stash_hwaccel_context = avctx->hwaccel_context;
704  p->parent->stash_hwaccel_priv = avctx->internal->hwaccel_priv_data;
705  }
706 
707  pthread_mutex_lock(&p->progress_mutex);
708  if(atomic_load(&p->state) == STATE_SETUP_FINISHED){
709  av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
710  }
711 
713 
714  pthread_cond_broadcast(&p->progress_cond);
715  pthread_mutex_unlock(&p->progress_mutex);
716 }
717 
718 /// Waits for all threads to finish.
719 static av_cold void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
720 {
721  int i;
722 
723  async_unlock(fctx);
724 
725  for (i = 0; i < thread_count; i++) {
726  PerThreadContext *p = &fctx->threads[i];
727 
728  if (atomic_load(&p->state) != STATE_INPUT_READY) {
729  pthread_mutex_lock(&p->progress_mutex);
730  while (atomic_load(&p->state) != STATE_INPUT_READY)
731  pthread_cond_wait(&p->output_cond, &p->progress_mutex);
732  pthread_mutex_unlock(&p->progress_mutex);
733  }
734  }
735 
736  async_lock(fctx);
737 }
738 
739 #define OFF(member) offsetof(FrameThreadContext, member)
740 DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, pthread_init_cnt,
741  (OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),
742  (OFF(async_cond)));
743 #undef OFF
744 
745 #define OFF(member) offsetof(PerThreadContext, member)
746 DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread, pthread_init_cnt,
747  (OFF(progress_mutex), OFF(mutex)),
748  (OFF(input_cond), OFF(progress_cond), OFF(output_cond)));
749 #undef OFF
750 
751 av_cold void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
752 {
753  FrameThreadContext *fctx = avctx->internal->thread_ctx;
754  const FFCodec *codec = ffcodec(avctx->codec);
755  int i;
756 
757  park_frame_worker_threads(fctx, thread_count);
758 
759  for (i = 0; i < thread_count; i++) {
760  PerThreadContext *p = &fctx->threads[i];
761  AVCodecContext *ctx = p->avctx;
762 
763  if (ctx->internal) {
764  if (p->thread_init == INITIALIZED) {
765  pthread_mutex_lock(&p->mutex);
766  p->die = 1;
767  pthread_cond_signal(&p->input_cond);
768  pthread_mutex_unlock(&p->mutex);
769 
770  pthread_join(p->thread, NULL);
771  }
772  if (codec->close && p->thread_init != UNINITIALIZED)
773  codec->close(ctx);
774 
775  /* When using a threadsafe hwaccel, this is where
776  * each thread's context is uninit'd and freed. */
778 
779  if (ctx->priv_data) {
780  if (codec->p.priv_class)
783  }
784 
785  av_refstruct_unref(&ctx->internal->pool);
786  av_packet_free(&ctx->internal->in_pkt);
787  av_packet_free(&ctx->internal->last_pkt_props);
789  av_freep(&ctx->internal);
790  av_buffer_unref(&ctx->hw_frames_ctx);
791  av_frame_side_data_free(&ctx->decoded_side_data,
792  &ctx->nb_decoded_side_data);
793  }
794 
795  decoded_frames_free(&p->df);
796 
797  ff_pthread_free(p, per_thread_offsets);
798  av_packet_free(&p->avpkt);
799 
800  av_freep(&p->avctx);
801  }
802 
803  decoded_frames_free(&fctx->df);
804  av_packet_free(&fctx->next_pkt);
805 
806  av_freep(&fctx->threads);
807  ff_pthread_free(fctx, thread_ctx_offsets);
808 
809  /* if we have stashed hwaccel state, move it to the user-facing context,
810  * so it will be freed in ff_codec_close() */
811  av_assert0(!avctx->hwaccel);
812  FFSWAP(const AVHWAccel*, avctx->hwaccel, fctx->stash_hwaccel);
813  FFSWAP(void*, avctx->hwaccel_context, fctx->stash_hwaccel_context);
814  FFSWAP(void*, avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv);
815 
816  av_freep(&avctx->internal->thread_ctx);
817 }
818 
819 static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
820  FrameThreadContext *fctx, AVCodecContext *avctx,
821  const FFCodec *codec, int first)
822 {
824  int err;
825 
826  atomic_init(&p->state, STATE_INPUT_READY);
827 
828  copy = av_memdup(avctx, sizeof(*avctx));
829  if (!copy)
830  return AVERROR(ENOMEM);
831  copy->priv_data = NULL;
832  copy->decoded_side_data = NULL;
833  copy->nb_decoded_side_data = 0;
834 
835  /* From now on, this PerThreadContext will be cleaned up by
836  * ff_frame_thread_free in case of errors. */
837  (*threads_to_free)++;
838 
839  p->parent = fctx;
840  p->avctx = copy;
841 
842  copy->internal = ff_decode_internal_alloc();
843  if (!copy->internal)
844  return AVERROR(ENOMEM);
846  copy->internal->thread_ctx = p;
847  copy->internal->progress_frame_pool = avctx->internal->progress_frame_pool;
848 
849  copy->delay = avctx->delay;
850 
851  if (codec->priv_data_size) {
852  copy->priv_data = av_mallocz(codec->priv_data_size);
853  if (!copy->priv_data)
854  return AVERROR(ENOMEM);
855 
856  if (codec->p.priv_class) {
857  *(const AVClass **)copy->priv_data = codec->p.priv_class;
858  err = av_opt_copy(copy->priv_data, avctx->priv_data);
859  if (err < 0)
860  return err;
861  }
862  }
863 
864  err = ff_pthread_init(p, per_thread_offsets);
865  if (err < 0)
866  return err;
867 
868  if (!(p->avpkt = av_packet_alloc()))
869  return AVERROR(ENOMEM);
870 
871  copy->internal->is_frame_mt = 1;
872  if (!first)
873  copy->internal->is_copy = 1;
874 
875  copy->internal->in_pkt = av_packet_alloc();
876  if (!copy->internal->in_pkt)
877  return AVERROR(ENOMEM);
878 
879  copy->internal->last_pkt_props = av_packet_alloc();
880  if (!copy->internal->last_pkt_props)
881  return AVERROR(ENOMEM);
882 
883  if (codec->init) {
884  err = codec->init(copy);
885  if (err < 0) {
887  p->thread_init = NEEDS_CLOSE;
888  return err;
889  }
890  }
891  p->thread_init = NEEDS_CLOSE;
892 
893  if (first) {
894  update_context_from_thread(avctx, copy, 1);
895 
897  for (int i = 0; i < copy->nb_decoded_side_data; i++) {
899  &avctx->nb_decoded_side_data,
900  copy->decoded_side_data[i], 0);
901  if (err < 0)
902  return err;
903  }
904  }
905 
906  atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
907 
908  err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
909  if (err < 0)
910  return err;
911  p->thread_init = INITIALIZED;
912 
913  return 0;
914 }
915 
917 {
918  int thread_count = avctx->thread_count;
919  const FFCodec *codec = ffcodec(avctx->codec);
920  FrameThreadContext *fctx;
921  int err, i = 0;
922 
923  if (!thread_count) {
924  int nb_cpus = av_cpu_count();
925  // use number of cores + 1 as thread count if there is more than one
926  if (nb_cpus > 1)
927  thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
928  else
929  thread_count = avctx->thread_count = 1;
930  }
931 
932  if (thread_count <= 1) {
933  avctx->active_thread_type = 0;
934  return 0;
935  }
936 
937  avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
938  if (!fctx)
939  return AVERROR(ENOMEM);
940 
941  err = ff_pthread_init(fctx, thread_ctx_offsets);
942  if (err < 0) {
943  ff_pthread_free(fctx, thread_ctx_offsets);
944  av_freep(&avctx->internal->thread_ctx);
945  return err;
946  }
947 
948  fctx->next_pkt = av_packet_alloc();
949  if (!fctx->next_pkt)
950  return AVERROR(ENOMEM);
951 
952  fctx->async_lock = 1;
953 
954  if (codec->p.type == AVMEDIA_TYPE_VIDEO)
955  avctx->delay = avctx->thread_count - 1;
956 
957  fctx->threads = av_calloc(thread_count, sizeof(*fctx->threads));
958  if (!fctx->threads) {
959  err = AVERROR(ENOMEM);
960  goto error;
961  }
962 
963  for (; i < thread_count; ) {
964  PerThreadContext *p = &fctx->threads[i];
965  int first = !i;
966 
967  err = init_thread(p, &i, fctx, avctx, codec, first);
968  if (err < 0)
969  goto error;
970  }
971 
972  return 0;
973 
974 error:
975  ff_frame_thread_free(avctx, i);
976  return err;
977 }
978 
980 {
981  int i;
982  FrameThreadContext *fctx = avctx->internal->thread_ctx;
983 
984  if (!fctx) return;
985 
987  if (fctx->prev_thread) {
988  if (fctx->prev_thread != &fctx->threads[0])
990  }
991 
992  fctx->next_decoding = fctx->next_finished = 0;
993  fctx->prev_thread = NULL;
994 
995  decoded_frames_flush(&fctx->df);
996  fctx->result = 0;
997 
998  for (i = 0; i < avctx->thread_count; i++) {
999  PerThreadContext *p = &fctx->threads[i];
1000 
1001  decoded_frames_flush(&p->df);
1002  p->result = 0;
1003 
1004  avcodec_flush_buffers(p->avctx);
1005  }
1006 }
1007 
1009 {
1010  if ((avctx->active_thread_type & FF_THREAD_FRAME) &&
1011  ffcodec(avctx->codec)->update_thread_context) {
1013 
1014  if (atomic_load(&p->state) != STATE_SETTING_UP)
1015  return 0;
1016  }
1017 
1018  return 1;
1019 }
1020 
1022 {
1024  int err;
1025 
1026  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
1027  return ff_get_buffer(avctx, f, flags);
1028 
1029  p = avctx->internal->thread_ctx;
1030  if (atomic_load(&p->state) != STATE_SETTING_UP &&
1031  ffcodec(avctx->codec)->update_thread_context) {
1032  av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
1033  return -1;
1034  }
1035 
1036  pthread_mutex_lock(&p->parent->buffer_mutex);
1037  err = ff_get_buffer(avctx, f, flags);
1038 
1039  pthread_mutex_unlock(&p->parent->buffer_mutex);
1040 
1041  return err;
1042 }
1043 
1045 {
1046  int ret = thread_get_buffer_internal(avctx, f, flags);
1047  if (ret < 0)
1048  av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
1049  return ret;
1050 }
1051 
1053 {
1054  int ret;
1055 
1056  f->owner[0] = f->owner[1] = avctx;
1057  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
1058  return ff_get_buffer(avctx, f->f, flags);
1059 
1060  f->progress = av_refstruct_allocz(sizeof(*f->progress));
1061  if (!f->progress)
1062  return AVERROR(ENOMEM);
1063 
1064  atomic_init(&f->progress->progress[0], -1);
1065  atomic_init(&f->progress->progress[1], -1);
1066 
1067  ret = ff_thread_get_buffer(avctx, f->f, flags);
1068  if (ret)
1069  av_refstruct_unref(&f->progress);
1070  return ret;
1071 }
1072 
1074 {
1075  av_refstruct_unref(&f->progress);
1076  f->owner[0] = f->owner[1] = NULL;
1077  if (f->f)
1078  av_frame_unref(f->f);
1079 }
1080 
1082 {
1084  const void *ref;
1085 
1086  if (!avctx->internal->is_copy)
1087  return avctx->active_thread_type & FF_THREAD_FRAME ?
1089 
1090  p = avctx->internal->thread_ctx;
1091 
1092  av_assert1(memcpy(&ref, (char*)avctx->priv_data + offset, sizeof(ref)) && ref == NULL);
1093 
1094  memcpy(&ref, (const char*)p->parent->threads[0].avctx->priv_data + offset, sizeof(ref));
1095  av_assert1(ref);
1096  av_refstruct_replace((char*)avctx->priv_data + offset, ref);
1097 
1098  return FF_THREAD_IS_COPY;
1099 }
1100 
1102 {
1104 
1105  if (!AVPACKET_IS_EMPTY(p->avpkt)) {
1106  av_packet_move_ref(pkt, p->avpkt);
1107  return 0;
1108  }
1109 
1110  return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN);
1111 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
flags
const SwsFlags flags[]
Definition: swscale.c:71
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:174
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:432
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1417
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:180
AVCodecContext::hwaccel_context
void * hwaccel_context
Legacy hardware accelerator context.
Definition: avcodec.h:1441
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:216
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:251
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
hwaccel_serial
static int hwaccel_serial(const AVCodecContext *avctx)
Definition: pthread_frame.c:157
AVCodecContext::decoded_side_data
AVFrameSideData ** decoded_side_data
Array containing static side data, such as HDR10 CLL / MDCV structures.
Definition: avcodec.h:1936
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:146
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:819
INITIALIZED
@ INITIALIZED
Thread has been properly set up.
Definition: pthread_frame.c:65
ff_thread_can_start_frame
int ff_thread_can_start_frame(AVCodecContext *avctx)
Definition: pthread_frame.c:1008
decoded_frames_free
static void decoded_frames_free(DecodedFrames *df)
Definition: pthread_frame.c:228
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:123
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
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:1081
version_major.h
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
FFCodec
Definition: codec_internal.h:127
STATE_INPUT_READY
@ STATE_INPUT_READY
Set when the thread is awaiting a packet.
Definition: pthread_frame.c:55
FrameThreadContext::next_pkt
AVPacket * next_pkt
Packet to be submitted to the next thread for decoding.
Definition: pthread_frame.c:144
DecodedFrames::nb_f
size_t nb_f
Definition: pthread_frame.c:70
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:248
FrameThreadContext::stash_hwaccel_context
void * stash_hwaccel_context
Definition: pthread_frame.c:153
AVCodecContext::delay
int delay
Codec delay.
Definition: avcodec.h:583
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:147
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:74
FrameThreadContext::buffer_mutex
pthread_mutex_t buffer_mutex
Mutex used to protect get/release_buffer().
Definition: pthread_frame.c:128
ff_hwaccel_uninit
void ff_hwaccel_uninit(AVCodecContext *avctx)
Definition: decode.c:1198
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:162
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:1955
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:448
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1573
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:469
FrameThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:127
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1943
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:52
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:719
mutex
static AVMutex mutex
Definition: resman.c:61
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
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_cold
#define av_cold
Definition: attributes.h:106
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:629
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:179
FrameThreadContext::async_lock
int async_lock
Definition: pthread_frame.c:136
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
UNINITIALIZED
@ UNINITIALIZED
Thread has not been created, AVCodec->close mustn't be called.
Definition: pthread_frame.c:63
AVCodecContext::nb_decoded_side_data
int nb_decoded_side_data
Definition: avcodec.h:1937
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:1044
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:979
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
decode.h
STATE_SETTING_UP
@ STATE_SETTING_UP
Set before the codec has called ff_thread_finish_setup().
Definition: pthread_frame.c:57
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
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
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:125
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
FFCodec::init
int(* init)(struct AVCodecContext *)
Definition: codec_internal.h:187
ff_decode_internal_sync
void ff_decode_internal_sync(struct AVCodecContext *dst, const struct AVCodecContext *src)
arg
const char * arg
Definition: jacosubdec.c:65
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
threadframe.h
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:76
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
ff_thread_receive_frame
int ff_thread_receive_frame(AVCodecContext *avctx, AVFrame *frame, unsigned flags)
Submit available packets for decoding to worker threads, return a decoded frame if available.
Definition: pthread_frame.c:563
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:652
thread_get_buffer_internal
static int thread_get_buffer_internal(AVCodecContext *avctx, AVFrame *f, int flags)
Definition: pthread_frame.c:1021
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:244
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:474
STATE_SETUP_FINISHED
@ STATE_SETUP_FINISHED
Set after the codec has called ff_thread_finish_setup().
Definition: pthread_frame.c:59
PerThreadContext::progress_mutex
pthread_mutex_t progress_mutex
Mutex used to protect frame progress values and progress_cond.
Definition: pthread_frame.c:92
FrameThreadContext::async_mutex
pthread_mutex_t async_mutex
Definition: pthread_frame.c:134
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:673
ff_thread_release_ext_buffer
void ff_thread_release_ext_buffer(ThreadFrame *f)
Unref a ThreadFrame.
Definition: pthread_frame.c:1073
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:133
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_CODEC_RECEIVE_FRAME_FLAG_SYNCHRONOUS
#define AV_CODEC_RECEIVE_FRAME_FLAG_SYNCHRONOUS
The decoder will bypass frame threading and return the next frame as soon as possible.
Definition: avcodec.h:424
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:489
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:1399
OFF
#define OFF(member)
Definition: pthread_frame.c:745
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:162
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:2145
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:228
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
NEEDS_CLOSE
@ NEEDS_CLOSE
FFCodec->close needs to be called.
Definition: pthread_frame.c:64
FrameThreadContext::stash_hwaccel
const AVHWAccel * stash_hwaccel
Definition: pthread_frame.c:152
ff_frame_thread_free
av_cold void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
Definition: pthread_frame.c:751
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:1747
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:87
cpu.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
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:171
FrameThreadContext::async_cond
pthread_cond_t async_cond
Definition: pthread_frame.c:135
ffcodec
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
Definition: codec_internal.h:290
decoded_frames_pop
static void decoded_frames_pop(DecodedFrames *df, AVFrame *dst)
Definition: pthread_frame.c:213
frame.h
buffer.h
FrameThreadContext::df
DecodedFrames df
Definition: pthread_frame.c:138
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:63
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:1101
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:614
decoded_frames_flush
static void decoded_frames_flush(DecodedFrames *df)
Definition: pthread_frame.c:221
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1584
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:395
PerThreadContext::thread_init
int thread_init
Definition: pthread_frame.c:85
log.h
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:133
internal.h
common.h
FrameThreadContext::result
int result
Definition: pthread_frame.c:139
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:58
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:523
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
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:1052
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:381
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:265
ff_decode_internal_alloc
struct AVCodecInternal * ff_decode_internal_alloc(void)
Definition: decode.c:2346
decoded_frames_get_free
static AVFrame * decoded_frames_get_free(DecodedFrames *df)
Definition: pthread_frame.c:192
PerThreadContext::async_serializing
int async_serializing
Definition: pthread_frame.c:109
hwaccel
static const char * hwaccel
Definition: ffplay.c:356
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:439
AVCodecContext::active_thread_type
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1592
PerThreadContext::hwaccel_serializing
int hwaccel_serializing
Definition: pthread_frame.c:108
ThreadFrame
Definition: threadframe.h:27
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:499
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
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
FFCodec::close
int(* close)(struct AVCodecContext *)
Definition: codec_internal.h:249
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
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
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
mem.h
packet_internal.h
ff_frame_thread_init
av_cold int ff_frame_thread_init(AVCodecContext *avctx)
Definition: pthread_frame.c:916
ThreadingStatus
ThreadingStatus
Definition: thread.h:60
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:466
AVPacket
This structure stores compressed data.
Definition: packet.h:565
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:2366
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:346
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
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:1291
ThreadFrameProgress::progress
atomic_int progress[2]
Definition: pthread_frame.c:75
FrameThreadContext::stash_hwaccel_priv
void * stash_hwaccel_priv
Definition: pthread_frame.c:154
src
#define src
Definition: vp8dsp.c:248
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:124
ff_thread_setname
static int ff_thread_setname(const char *name)
Definition: thread.h:216