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