FFmpeg
pthread_frame.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file
21  * Frame multithreading support functions
22  * @see doc/multithreading.txt
23  */
24 
25 #include "config.h"
26 
27 #include <stdatomic.h>
28 #include <stdint.h>
29 
30 #include "avcodec.h"
31 #include "avcodec_internal.h"
32 #include "codec_internal.h"
33 #include "decode.h"
34 #include "hwaccel_internal.h"
35 #include "hwconfig.h"
36 #include "internal.h"
37 #include "pthread_internal.h"
38 #include "refstruct.h"
39 #include "thread.h"
40 #include "threadframe.h"
41 #include "version_major.h"
42 
43 #include "libavutil/avassert.h"
44 #include "libavutil/buffer.h"
45 #include "libavutil/common.h"
46 #include "libavutil/cpu.h"
47 #include "libavutil/frame.h"
48 #include "libavutil/internal.h"
49 #include "libavutil/log.h"
50 #include "libavutil/mem.h"
51 #include "libavutil/opt.h"
52 #include "libavutil/thread.h"
53 
54 enum {
55  /// Set when the thread is awaiting a packet.
57  /// Set before the codec has called ff_thread_finish_setup().
59  /// Set after the codec has called ff_thread_finish_setup().
61 };
62 
63 enum {
64  UNINITIALIZED, ///< Thread has not been created, AVCodec->close mustn't be called
65  NEEDS_CLOSE, ///< FFCodec->close needs to be called
66  INITIALIZED, ///< Thread has been properly set up
67 };
68 
69 typedef struct ThreadFrameProgress {
72 
73 /**
74  * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
75  */
76 typedef struct PerThreadContext {
78 
81  unsigned pthread_init_cnt;///< Number of successfully initialized mutexes/conditions
82  pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread.
83  pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change.
84  pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish.
85 
86  pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext.
87  pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
88 
89  AVCodecContext *avctx; ///< Context used to decode packets passed to this thread.
90 
91  AVPacket *avpkt; ///< Input packet (for decoding) or output (for encoding).
92 
93  AVFrame *frame; ///< Output frame (for decoding) or input (for encoding).
94  int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
95  int result; ///< The result of the last codec decode/encode() call.
96 
98 
99  int die; ///< Set when the thread should exit.
100 
103 
104  // set to 1 in ff_thread_finish_setup() when a threadsafe hwaccel is used;
105  // cannot check hwaccel caps directly, because
106  // worked threads clear hwaccel state for thread-unsafe hwaccels
107  // after each decode call
109 
110  atomic_int debug_threads; ///< Set if the FF_DEBUG_THREADS option is set.
112 
113 /**
114  * Context stored in the client AVCodecInternal thread_ctx.
115  */
116 typedef struct FrameThreadContext {
117  PerThreadContext *threads; ///< The contexts for each thread.
118  PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
119 
120  unsigned pthread_init_cnt; ///< Number of successfully initialized mutexes/conditions
121  pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
122  /**
123  * This lock is used for ensuring threads run in serial when thread-unsafe
124  * hwaccel is used.
125  */
130 
131  int next_decoding; ///< The next context to submit a packet to.
132  int next_finished; ///< The next context to return output from.
133 
134  int delaying; /**<
135  * Set for the first N packets, where N is the number of threads.
136  * While it is set, ff_thread_en/decode_frame won't return any results.
137  */
138 
139  /* hwaccel state for thread-unsafe hwaccels is temporarily stored here in
140  * order to transfer its ownership to the next decoding thread without the
141  * need for extra synchronization */
146 
147 static int hwaccel_serial(const AVCodecContext *avctx)
148 {
149  return avctx->hwaccel && !(ffhwaccel(avctx->hwaccel)->caps_internal & HWACCEL_CAP_THREAD_SAFE);
150 }
151 
152 static void async_lock(FrameThreadContext *fctx)
153 {
155  while (fctx->async_lock)
156  pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex);
157  fctx->async_lock = 1;
159 }
160 
162 {
164  av_assert0(fctx->async_lock);
165  fctx->async_lock = 0;
168 }
169 
171 {
172  AVCodecContext *avctx = p->avctx;
173  int idx = p - p->parent->threads;
174  char name[16];
175 
176  snprintf(name, sizeof(name), "av:%.7s:df%d", avctx->codec->name, idx);
177 
179 }
180 
181 /**
182  * Codec worker thread.
183  *
184  * Automatically calls ff_thread_finish_setup() if the codec does
185  * not provide an update_thread_context method, or if the codec returns
186  * before calling it.
187  */
189 {
190  PerThreadContext *p = arg;
191  AVCodecContext *avctx = p->avctx;
192  const FFCodec *codec = ffcodec(avctx->codec);
193 
194  thread_set_name(p);
195 
197  while (1) {
198  while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die)
200 
201  if (p->die) break;
202 
203  if (!codec->update_thread_context)
204  ff_thread_finish_setup(avctx);
205 
206  /* If a decoder supports hwaccel, then it must call ff_get_format().
207  * Since that call must happen before ff_thread_finish_setup(), the
208  * decoder is required to implement update_thread_context() and call
209  * ff_thread_finish_setup() manually. Therefore the above
210  * ff_thread_finish_setup() call did not happen and hwaccel_serializing
211  * cannot be true here. */
213 
214  /* if the previous thread uses thread-unsafe hwaccel then we take the
215  * lock to ensure the threads don't run concurrently */
216  if (hwaccel_serial(avctx)) {
218  p->hwaccel_serializing = 1;
219  }
220 
221  av_frame_unref(p->frame);
222  p->got_frame = 0;
223  p->result = codec->cb.decode(avctx, p->frame, &p->got_frame, p->avpkt);
224 
225  if ((p->result < 0 || !p->got_frame) && p->frame->buf[0])
226  av_frame_unref(p->frame);
227 
228  if (atomic_load(&p->state) == STATE_SETTING_UP)
229  ff_thread_finish_setup(avctx);
230 
231  if (p->hwaccel_serializing) {
232  /* wipe hwaccel state for thread-unsafe hwaccels to avoid stale
233  * pointers lying around;
234  * the state was transferred to FrameThreadContext in
235  * ff_thread_finish_setup(), so nothing is leaked */
236  avctx->hwaccel = NULL;
237  avctx->hwaccel_context = NULL;
238  avctx->internal->hwaccel_priv_data = NULL;
239 
240  p->hwaccel_serializing = 0;
242  }
243  av_assert0(!avctx->hwaccel ||
245 
246  if (p->async_serializing) {
247  p->async_serializing = 0;
248 
249  async_unlock(p->parent);
250  }
251 
253 
255 
259  }
261 
262  return NULL;
263 }
264 
265 /**
266  * Update the next thread's AVCodecContext with values from the reference thread's context.
267  *
268  * @param dst The destination context.
269  * @param src The source context.
270  * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
271  * @return 0 on success, negative error code on failure
272  */
273 static int update_context_from_thread(AVCodecContext *dst, const AVCodecContext *src, int for_user)
274 {
275  const FFCodec *const codec = ffcodec(dst->codec);
276  int err = 0;
277 
278  if (dst != src && (for_user || codec->update_thread_context)) {
279  dst->time_base = src->time_base;
280  dst->framerate = src->framerate;
281  dst->width = src->width;
282  dst->height = src->height;
283  dst->pix_fmt = src->pix_fmt;
284  dst->sw_pix_fmt = src->sw_pix_fmt;
285 
286  dst->coded_width = src->coded_width;
287  dst->coded_height = src->coded_height;
288 
289  dst->has_b_frames = src->has_b_frames;
290  dst->idct_algo = src->idct_algo;
291  dst->properties = src->properties;
292 
293  dst->bits_per_coded_sample = src->bits_per_coded_sample;
294  dst->sample_aspect_ratio = src->sample_aspect_ratio;
295 
296  dst->profile = src->profile;
297  dst->level = src->level;
298 
299  dst->bits_per_raw_sample = src->bits_per_raw_sample;
300 #if FF_API_TICKS_PER_FRAME
302  dst->ticks_per_frame = src->ticks_per_frame;
304 #endif
305  dst->color_primaries = src->color_primaries;
306 
307  dst->color_trc = src->color_trc;
308  dst->colorspace = src->colorspace;
309  dst->color_range = src->color_range;
310  dst->chroma_sample_location = src->chroma_sample_location;
311 
312  dst->sample_rate = src->sample_rate;
313  dst->sample_fmt = src->sample_fmt;
314 #if FF_API_OLD_CHANNEL_LAYOUT
316  dst->channels = src->channels;
317  dst->channel_layout = src->channel_layout;
319 #endif
320  err = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
321  if (err < 0)
322  return err;
323 
324  if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
325  (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
327 
328  if (src->hw_frames_ctx) {
329  dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
330  if (!dst->hw_frames_ctx)
331  return AVERROR(ENOMEM);
332  }
333  }
334 
335  dst->hwaccel_flags = src->hwaccel_flags;
336 
337  ff_refstruct_replace(&dst->internal->pool, src->internal->pool);
338  }
339 
340  if (for_user) {
342  err = codec->update_thread_context_for_user(dst, src);
343  } else {
344  const PerThreadContext *p_src = src->internal->thread_ctx;
345  PerThreadContext *p_dst = dst->internal->thread_ctx;
346 
347  if (codec->update_thread_context) {
348  err = codec->update_thread_context(dst, src);
349  if (err < 0)
350  return err;
351  }
352 
353  // reset dst hwaccel state if needed
355  (!dst->hwaccel && !dst->internal->hwaccel_priv_data));
356  if (p_dst->hwaccel_threadsafe &&
357  (!p_src->hwaccel_threadsafe || dst->hwaccel != src->hwaccel)) {
358  ff_hwaccel_uninit(dst);
359  p_dst->hwaccel_threadsafe = 0;
360  }
361 
362  // propagate hwaccel state for threadsafe hwaccels
363  if (p_src->hwaccel_threadsafe) {
364  const FFHWAccel *hwaccel = ffhwaccel(src->hwaccel);
365  if (!dst->hwaccel) {
366  if (hwaccel->priv_data_size) {
368 
370  av_mallocz(hwaccel->priv_data_size);
371  if (!dst->internal->hwaccel_priv_data)
372  return AVERROR(ENOMEM);
373  }
374  dst->hwaccel = src->hwaccel;
375  }
376  av_assert0(dst->hwaccel == src->hwaccel);
377 
378  if (hwaccel->update_thread_context) {
379  err = hwaccel->update_thread_context(dst, src);
380  if (err < 0) {
381  av_log(dst, AV_LOG_ERROR, "Error propagating hwaccel state\n");
382  ff_hwaccel_uninit(dst);
383  return err;
384  }
385  }
386  p_dst->hwaccel_threadsafe = 1;
387  }
388  }
389 
390  return err;
391 }
392 
393 /**
394  * Update the next thread's AVCodecContext with values set by the user.
395  *
396  * @param dst The destination context.
397  * @param src The source context.
398  * @return 0 on success, negative error code on failure
399  */
401 {
402  int err;
403 
404  dst->flags = src->flags;
405 
406  dst->draw_horiz_band= src->draw_horiz_band;
407  dst->get_buffer2 = src->get_buffer2;
408 
409  dst->opaque = src->opaque;
410  dst->debug = src->debug;
411 
412  dst->slice_flags = src->slice_flags;
413  dst->flags2 = src->flags2;
414  dst->export_side_data = src->export_side_data;
415 
416  dst->skip_loop_filter = src->skip_loop_filter;
417  dst->skip_idct = src->skip_idct;
418  dst->skip_frame = src->skip_frame;
419 
420  dst->frame_num = src->frame_num;
421 #if FF_API_AVCTX_FRAME_NUMBER
423  dst->frame_number = src->frame_number;
425 #endif
426 #if FF_API_REORDERED_OPAQUE
428  dst->reordered_opaque = src->reordered_opaque;
430 #endif
431 
433  err = av_packet_copy_props(dst->internal->last_pkt_props, src->internal->last_pkt_props);
434  if (err < 0)
435  return err;
436 
437  return 0;
438 }
439 
440 static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx,
441  AVPacket *avpkt)
442 {
443  FrameThreadContext *fctx = p->parent;
444  PerThreadContext *prev_thread = fctx->prev_thread;
445  const AVCodec *codec = p->avctx->codec;
446  int ret;
447 
448  if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY))
449  return 0;
450 
452 
453  ret = update_context_from_user(p->avctx, user_avctx);
454  if (ret) {
456  return ret;
457  }
459  (p->avctx->debug & FF_DEBUG_THREADS) != 0,
460  memory_order_relaxed);
461 
462  if (prev_thread) {
463  int err;
464  if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) {
465  pthread_mutex_lock(&prev_thread->progress_mutex);
466  while (atomic_load(&prev_thread->state) == STATE_SETTING_UP)
467  pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
468  pthread_mutex_unlock(&prev_thread->progress_mutex);
469  }
470 
471  err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
472  if (err) {
474  return err;
475  }
476  }
477 
478  /* transfer the stashed hwaccel state, if any */
480  if (!p->hwaccel_threadsafe) {
481  FFSWAP(const AVHWAccel*, p->avctx->hwaccel, fctx->stash_hwaccel);
484  }
485 
487  ret = av_packet_ref(p->avpkt, avpkt);
488  if (ret < 0) {
490  av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n");
491  return ret;
492  }
493 
497 
498  fctx->prev_thread = p;
499  fctx->next_decoding++;
500 
501  return 0;
502 }
503 
505  AVFrame *picture, int *got_picture_ptr,
506  AVPacket *avpkt)
507 {
508  FrameThreadContext *fctx = avctx->internal->thread_ctx;
509  int finished = fctx->next_finished;
510  PerThreadContext *p;
511  int err;
512 
513  /* release the async lock, permitting blocked hwaccel threads to
514  * go forward while we are in this function */
515  async_unlock(fctx);
516 
517  /*
518  * Submit a packet to the next decoding thread.
519  */
520 
521  p = &fctx->threads[fctx->next_decoding];
522  err = submit_packet(p, avctx, avpkt);
523  if (err)
524  goto finish;
525 
526  /*
527  * If we're still receiving the initial packets, don't return a frame.
528  */
529 
530  if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
531  fctx->delaying = 0;
532 
533  if (fctx->delaying) {
534  *got_picture_ptr=0;
535  if (avpkt->size) {
536  err = avpkt->size;
537  goto finish;
538  }
539  }
540 
541  /*
542  * Return the next available frame from the oldest thread.
543  * If we're at the end of the stream, then we have to skip threads that
544  * didn't output a frame/error, because we don't want to accidentally signal
545  * EOF (avpkt->size == 0 && *got_picture_ptr == 0 && err >= 0).
546  */
547 
548  do {
549  p = &fctx->threads[finished++];
550 
551  if (atomic_load(&p->state) != STATE_INPUT_READY) {
553  while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY)
556  }
557 
558  av_frame_move_ref(picture, p->frame);
559  *got_picture_ptr = p->got_frame;
560  picture->pkt_dts = p->avpkt->dts;
561  err = p->result;
562 
563  /*
564  * A later call with avkpt->size == 0 may loop over all threads,
565  * including this one, searching for a frame/error to return before being
566  * stopped by the "finished != fctx->next_finished" condition.
567  * Make sure we don't mistakenly return the same frame/error again.
568  */
569  p->got_frame = 0;
570  p->result = 0;
571 
572  if (finished >= avctx->thread_count) finished = 0;
573  } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished);
574 
575  update_context_from_thread(avctx, p->avctx, 1);
576 
577  if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
578 
579  fctx->next_finished = finished;
580 
581  /* return the size of the consumed packet if no error occurred */
582  if (err >= 0)
583  err = avpkt->size;
584 finish:
585  async_lock(fctx);
586  return err;
587 }
588 
590 {
591  PerThreadContext *p;
592  atomic_int *progress = f->progress ? f->progress->progress : NULL;
593 
594  if (!progress ||
595  atomic_load_explicit(&progress[field], memory_order_relaxed) >= n)
596  return;
597 
598  p = f->owner[field]->internal->thread_ctx;
599 
600  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
601  av_log(f->owner[field], AV_LOG_DEBUG,
602  "%p finished %d field %d\n", progress, n, field);
603 
605 
606  atomic_store_explicit(&progress[field], n, memory_order_release);
607 
610 }
611 
612 void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
613 {
614  PerThreadContext *p;
615  atomic_int *progress = f->progress ? f->progress->progress : NULL;
616 
617  if (!progress ||
618  atomic_load_explicit(&progress[field], memory_order_acquire) >= n)
619  return;
620 
621  p = f->owner[field]->internal->thread_ctx;
622 
623  if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed))
624  av_log(f->owner[field], AV_LOG_DEBUG,
625  "thread awaiting %d field %d from %p\n", n, field, progress);
626 
628  while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n)
631 }
632 
634  PerThreadContext *p;
635 
636  if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
637 
638  p = avctx->internal->thread_ctx;
639 
640  p->hwaccel_threadsafe = avctx->hwaccel &&
642 
643  if (hwaccel_serial(avctx) && !p->hwaccel_serializing) {
645  p->hwaccel_serializing = 1;
646  }
647 
648  /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */
649  if (avctx->hwaccel &&
651  p->async_serializing = 1;
652 
653  async_lock(p->parent);
654  }
655 
656  /* thread-unsafe hwaccels share a single private data instance, so we
657  * save hwaccel state for passing to the next thread;
658  * this is done here so that this worker thread can wipe its own hwaccel
659  * state after decoding, without requiring synchronization */
661  if (hwaccel_serial(avctx)) {
662  p->parent->stash_hwaccel = avctx->hwaccel;
665  }
666 
669  av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
670  }
671 
673 
676 }
677 
678 /// Waits for all threads to finish.
679 static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
680 {
681  int i;
682 
683  async_unlock(fctx);
684 
685  for (i = 0; i < thread_count; i++) {
686  PerThreadContext *p = &fctx->threads[i];
687 
688  if (atomic_load(&p->state) != STATE_INPUT_READY) {
690  while (atomic_load(&p->state) != STATE_INPUT_READY)
693  }
694  p->got_frame = 0;
695  }
696 
697  async_lock(fctx);
698 }
699 
700 #define OFF(member) offsetof(FrameThreadContext, member)
701 DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, pthread_init_cnt,
702  (OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),
703  (OFF(async_cond)));
704 #undef OFF
705 
706 #define OFF(member) offsetof(PerThreadContext, member)
707 DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread, pthread_init_cnt,
708  (OFF(progress_mutex), OFF(mutex)),
709  (OFF(input_cond), OFF(progress_cond), OFF(output_cond)));
710 #undef OFF
711 
712 void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
713 {
714  FrameThreadContext *fctx = avctx->internal->thread_ctx;
715  const FFCodec *codec = ffcodec(avctx->codec);
716  int i;
717 
718  park_frame_worker_threads(fctx, thread_count);
719 
720  for (i = 0; i < thread_count; i++) {
721  PerThreadContext *p = &fctx->threads[i];
722  AVCodecContext *ctx = p->avctx;
723 
724  if (ctx->internal) {
725  if (p->thread_init == INITIALIZED) {
727  p->die = 1;
730 
731  pthread_join(p->thread, NULL);
732  }
733  if (codec->close && p->thread_init != UNINITIALIZED)
734  codec->close(ctx);
735 
736  /* When using a threadsafe hwaccel, this is where
737  * each thread's context is uninit'd and freed. */
739 
740  if (ctx->priv_data) {
741  if (codec->p.priv_class)
744  }
745 
746  ff_refstruct_unref(&ctx->internal->pool);
747  av_packet_free(&ctx->internal->last_pkt_props);
748  av_freep(&ctx->internal);
749  av_buffer_unref(&ctx->hw_frames_ctx);
750  }
751 
752  av_frame_free(&p->frame);
753 
754  ff_pthread_free(p, per_thread_offsets);
755  av_packet_free(&p->avpkt);
756 
757  av_freep(&p->avctx);
758  }
759 
760  av_freep(&fctx->threads);
761  ff_pthread_free(fctx, thread_ctx_offsets);
762 
763  /* if we have stashed hwaccel state, move it to the user-facing context,
764  * so it will be freed in avcodec_close() */
765  av_assert0(!avctx->hwaccel);
766  FFSWAP(const AVHWAccel*, avctx->hwaccel, fctx->stash_hwaccel);
767  FFSWAP(void*, avctx->hwaccel_context, fctx->stash_hwaccel_context);
768  FFSWAP(void*, avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv);
769 
770  av_freep(&avctx->internal->thread_ctx);
771 }
772 
773 static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
774  FrameThreadContext *fctx, AVCodecContext *avctx,
775  const FFCodec *codec, int first)
776 {
778  int err;
779 
781 
782  copy = av_memdup(avctx, sizeof(*avctx));
783  if (!copy)
784  return AVERROR(ENOMEM);
785  copy->priv_data = NULL;
786 
787  /* From now on, this PerThreadContext will be cleaned up by
788  * ff_frame_thread_free in case of errors. */
789  (*threads_to_free)++;
790 
791  p->parent = fctx;
792  p->avctx = copy;
793 
794  copy->internal = ff_decode_internal_alloc();
795  if (!copy->internal)
796  return AVERROR(ENOMEM);
797  copy->internal->thread_ctx = p;
798 
799  copy->delay = avctx->delay;
800 
801  if (codec->priv_data_size) {
802  copy->priv_data = av_mallocz(codec->priv_data_size);
803  if (!copy->priv_data)
804  return AVERROR(ENOMEM);
805 
806  if (codec->p.priv_class) {
807  *(const AVClass **)copy->priv_data = codec->p.priv_class;
808  err = av_opt_copy(copy->priv_data, avctx->priv_data);
809  if (err < 0)
810  return err;
811  }
812  }
813 
814  err = ff_pthread_init(p, per_thread_offsets);
815  if (err < 0)
816  return err;
817 
818  if (!(p->frame = av_frame_alloc()) ||
819  !(p->avpkt = av_packet_alloc()))
820  return AVERROR(ENOMEM);
821 
822  if (!first)
823  copy->internal->is_copy = 1;
824 
825  copy->internal->last_pkt_props = av_packet_alloc();
826  if (!copy->internal->last_pkt_props)
827  return AVERROR(ENOMEM);
828 
829  if (codec->init) {
830  err = codec->init(copy);
831  if (err < 0) {
834  return err;
835  }
836  }
838 
839  if (first)
840  update_context_from_thread(avctx, copy, 1);
841 
842  atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
843 
845  if (err < 0)
846  return err;
848 
849  return 0;
850 }
851 
853 {
854  int thread_count = avctx->thread_count;
855  const FFCodec *codec = ffcodec(avctx->codec);
856  FrameThreadContext *fctx;
857  int err, i = 0;
858 
859  if (!thread_count) {
860  int nb_cpus = av_cpu_count();
861  // use number of cores + 1 as thread count if there is more than one
862  if (nb_cpus > 1)
863  thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
864  else
865  thread_count = avctx->thread_count = 1;
866  }
867 
868  if (thread_count <= 1) {
869  avctx->active_thread_type = 0;
870  return 0;
871  }
872 
873  avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
874  if (!fctx)
875  return AVERROR(ENOMEM);
876 
877  err = ff_pthread_init(fctx, thread_ctx_offsets);
878  if (err < 0) {
879  ff_pthread_free(fctx, thread_ctx_offsets);
880  av_freep(&avctx->internal->thread_ctx);
881  return err;
882  }
883 
884  fctx->async_lock = 1;
885  fctx->delaying = 1;
886 
887  if (codec->p.type == AVMEDIA_TYPE_VIDEO)
888  avctx->delay = avctx->thread_count - 1;
889 
890  fctx->threads = av_calloc(thread_count, sizeof(*fctx->threads));
891  if (!fctx->threads) {
892  err = AVERROR(ENOMEM);
893  goto error;
894  }
895 
896  for (; i < thread_count; ) {
897  PerThreadContext *p = &fctx->threads[i];
898  int first = !i;
899 
900  err = init_thread(p, &i, fctx, avctx, codec, first);
901  if (err < 0)
902  goto error;
903  }
904 
905  return 0;
906 
907 error:
908  ff_frame_thread_free(avctx, i);
909  return err;
910 }
911 
913 {
914  int i;
915  FrameThreadContext *fctx = avctx->internal->thread_ctx;
916 
917  if (!fctx) return;
918 
920  if (fctx->prev_thread) {
921  if (fctx->prev_thread != &fctx->threads[0])
923  }
924 
925  fctx->next_decoding = fctx->next_finished = 0;
926  fctx->delaying = 1;
927  fctx->prev_thread = NULL;
928  for (i = 0; i < avctx->thread_count; i++) {
929  PerThreadContext *p = &fctx->threads[i];
930  // Make sure decode flush calls with size=0 won't return old frames
931  p->got_frame = 0;
932  av_frame_unref(p->frame);
933  p->result = 0;
934 
935  if (ffcodec(avctx->codec)->flush)
936  ffcodec(avctx->codec)->flush(p->avctx);
937  }
938 }
939 
941 {
942  if ((avctx->active_thread_type & FF_THREAD_FRAME) &&
944  PerThreadContext *p = avctx->internal->thread_ctx;
945 
946  if (atomic_load(&p->state) != STATE_SETTING_UP)
947  return 0;
948  }
949 
950  return 1;
951 }
952 
954 {
955  PerThreadContext *p;
956  int err;
957 
958  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
959  return ff_get_buffer(avctx, f, flags);
960 
961  p = avctx->internal->thread_ctx;
962  if (atomic_load(&p->state) != STATE_SETTING_UP &&
964  av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
965  return -1;
966  }
967 
969  err = ff_get_buffer(avctx, f, flags);
970 
972 
973  return err;
974 }
975 
977 {
978  int ret = thread_get_buffer_internal(avctx, f, flags);
979  if (ret < 0)
980  av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
981  return ret;
982 }
983 
985 {
986  int ret;
987 
988  f->owner[0] = f->owner[1] = avctx;
989  /* Hint: It is possible for this function to be called with codecs
990  * that don't support frame threading at all, namely in case
991  * a frame-threaded decoder shares code with codecs that are not.
992  * This currently affects non-MPEG-4 mpegvideo codecs and and VP7.
993  * The following check will always be true for them. */
994  if (!(avctx->active_thread_type & FF_THREAD_FRAME))
995  return ff_get_buffer(avctx, f->f, flags);
996 
998  f->progress = ff_refstruct_allocz(sizeof(*f->progress));
999  if (!f->progress)
1000  return AVERROR(ENOMEM);
1001 
1002  atomic_init(&f->progress->progress[0], -1);
1003  atomic_init(&f->progress->progress[1], -1);
1004  }
1005 
1006  ret = ff_thread_get_buffer(avctx, f->f, flags);
1007  if (ret)
1008  ff_refstruct_unref(&f->progress);
1009  return ret;
1010 }
1011 
1013 {
1014  ff_refstruct_unref(&f->progress);
1015  f->owner[0] = f->owner[1] = NULL;
1016  if (f->f)
1017  av_frame_unref(f->f);
1018 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
INITIALIZED
@ INITIALIZED
Thread has been properly set up.
Definition: pthread_frame.c:66
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:157
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:423
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1435
AVCodec
AVCodec.
Definition: codec.h:187
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:170
AVCodecContext::hwaccel_context
void * hwaccel_context
Legacy hardware accelerator context.
Definition: avcodec.h:1459
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:186
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:82
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:147
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1029
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1064
PerThreadContext::debug_threads
atomic_int debug_threads
Set if the FF_DEBUG_THREADS option is set.
Definition: pthread_frame.c:110
AVCodec::priv_class
const AVClass * priv_class
AVClass for the private context.
Definition: codec.h:219
FrameThreadContext::next_decoding
int next_decoding
The next context to submit a packet to.
Definition: pthread_frame.c:131
thread.h
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
ThreadFrameProgress
Definition: pthread_frame.c:69
ff_thread_flush
void ff_thread_flush(AVCodecContext *avctx)
Wait for decoding threads to finish and reset internal state.
Definition: pthread_frame.c:912
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:773
ff_thread_can_start_frame
int ff_thread_can_start_frame(AVCodecContext *avctx)
Definition: pthread_frame.c:940
MAX_AUTO_THREADS
#define MAX_AUTO_THREADS
Definition: pthread_internal.h:26
PerThreadContext::state
atomic_int state
Definition: pthread_frame.c:97
FrameThreadContext
Context stored in the client AVCodecInternal thread_ctx.
Definition: pthread_frame.c:116
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:100
park_frame_worker_threads
static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
Waits for all threads to finish.
Definition: pthread_frame.c:679
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:1022
AVCodec::capabilities
int capabilities
Codec capabilities.
Definition: codec.h:206
internal.h
version_major.h
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
FFCodec
Definition: codec_internal.h:127
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:590
FrameThreadContext::stash_hwaccel_context
void * stash_hwaccel_context
Definition: pthread_frame.c:143
AVCodecContext::delay
int delay
Codec delay.
Definition: avcodec.h:604
PerThreadContext::die
int die
Set when the thread should exit.
Definition: pthread_frame.c:99
thread.h
ff_pthread_free
av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
Definition: pthread.c:91
FrameThreadContext::next_finished
int next_finished
The next context to return output from.
Definition: pthread_frame.c:132
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:74
UNINITIALIZED
@ UNINITIALIZED
Thread has not been created, AVCodec->close mustn't be called.
Definition: pthread_frame.c:64
FrameThreadContext::buffer_mutex
pthread_mutex_t buffer_mutex
Mutex used to protect get/release_buffer().
Definition: pthread_frame.c:121
ff_hwaccel_uninit
void ff_hwaccel_uninit(AVCodecContext *avctx)
Definition: decode.c:1252
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:145
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1803
ff_frame_thread_free
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
Definition: pthread_frame.c:712
AVHWAccel
Definition: avcodec.h:2129
AVCodecContext::skip_idct
enum AVDiscard skip_idct
Skip IDCT/dequantization for selected frames.
Definition: avcodec.h:1759
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
finish
static void finish(void)
Definition: movenc.c:342
FFHWAccel
Definition: hwaccel_internal.h:34
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:450
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:2107
AVCodecContext::skip_frame
enum AVDiscard skip_frame
Skip decoding for selected frames.
Definition: avcodec.h:1766
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1532
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:400
FrameThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:120
HWACCEL_CAP_THREAD_SAFE
#define HWACCEL_CAP_THREAD_SAFE
Definition: hwaccel_internal.h:32
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:521
PerThreadContext
Context used by codec threads and stored in their AVCodecInternal thread_ctx.
Definition: pthread_frame.c:76
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:636
submit_packet
static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, AVPacket *avpkt)
Definition: pthread_frame.c:440
refstruct.h
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:88
AVCodecContext::get_buffer2
int(* get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags)
This callback is called at the beginning of each frame to get data buffer(s) for it.
Definition: avcodec.h:1237
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
avassert.h
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:1015
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
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:589
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:162
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:744
FrameThreadContext::async_lock
int async_lock
Definition: pthread_frame.c:129
FFHWAccel::priv_data_size
int priv_data_size
Size of the private data to allocate in AVCodecInternal.hwaccel_priv_data.
Definition: hwaccel_internal.h:112
AVCodecInternal::pool
struct FramePool * pool
Definition: internal.h:65
PerThreadContext::output_cond
pthread_cond_t output_cond
Used by the main thread to wait for frames to finish.
Definition: pthread_frame.c:84
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:976
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1517
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
FFCodec::flush
void(* flush)(struct AVCodecContext *)
Flush buffers.
Definition: codec_internal.h:246
decode.h
PerThreadContext::hwaccel_threadsafe
int hwaccel_threadsafe
Definition: pthread_frame.c:108
field
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this field
Definition: writing_filters.txt:78
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
pthread_cond_broadcast
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
Definition: os2threads.h:162
FrameThreadContext::prev_thread
PerThreadContext * prev_thread
The last thread submit_packet() was called on.
Definition: pthread_frame.c:118
FFCodec::decode
int(* decode)(struct AVCodecContext *avctx, struct AVFrame *frame, int *got_frame_ptr, struct AVPacket *avpkt)
Decode to an AVFrame.
Definition: codec_internal.h:193
FFCodec::init
int(* init)(struct AVCodecContext *)
Definition: codec_internal.h:178
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:451
arg
const char * arg
Definition: jacosubdec.c:67
pthread_create
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
Definition: os2threads.h:80
PerThreadContext::got_frame
int got_frame
The output of got_picture_ptr from the last avcodec_decode_video() call.
Definition: pthread_frame.c:94
threadframe.h
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:66
NULL
#define NULL
Definition: coverity.c:32
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:1039
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
hwaccel_internal.h
ff_thread_await_progress
void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
Definition: pthread_frame.c:612
AVCodecContext::slice_flags
int slice_flags
slice flags
Definition: avcodec.h:915
thread_get_buffer_internal
static int thread_get_buffer_internal(AVCodecContext *avctx, AVFrame *f, int flags)
Definition: pthread_frame.c:953
AVCodec::type
enum AVMediaType type
Definition: codec.h:200
frame_worker_thread
static attribute_align_arg void * frame_worker_thread(void *arg)
Codec worker thread.
Definition: pthread_frame.c:188
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:476
PerThreadContext::progress_mutex
pthread_mutex_t progress_mutex
Mutex used to protect frame progress values and progress_cond.
Definition: pthread_frame.c:87
FrameThreadContext::async_mutex
pthread_mutex_t async_mutex
Definition: pthread_frame.c:127
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:633
ff_thread_release_ext_buffer
void ff_thread_release_ext_buffer(ThreadFrame *f)
Unref a ThreadFrame.
Definition: pthread_frame.c:1012
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:126
PerThreadContext::avctx
AVCodecContext * avctx
Context used to decode packets passed to this thread.
Definition: pthread_frame.c:89
ff_refstruct_allocz
static void * ff_refstruct_allocz(size_t size)
Equivalent to ff_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
pthread_internal.h
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1719
FFCodec::cb
union FFCodec::@53 cb
AVFrame::pkt_dts
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
Definition: frame.h:459
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:431
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1740
atomic_load_explicit
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:96
FF_DEBUG_THREADS
#define FF_DEBUG_THREADS
Definition: avcodec.h:1401
OFF
#define OFF(member)
Definition: pthread_frame.c:706
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:79
AVCodecInternal::last_pkt_props
AVPacket * last_pkt_props
Properties (timestamps+side data) extracted from the last packet passed for decoding.
Definition: internal.h:84
async_lock
static void async_lock(FrameThreadContext *fctx)
Definition: pthread_frame.c:152
PerThreadContext::pthread_init_cnt
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
Definition: pthread_frame.c:81
PerThreadContext::thread
pthread_t thread
Definition: pthread_frame.c:79
av_cpu_count
int av_cpu_count(void)
Definition: cpu.c:209
attribute_align_arg
#define attribute_align_arg
Definition: internal.h:50
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:563
PerThreadContext::result
int result
The result of the last codec decode/encode() call.
Definition: pthread_frame.c:95
FrameThreadContext::stash_hwaccel
const AVHWAccel * stash_hwaccel
Definition: pthread_frame.c:142
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:85
f
f
Definition: af_crystalizer.c:121
AVCodecContext::flags2
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:528
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1617
AVPacket::size
int size
Definition: packet.h:492
ff_thread_decode_frame
int ff_thread_decode_frame(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt)
Submit a new frame to a decoding thread.
Definition: pthread_frame.c:504
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:185
codec_internal.h
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:124
cpu.h
PerThreadContext::avpkt
AVPacket * avpkt
Input packet (for decoding) or output (for encoding).
Definition: pthread_frame.c:91
async_unlock
static void async_unlock(FrameThreadContext *fctx)
Definition: pthread_frame.c:161
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1080
FrameThreadContext::async_cond
pthread_cond_t async_cond
Definition: pthread_frame.c:128
FF_CODEC_CAP_ALLOCATE_PROGRESS
#define FF_CODEC_CAP_ALLOCATE_PROGRESS
Definition: codec_internal.h:69
ffcodec
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
Definition: codec_internal.h:325
frame.h
buffer.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:490
PerThreadContext::parent
struct FrameThreadContext * parent
Definition: pthread_frame.c:77
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:63
AVCodecContext::skip_loop_filter
enum AVDiscard skip_loop_filter
Skip loop filtering for selected frames.
Definition: avcodec.h:1752
pthread_t
Definition: os2threads.h:44
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1543
STATE_INPUT_READY
@ STATE_INPUT_READY
Set when the thread is awaiting a packet.
Definition: pthread_frame.c:56
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1510
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: avpacket.c:386
PerThreadContext::thread_init
int thread_init
Definition: pthread_frame.c:80
log.h
NEEDS_CLOSE
@ NEEDS_CLOSE
FFCodec->close needs to be called.
Definition: pthread_frame.c:65
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVCodecContext::properties
unsigned properties
Properties of the stream that gets decoded.
Definition: avcodec.h:1904
internal.h
common.h
AVCodecContext::hwaccel_flags
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition: avcodec.h:1990
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:649
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:622
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1486
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
AVCodecContext::chroma_sample_location
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:1046
pthread_cond_t
Definition: os2threads.h:58
AVCodecContext::height
int height
Definition: avcodec.h:621
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:658
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:984
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
STATE_SETUP_FINISHED
@ STATE_SETUP_FINISHED
Set after the codec has called ff_thread_finish_setup().
Definition: pthread_frame.c:60
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1940
avcodec.h
AVCodecContext::frame_num
int64_t frame_num
Frame counter, set by libavcodec.
Definition: avcodec.h:2118
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
ff_frame_thread_init
int ff_frame_thread_init(AVCodecContext *avctx)
Definition: pthread_frame.c:852
ff_decode_internal_alloc
struct AVCodecInternal * ff_decode_internal_alloc(void)
Definition: decode.c:1884
PerThreadContext::async_serializing
int async_serializing
Definition: pthread_frame.c:102
AVCodecContext::opaque
void * opaque
Private data of the user, can be used to carry app specific stuff.
Definition: avcodec.h:483
ff_refstruct_replace
void ff_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
Definition: refstruct.c:156
pthread_cond_signal
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:152
AVCodecContext::draw_horiz_band
void(* draw_horiz_band)(struct AVCodecContext *s, const AVFrame *src, int offset[AV_NUM_DATA_POINTERS], int y, int type, int height)
If non NULL, 'draw_horiz_band' is called by the libavcodec decoder to draw a horizontal band.
Definition: avcodec.h:683
AVCodecContext
main external API structure.
Definition: avcodec.h:441
AVCodecContext::active_thread_type
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1551
PerThreadContext::hwaccel_serializing
int hwaccel_serializing
Definition: pthread_frame.c:101
STATE_SETTING_UP
@ STATE_SETTING_UP
Set before the codec has called ff_thread_finish_setup().
Definition: pthread_frame.c:58
ThreadFrame
Definition: threadframe.h:27
avcodec_internal.h
PerThreadContext::frame
AVFrame * frame
Output frame (for decoding) or input (for encoding).
Definition: pthread_frame.c:93
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1596
ffhwaccel
static const FFHWAccel * ffhwaccel(const AVHWAccel *codec)
Definition: hwaccel_internal.h:166
AVCodecContext::ticks_per_frame
attribute_deprecated int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:579
AVCodecContext::export_side_data
int export_side_data
Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of metadata exported in frame,...
Definition: avcodec.h:2057
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: codec.h:76
FFCodec::close
int(* close)(struct AVCodecContext *)
Definition: codec_internal.h:240
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:104
pthread_cond_wait
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:192
AVCodecContext::debug
int debug
debug
Definition: avcodec.h:1388
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:647
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:636
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FrameThreadContext::delaying
int delaying
Set for the first N packets, where N is the number of threads.
Definition: pthread_frame.c:134
mem.h
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:1885
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:468
AVPacket
This structure stores compressed data.
Definition: packet.h:468
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AVCodecInternal::thread_ctx
void * thread_ctx
Definition: internal.h:67
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:621
AVCodecContext::frame_number
attribute_deprecated int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:1106
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
PerThreadContext::mutex
pthread_mutex_t mutex
Mutex used to protect the contents of the PerThreadContext.
Definition: pthread_frame.c:86
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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:273
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1810
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
FFHWAccel::caps_internal
int caps_internal
Internal hwaccel capabilities.
Definition: hwaccel_internal.h:117
snprintf
#define snprintf
Definition: snprintf.h:34
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1143
ff_refstruct_unref
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:116
AVCodecContext::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition: avcodec.h:822
ThreadFrameProgress::progress
atomic_int progress[2]
Definition: pthread_frame.c:70
FrameThreadContext::stash_hwaccel_priv
void * stash_hwaccel_priv
Definition: pthread_frame.c:144
mutex
static AVMutex mutex
Definition: log.c:46
PerThreadContext::progress_cond
pthread_cond_t progress_cond
Used by child threads to wait for progress to change.
Definition: pthread_frame.c:83
FFHWAccel::update_thread_context
int(* update_thread_context)(AVCodecContext *dst, const AVCodecContext *src)
Copy necessary context variables from a previous thread context to the current one.
Definition: hwaccel_internal.h:150
FrameThreadContext::threads
PerThreadContext * threads
The contexts for each thread.
Definition: pthread_frame.c:117
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:75
ff_thread_setname
static int ff_thread_setname(const char *name)
Definition: thread.h:214