添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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 */
19 /**
20 * @file
21 * Frame multithreading support functions
22 * @see doc/multithreading.txt
23 */
25 #include <stdatomic.h>
27 #include " avcodec.h "
28 #include " avcodec_internal.h "
29 #include " codec_desc.h "
30 #include " codec_internal.h "
31 #include " decode.h "
32 #include " hwaccel_internal.h "
33 #include " hwconfig.h "
34 #include " internal.h "
35 #include " packet_internal.h "
36 #include " pthread_internal.h "
37 #include " refstruct.h "
38 #include " thread.h "
39 #include " threadframe.h "
40 #include " version_major.h "
43 #include " libavutil/buffer.h "
44 #include " libavutil/common.h "
45 #include " libavutil/cpu.h "
46 #include " libavutil/frame.h "
48 #include " libavutil/log.h "
49 #include " libavutil/mem.h "
50 #include " libavutil/opt.h "
51 #include " libavutil/thread.h "
53 enum {
54 /// Set when the thread is awaiting a packet.
56 /// Set before the codec has called ff_thread_finish_setup().
58 /// Set after the codec has called ff_thread_finish_setup().
60 };
62 enum {
63 UNINITIALIZED , ///< Thread has not been created, AVCodec->close mustn't be called
64 NEEDS_CLOSE , ///< FFCodec->close needs to be called
65 INITIALIZED , ///< Thread has been properly set up
66 };
68 typedef struct DecodedFrames {
78 /**
79 * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
80 */
84 pthread_t thread ;
86 unsigned pthread_init_cnt ; ///< Number of successfully initialized mutexes/conditions
87 pthread_cond_t input_cond ; ///< Used to wait for a new packet from the main thread.
88 pthread_cond_t progress_cond ; ///< Used by child threads to wait for progress to change.
89 pthread_cond_t output_cond ; ///< Used by the main thread to wait for frames to finish.
91 pthread_mutex_t mutex ; ///< Mutex used to protect the contents of the PerThreadContext.
92 pthread_mutex_t progress_mutex ; ///< Mutex used to protect frame progress values and progress_cond.
94 AVCodecContext * avctx ; ///< Context used to decode packets passed to this thread.
96 AVPacket * avpkt ; ///< Input packet (for decoding) or output (for encoding).
98 /**
99 * Decoded frames from a single decode iteration.
100 */
102 int result ; ///< The result of the last codec decode/encode() call.
106 int die ; ///< Set when the thread should exit.
111 // set to 1 in ff_thread_finish_setup() when a threadsafe hwaccel is used;
112 // cannot check hwaccel caps directly, because
113 // worked threads clear hwaccel state for thread-unsafe hwaccels
114 // after each decode call
117 atomic_int debug_threads ; ///< Set if the FF_DEBUG_THREADS option is set.
119 /// The following two fields have the same semantics as the DecodeContext field
124 /**
125 * Context stored in the client AVCodecInternal thread_ctx.
126 */
128 PerThreadContext * threads ; ///< The contexts for each thread.
129 PerThreadContext * prev_thread ; ///< The last thread submit_packet() was called on.
131 unsigned pthread_init_cnt ; ///< Number of successfully initialized mutexes/conditions
132 pthread_mutex_t buffer_mutex ; ///< Mutex used to protect get/release_buffer().
133 /**
134 * This lock is used for ensuring threads run in serial when thread-unsafe
135 * hwaccel is used.
136 */
145 /**
146 * Packet to be submitted to the next thread for decoding.
147 */
150 int next_decoding ; ///< The next context to submit a packet to.
151 int next_finished ; ///< The next context to return output from.
153 /* hwaccel state for thread-unsafe hwaccels is temporarily stored here in
154 * order to transfer its ownership to the next decoding thread without the
155 * need for extra synchronization */
162 {
164 }
167 {
169 while (fctx-> async_lock )
171 fctx-> async_lock = 1;
173 }
176 {
179 fctx-> async_lock = 0;
182 }
185 {
186 AVCodecContext *avctx = p-> avctx ;
187 int idx = p - p-> parent -> threads ;
188 char name [16];
190 snprintf ( name , sizeof ( name ), "av:%.7s:df%d" , avctx-> codec -> name , idx);
193 }
195 // get a free frame to decode into
197 {
198 if ( df ->nb_f == df ->nb_f_allocated) {
200 sizeof (* df ->f));
201 if (! tmp )
202 return NULL ;
203 df ->f = tmp ;
205 df ->f[ df ->nb_f] = av_frame_alloc ();
206 if (! df ->f[ df ->nb_f])
207 return NULL ;
209 df ->nb_f_allocated++;
210 }
212 av_assert0 (! df ->f[ df ->nb_f]->buf[0]);
214 return df ->f[ df ->nb_f];
215 }
218 {
219 AVFrame *tmp_frame = df ->f[0];
220 av_frame_move_ref (dst, tmp_frame);
221 memmove( df ->f, df ->f + 1, ( df ->nb_f - 1) * sizeof (* df ->f));
222 df ->f[-- df ->nb_f] = tmp_frame;
223 }
226 {
227 for ( size_t i = 0; i < df ->nb_f; i ++)
229 df ->nb_f = 0;
230 }
233 {
234 for ( size_t i = 0; i < df ->nb_f_allocated; i ++)
236 av_freep (& df ->f);
237 df ->nb_f = 0;
238 df ->nb_f_allocated = 0;
239 }
241 /**
242 * Codec worker thread.
243 *
244 * Automatically calls ff_thread_finish_setup() if the codec does
245 * not provide an update_thread_context method, or if the codec returns
246 * before calling it.
247 */
249 {
251 AVCodecContext *avctx = p-> avctx ;
252 const FFCodec *codec = ffcodec (avctx-> codec );
257 while (1) {
258 int ret ;
263 if (p-> die ) break ;
265 if (!codec-> update_thread_context )
268 /* If a decoder supports hwaccel, then it must call ff_get_format().
269 * Since that call must happen before ff_thread_finish_setup(), the
270 * decoder is required to implement update_thread_context() and call
271 * ff_thread_finish_setup() manually. Therefore the above
272 * ff_thread_finish_setup() call did not happen and hwaccel_serializing
273 * cannot be true here. */
276 /* if the previous thread uses thread-unsafe hwaccel then we take the
277 * lock to ensure the threads don't run concurrently */
278 if ( hwaccel_serial (avctx)) {
281 }
283 ret = 0;
284 while ( ret >= 0) {
287 /* get the frame which will store the output */
289 if (! frame ) {
290 p-> result = AVERROR (ENOMEM);
291 goto alloc_fail;
292 }
294 /* do the actual decoding */
296 if ( ret == 0)
297 p-> df . nb_f ++;
298 else if (ret < 0 && frame->buf[0])
301 p-> result = ( ret == AVERROR (EAGAIN)) ? 0 : ret ;
302 }
307 alloc_fail:
308 if (p-> hwaccel_serializing ) {
309 /* wipe hwaccel state for thread-unsafe hwaccels to avoid stale
310 * pointers lying around;
311 * the state was transferred to FrameThreadContext in
312 * ff_thread_finish_setup(), so nothing is leaked */
313 avctx-> hwaccel = NULL ;
319 }
320 av_assert0 (!avctx-> hwaccel ||
323 if (p-> async_serializing ) {
327 }
336 }
339 return NULL ;
340 }
342 /**
343 * Update the next thread's AVCodecContext with values from the reference thread's context.
344 *
345 * @param dst The destination context.
346 * @param src The source context.
347 * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
348 * @return 0 on success, negative error code on failure
349 */
351 {
352 const FFCodec * const codec = ffcodec (dst-> codec );
353 int err = 0;
355 if (dst != src && (for_user || codec-> update_thread_context )) {
356 dst-> time_base = src ->time_base;
357 dst-> framerate = src ->framerate;
358 dst-> width = src ->width;
359 dst-> height = src ->height;
360 dst-> pix_fmt = src ->pix_fmt;
361 dst-> sw_pix_fmt = src ->sw_pix_fmt;
363 dst-> coded_width = src ->coded_width;
364 dst-> coded_height = src ->coded_height;
366 dst-> has_b_frames = src ->has_b_frames;
367 dst-> idct_algo = src ->idct_algo;
368 dst-> properties = src ->properties;
370 dst-> bits_per_coded_sample = src ->bits_per_coded_sample;
371 dst-> sample_aspect_ratio = src ->sample_aspect_ratio;
373 dst-> profile = src ->profile;
374 dst-> level = src ->level;
376 dst-> bits_per_raw_sample = src ->bits_per_raw_sample;
377 #if FF_API_TICKS_PER_FRAME
379 dst-> ticks_per_frame = src ->ticks_per_frame;
381 #endif
382 dst-> color_primaries = src ->color_primaries;
384 dst-> color_trc = src ->color_trc;
385 dst-> colorspace = src ->colorspace;
386 dst-> color_range = src ->color_range;
387 dst-> chroma_sample_location = src ->chroma_sample_location;
389 dst-> sample_rate = src ->sample_rate;
390 dst-> sample_fmt = src ->sample_fmt;
391 err = av_channel_layout_copy (&dst-> ch_layout , & src ->ch_layout);
392 if (err < 0)
393 return err;
395 if (!!dst-> hw_frames_ctx != !! src ->hw_frames_ctx ||
396 (dst-> hw_frames_ctx && dst-> hw_frames_ctx -> data != src ->hw_frames_ctx->data)) {
399 if ( src ->hw_frames_ctx) {
400 dst-> hw_frames_ctx = av_buffer_ref ( src ->hw_frames_ctx);
401 if (!dst-> hw_frames_ctx )
402 return AVERROR (ENOMEM);
403 }
404 }
406 dst-> hwaccel_flags = src ->hwaccel_flags;
408 ff_refstruct_replace (&dst-> internal -> pool , src ->internal->pool);
409 }
411 if (for_user) {
414 } else {
415 const PerThreadContext *p_src = src ->internal->thread_ctx;
418 if (codec-> update_thread_context ) {
419 err = codec-> update_thread_context (dst, src );
420 if (err < 0)
421 return err;
422 }
424 // reset dst hwaccel state if needed
426 (!dst-> hwaccel && !dst-> internal -> hwaccel_priv_data ));
427 if (p_dst-> hwaccel_threadsafe &&
428 (!p_src-> hwaccel_threadsafe || dst-> hwaccel != src ->hwaccel)) {
430 p_dst-> hwaccel_threadsafe = 0;
431 }
433 // propagate hwaccel state for threadsafe hwaccels
434 if (p_src-> hwaccel_threadsafe ) {
436 if (!dst-> hwaccel ) {
437 if ( hwaccel ->priv_data_size) {
438 av_assert0 ( hwaccel ->update_thread_context);
441 av_mallocz ( hwaccel ->priv_data_size);
443 return AVERROR (ENOMEM);
444 }
445 dst-> hwaccel = src ->hwaccel;
446 }
447 av_assert0 (dst-> hwaccel == src ->hwaccel);
449 if ( hwaccel ->update_thread_context) {
450 err = hwaccel ->update_thread_context(dst, src );
451 if (err < 0) {
452 av_log (dst, AV_LOG_ERROR , "Error propagating hwaccel state\n" );
454 return err;
455 }
456 }
457 p_dst-> hwaccel_threadsafe = 1;
458 }
459 }
461 return err;
462 }
464 /**
465 * Update the next thread's AVCodecContext with values set by the user.
466 *
467 * @param dst The destination context.
468 * @param src The source context.
469 * @return 0 on success, negative error code on failure
470 */
472 {
473 int err;
475 dst-> flags = src ->flags;
477 dst-> draw_horiz_band = src ->draw_horiz_band;
478 dst-> get_buffer2 = src ->get_buffer2;
480 dst-> opaque = src ->opaque;
481 dst-> debug = src ->debug;
483 dst-> slice_flags = src ->slice_flags;
484 dst-> flags2 = src ->flags2;
485 dst-> export_side_data = src ->export_side_data;
487 dst-> skip_loop_filter = src ->skip_loop_filter;
488 dst-> skip_idct = src ->skip_idct;
489 dst-> skip_frame = src ->skip_frame;
491 dst-> frame_num = src ->frame_num;
494 err = av_packet_copy_props (dst-> internal -> last_pkt_props , src ->internal->last_pkt_props);
495 if (err < 0)
496 return err;
498 return 0;
499 }
502 AVPacket *in_pkt)
503 {
505 PerThreadContext *prev_thread = fctx-> prev_thread ;
506 const AVCodec *codec = p-> avctx -> codec ;
507 int ret ;
518 if ( ret ) {
520 return ret ;
521 }
523 (p-> avctx -> debug & FF_DEBUG_THREADS ) != 0,
524 memory_order_relaxed);
526 if (prev_thread) {
527 if ( atomic_load (&prev_thread-> state ) == STATE_SETTING_UP ) {
529 while ( atomic_load (&prev_thread-> state ) == STATE_SETTING_UP )
530 pthread_cond_wait (&prev_thread-> progress_cond , &prev_thread-> progress_mutex );
532 }
534 /* codecs without delay might not be prepared to be called repeatedly here during
535 * flushing (vp3/theora), and also don't need to be, since from this point on, they
536 * will always return EOF anyway */
537 if (!p-> avctx -> internal -> draining ||
540 if ( ret ) {
542 return ret ;
543 }
544 }
545 }
547 /* transfer the stashed hwaccel state, if any */
549 if (!p-> hwaccel_threadsafe ) {
553 }
559 fctx-> prev_thread = p;
562 return 0;
563 }
566 {
568 int ret = 0;
570 /* release the async lock, permitting blocked hwaccel threads to
571 * go forward while we are in this function */
572 async_unlock (fctx);
574 /* submit packets to threads while there are no buffered results to return */
575 while (!fctx-> df . nb_f && !fctx-> result ) {
578 /* get a packet to be submitted to the next thread */
581 if ( ret < 0 && ret != AVERROR_EOF )
582 goto finish ;
585 fctx-> next_pkt );
586 if ( ret < 0)
587 goto finish ;
589 /* do not return any frames until all threads have something to do */
590 if (fctx-> next_decoding != fctx-> next_finished &&
591 !avctx-> internal -> draining )
592 continue ;
594 p = &fctx-> threads [fctx-> next_finished ];
595 fctx-> next_finished = (fctx-> next_finished + 1) % avctx-> thread_count ;
599 while ( atomic_load_explicit (&p-> state , memory_order_relaxed) != STATE_INPUT_READY )
602 }
605 fctx-> result = p-> result ;
606 p-> result = 0;
607 if (p-> df . nb_f )
609 }
611 /* a thread may return multiple frames AND an error
612 * we first return all the frames, then the error */
613 if (fctx-> df . nb_f ) {
615 ret = 0;
616 } else {
617 ret = fctx-> result ;
618 fctx-> result = 0;
619 }
622 async_lock (fctx);
623 return ret ;
624 }
627 {
629 atomic_int *progress = f ->progress ? f ->progress->progress : NULL ;
631 if (!progress ||
632 atomic_load_explicit (&progress[ field ], memory_order_relaxed) >= n)
633 return ;
635 p = f ->owner[ field ]->internal->thread_ctx;
637 if ( atomic_load_explicit (&p-> debug_threads , memory_order_relaxed))
639 "%p finished %d field %d\n" , progress, n, field );
643 atomic_store_explicit (&progress[ field ], n, memory_order_release);
647 }
650 {
652 atomic_int *progress = f ->progress ? f ->progress->progress : NULL ;
654 if (!progress ||
655 atomic_load_explicit (&progress[ field ], memory_order_acquire) >= n)
656 return ;
658 p = f ->owner[ field ]->internal->thread_ctx;
660 if ( atomic_load_explicit (&p-> debug_threads , memory_order_relaxed))
661 av_log ( f ->owner[ field ], AV_LOG_DEBUG ,
662 "thread awaiting %d field %d from %p\n" , n, field , progress);
665 while ( atomic_load_explicit (&progress[ field ], memory_order_relaxed) < n)
668 }
673 if (!(avctx-> active_thread_type & FF_THREAD_FRAME )) return ;
675 p = avctx-> internal -> thread_ctx ;
680 if ( hwaccel_serial (avctx) && !p-> hwaccel_serializing ) {
683 }
685 /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */
686 if (avctx-> hwaccel &&
691 }
693 /* thread-unsafe hwaccels share a single private data instance, so we
694 * save hwaccel state for passing to the next thread;
695 * this is done here so that this worker thread can wipe its own hwaccel
696 * state after decoding, without requiring synchronization */
698 if ( hwaccel_serial (avctx)) {
702 }
706 av_log (avctx, AV_LOG_WARNING , "Multiple ff_thread_finish_setup() calls\n" );
707 }
713 }
715 /// Waits for all threads to finish.
716 static void park_frame_worker_threads ( FrameThreadContext *fctx, int thread_count)
717 {
718 int i ;
720 async_unlock (fctx);
722 for ( i = 0; i < thread_count; i ++) {
729 pthread_mutex_unlock (&p-> progress_mutex );
730 }
731 }
733 async_lock (fctx);
734 }
736 #define OFF(member) offsetof(FrameThreadContext, member)
737 DEFINE_OFFSET_ARRAY ( FrameThreadContext , thread_ctx, pthread_init_cnt,
738 ( OFF (buffer_mutex), OFF (hwaccel_mutex), OFF (async_mutex)),
739 ( OFF (async_cond)));
740 #undef OFF
742 #define OFF(member) offsetof(PerThreadContext, member)
743 DEFINE_OFFSET_ARRAY ( PerThreadContext , per_thread, pthread_init_cnt,
744 ( OFF (progress_mutex), OFF ( mutex )),
745 ( OFF (input_cond), OFF (progress_cond), OFF (output_cond)));
746 #undef OFF
748 void ff_frame_thread_free ( AVCodecContext *avctx, int thread_count)
749 {
751 const FFCodec *codec = ffcodec (avctx-> codec );
752 int i ;
754 park_frame_worker_threads (fctx, thread_count);
756 for ( i = 0; i < thread_count; i ++) {
760 if ( ctx ->internal) {
763 p-> die = 1;
768 }
769 if (codec-> close && p-> thread_init != UNINITIALIZED )
770 codec-> close ( ctx );
772 /* When using a threadsafe hwaccel, this is where
773 * each thread's context is uninit'd and freed. */
776 if ( ctx -> priv_data ) {
777 if (codec-> p . priv_class )
780 }
782 ff_refstruct_unref (& ctx ->internal->pool);
783 av_packet_free (& ctx ->internal->in_pkt);
784 av_packet_free (& ctx ->internal->last_pkt_props);
785 av_freep (& ctx ->internal);
786 av_buffer_unref (& ctx ->hw_frames_ctx);
787 av_frame_side_data_free (& ctx ->decoded_side_data,
788 & ctx ->nb_decoded_side_data);
789 }
793 ff_pthread_free (p, per_thread_offsets);
797 }
802 av_freep (&fctx-> threads );
803 ff_pthread_free (fctx, thread_ctx_offsets);
805 /* if we have stashed hwaccel state, move it to the user-facing context,
806 * so it will be freed in ff_codec_close() */
807 av_assert0 (!avctx-> hwaccel );
808 FFSWAP ( const AVHWAccel *, avctx-> hwaccel , fctx-> stash_hwaccel );
813 }
815 static av_cold int init_thread ( PerThreadContext *p, int *threads_to_free,
817 const FFCodec *codec, int first )
818 {
820 int err;
827 }
831 copy = av_memdup (avctx, sizeof (*avctx));
832 if (! copy )
833 return AVERROR (ENOMEM);
834 copy ->priv_data = NULL ;
835 copy ->decoded_side_data = NULL ;
836 copy ->nb_decoded_side_data = 0;
838 /* From now on, this PerThreadContext will be cleaned up by
839 * ff_frame_thread_free in case of errors. */
840 (*threads_to_free)++;
842 p-> parent = fctx;
843 p-> avctx = copy ;
846 if (! copy ->internal)
847 return AVERROR (ENOMEM);
848 copy ->internal->thread_ctx = p;
849 copy ->internal->progress_frame_pool = avctx-> internal -> progress_frame_pool ;
851 copy ->delay = avctx-> delay ;
853 if (codec-> priv_data_size ) {
854 copy ->priv_data = av_mallocz (codec-> priv_data_size );
855 if (! copy ->priv_data)
856 return AVERROR (ENOMEM);
858 if (codec-> p . priv_class ) {
859 *( const AVClass **) copy ->priv_data = codec-> p . priv_class ;
860 err = av_opt_copy ( copy ->priv_data, avctx-> priv_data );
861 if (err < 0)
862 return err;
863 }
864 }
866 err = ff_pthread_init (p, per_thread_offsets);
867 if (err < 0)
868 return err;
870 if (!(p-> avpkt = av_packet_alloc ()))
871 return AVERROR (ENOMEM);
873 copy ->internal->is_frame_mt = 1;
874 if (! first )
875 copy ->internal->is_copy = 1;
877 copy ->internal->in_pkt = av_packet_alloc ();
878 if (! copy ->internal->in_pkt)
879 return AVERROR (ENOMEM);
881 copy ->internal->last_pkt_props = av_packet_alloc ();
882 if (! copy ->internal->last_pkt_props)
883 return AVERROR (ENOMEM);
885 if (codec-> init ) {
886 err = codec-> init ( copy );
887 if (err < 0) {
890 return err;
891 }
892 }
895 if ( first ) {
899 for ( int i = 0; i < copy ->nb_decoded_side_data; i ++) {
902 copy ->decoded_side_data[ i ], 0);
903 if (err < 0)
904 return err;
905 }
906 }
911 if (err < 0)
912 return err;
915 return 0;
916 }
919 {
920 int thread_count = avctx-> thread_count ;
921 const FFCodec *codec = ffcodec (avctx-> codec );
923 int err, i = 0;
925 if (!thread_count) {
926 int nb_cpus = av_cpu_count ();
927 // use number of cores + 1 as thread count if there is more than one
928 if (nb_cpus > 1)
929 thread_count = avctx-> thread_count = FFMIN (nb_cpus + 1, MAX_AUTO_THREADS );
930 else
931 thread_count = avctx-> thread_count = 1;
932 }
934 if (thread_count <= 1) {
935 avctx-> active_thread_type = 0;
936 return 0;
937 }
940 if (!fctx)
941 return AVERROR (ENOMEM);
943 err = ff_pthread_init (fctx, thread_ctx_offsets);
944 if (err < 0) {
945 ff_pthread_free (fctx, thread_ctx_offsets);
947 return err;
948 }
951 if (!fctx-> next_pkt )
952 return AVERROR (ENOMEM);
954 fctx-> async_lock = 1;
956 if (codec-> p . type == AVMEDIA_TYPE_VIDEO )
957 avctx-> delay = avctx-> thread_count - 1;
959 fctx-> threads = av_calloc (thread_count, sizeof (*fctx-> threads ));
960 if (!fctx-> threads ) {
961 err = AVERROR (ENOMEM);
962 goto error ;
963 }
965 for (; i < thread_count; ) {
967 int first = ! i ;
969 err = init_thread (p, & i , fctx, avctx, codec, first );
970 if (err < 0)
971 goto error ;
972 }
974 return 0;
978 return err;
979 }
982 {
983 int i ;
986 if (!fctx) return ;
989 if (fctx-> prev_thread ) {
990 if (fctx-> prev_thread != &fctx-> threads [0])
992 }
994 fctx-> next_decoding = fctx-> next_finished = 0;
998 fctx-> result = 0;
1000 for ( i = 0; i < avctx-> thread_count ; i ++) {
1004 p-> result = 0;
1007 }
1008 }
1011 {
1017 return 0;
1018 }
1020 return 1;
1021 }
1024 {
1026 int err;
1029 return ff_get_buffer (avctx, f , flags );
1031 p = avctx-> internal -> thread_ctx ;
1034 av_log (avctx, AV_LOG_ERROR , "get_buffer() cannot be called after ff_thread_finish_setup()\n" );
1035 return -1;
1036 }
1039 err = ff_get_buffer (avctx, f , flags );
1043 return err;
1044 }
1047 {
1049 if ( ret < 0)
1050 av_log (avctx, AV_LOG_ERROR , "thread_get_buffer() failed\n" );
1051 return ret ;
1052 }
1055 {
1056 int ret ;
1058 f ->owner[0] = f ->owner[1] = avctx;
1060 return ff_get_buffer (avctx, f ->f, flags );
1062 f ->progress = ff_refstruct_allocz ( sizeof (* f ->progress));
1063 if (! f ->progress)
1064 return AVERROR (ENOMEM);
1066 atomic_init (& f ->progress->progress[0], -1);
1067 atomic_init (& f ->progress->progress[1], -1);
1070 if ( ret )
1071 ff_refstruct_unref (& f ->progress);
1072 return ret ;
1073 }
1076 {
1077 ff_refstruct_unref (& f ->progress);
1078 f ->owner[0] = f ->owner[1] = NULL ;
1079 if ( f ->f)
1081 }
1084 {
1086 const void * ref ;
1088 if (!avctx-> internal -> is_copy )
1092 p = avctx-> internal -> thread_ctx ;
1094 av_assert1 (memcpy(& ref , ( char *)avctx-> priv_data + offset , sizeof ( ref )) && ref == NULL );
1096 memcpy(& ref , ( const char *)p-> parent -> threads [0]. avctx -> priv_data + offset , sizeof ( ref ));
1098 ff_refstruct_replace (( char *)avctx-> priv_data + offset , ref );
1101 }
1104 {
1107 if (! AVPACKET_IS_EMPTY (p-> avpkt )) {
1109 return 0;
1110 }
1112 return avctx-> internal -> draining ? AVERROR_EOF : AVERROR (EAGAIN);
1113 }
static void error(const char *err)
_fmutex pthread_mutex_t
Definition: os2threads.h:53
int(* update_thread_context)(struct AVCodecContext *dst, const struct AVCodecContext *src)
Copy necessary context variables from a previous thread context to the current one.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:428
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1431
AVCodec.
Definition: codec.h:187
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
static void thread_set_name(PerThreadContext *p)
void * hwaccel_context
Legacy hardware accelerator context.
Definition: avcodec.h:1455
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
Definition: os2threads.h:94
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition: decode.c:240
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
pthread_cond_t input_cond
Used to wait for a new packet from the main thread.
#define atomic_store(object, desired)
Definition: stdatomic.h:85
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
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
enum AVPictureType initial_pict_type
static int hwaccel_serial(const AVCodecContext *avctx)
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:685
AVFrameSideData ** decoded_side_data
Array containing static side data, such as HDR10 CLL / MDCV structures.
Definition: avcodec.h:2081
int sample_rate
samples per second
Definition: avcodec.h:1050
atomic_int debug_threads
Set if the FF_DEBUG_THREADS option is set.
#define df(A, B)
Definition: vf_xbr.c:91
const AVClass * priv_class
AVClass for the private context.
Definition: codec.h:212
int next_decoding
The next context to submit a packet to.
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
void ff_thread_flush(AVCodecContext *avctx)
Wait for decoding threads to finish and reset internal state.
static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, FrameThreadContext *fctx, AVCodecContext *avctx, const FFCodec *codec, int first)
int ff_thread_can_start_frame(AVCodecContext *avctx)
static void decoded_frames_free(DecodedFrames *df)
AVPictureType
Definition: avutil.h:277
const struct AVCodecDescriptor * codec_descriptor
AVCodecDescriptor.
Definition: avcodec.h:1866
#define MAX_AUTO_THREADS
@ FF_THREAD_IS_FIRST_THREAD
Definition: thread.h:66
Context stored in the client AVCodecInternal thread_ctx.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
Waits for all threads to finish.
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
static uint8_t tmp[11]
Definition: aes_ctr.c:28
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:678
int capabilities
Codec capabilities.
Definition: codec.h:206
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.
intptr_t atomic_int
Definition: stdatomic.h:55
AVPacket * next_pkt
Packet to be submitted to the next thread for decoding.
int ff_thread_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Submit available packets for decoding to worker threads, return a decoded frame if available.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
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: frame.c:874
int delay
Codec delay.
Definition: avcodec.h:601
int die
Set when the thread should exit.
av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
Definition: pthread.c:92
int next_finished
The next context to return output from.
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
@ STATE_INPUT_READY
Set when the thread is awaiting a packet.
pthread_mutex_t buffer_mutex
Mutex used to protect get/release_buffer().
void ff_hwaccel_uninit(AVCodecContext *avctx)
Definition: decode.c:1253
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
int priv_data_size
Definition: codec_internal.h:144
AVRational framerate
Definition: avcodec.h:560
int is_copy
When using frame-threaded decoding, this field is set for the first worker thread (e....
Definition: internal.h:54
struct FFRefStructPool * progress_frame_pool
Definition: internal.h:71
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
enum AVDiscard skip_idct
Skip IDCT/dequantization for selected frames.
Definition: avcodec.h:1817
AVCodec p
The public AVCodec.
static void finish(void)
Definition: movenc.c:373
const struct AVCodec * codec
Definition: avcodec.h:454
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:1065
enum AVDiscard skip_frame
Skip decoding for selected frames.
Definition: avcodec.h:1824
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1587
static int update_context_from_user(AVCodecContext *dst, const AVCodecContext *src)
Update the next thread's AVCodecContext with values set by the user.
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1914
#define HWACCEL_CAP_THREAD_SAFE
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:502
Context used by codec threads and stored in their AVCodecInternal thread_ctx.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:148
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:1226
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:671
AVPacket * pkt
Definition: movenc.c:60
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
#define av_cold
Definition: attributes.h:90
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:625
void ff_thread_report_progress(ThreadFrame *f, int n, int field)
Notify later decoding threads when part of their reference picture is ready.
int(* update_thread_context_for_user)(struct AVCodecContext *dst, const struct AVCodecContext *src)
Copy variables back to the user-facing context.
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:723
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
struct FramePool * pool
Definition: internal.h:69
int nb_decoded_side_data
Definition: avcodec.h:2082
pthread_cond_t output_cond
Used by the main thread to wait for frames to finish.
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1579
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AVFormatContext * ctx
Definition: movenc.c:49
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
#define atomic_load(object)
Definition: stdatomic.h:93
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
Definition: os2threads.h:162
PerThreadContext * prev_thread
The last thread submit_packet() was called on.
int(* init)(struct AVCodecContext *)
const char * arg
Definition: jacosubdec.c:67
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
int props
Codec properties, a combination of AV_CODEC_PROP_* flags.
Definition: codec_desc.h:54
if(ret)
#define AV_CODEC_PROP_INTRA_ONLY
Codec uses only intra compression.
Definition: codec_desc.h:72
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Describe the class of an AVClass context structure.
Definition: log.h:66
#define NULL
Definition: coverity.c:32
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:695
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
@ UNINITIALIZED
Thread has not been created, AVCodec->close mustn't be called.
void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
int slice_flags
slice flags
Definition: avcodec.h:730
static int thread_get_buffer_internal(AVCodecContext *avctx, AVFrame *f, int flags)
enum AVMediaType type
Definition: codec.h:200
static attribute_align_arg void * frame_worker_thread(void *arg)
Codec worker thread.
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:480
pthread_mutex_t progress_mutex
Mutex used to protect frame progress values and progress_cond.
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
pthread_mutex_t async_mutex
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...
void ff_thread_release_ext_buffer(ThreadFrame *f)
Unref a ThreadFrame.
pthread_mutex_t hwaccel_mutex
This lock is used for ensuring threads run in serial when thread-unsafe hwaccel is used.
AVCodecContext * avctx
Context used to decode packets passed to this thread.
static void * ff_refstruct_allocz(size_t size)
Equivalent to ff_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
@ FF_THREAD_IS_COPY
Definition: thread.h:65
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: packet.c:485
#define AVPACKET_IS_EMPTY(pkt)
int level
Encoding level descriptor.
Definition: avcodec.h:1788
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:96
#define FF_DEBUG_THREADS
Definition: avcodec.h:1413
#define OFF(member)
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:82
AVPacket * last_pkt_props
Properties (timestamps+side data) extracted from the last packet passed for decoding.
Definition: internal.h:90
DecodedFrames df
Decoded frames from a single decode iteration.
static void async_lock(FrameThreadContext *fctx)
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c:2114
unsigned pthread_init_cnt
Number of successfully initialized mutexes/conditions.
int av_cpu_count(void)
Definition: cpu.c:209
#define attribute_align_arg
Definition: internal.h:50
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:544
int result
The result of the last codec decode/encode() call.
const AVHWAccel * stash_hwaccel
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:509
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1599
static void copy(const float *p1, float *p2, const int length)
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:130
int intra_only_flag
The following two fields have the same semantics as the DecodeContext field.
AVPacket * avpkt
Input packet (for decoding) or output (for encoding).
static void async_unlock(FrameThreadContext *fctx)
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1057
pthread_cond_t async_cond
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
static void decoded_frames_pop(DecodedFrames *df, AVFrame *dst)
@ AV_PICTURE_TYPE_NONE
Undefined.
Definition: avutil.h:278
struct FrameThreadContext * parent
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
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:63
enum AVDiscard skip_loop_filter
Skip loop filtering for selected frames.
Definition: avcodec.h:1810
@ FF_THREAD_NO_FRAME_THREADING
Definition: thread.h:67
int ff_thread_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Get a packet for decoding.
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:613
@ STATE_SETUP_FINISHED
Set after the codec has called ff_thread_finish_setup().
static void decoded_frames_flush(DecodedFrames *df)
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1598
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1572
unsigned caps_internal
Internal codec capabilities FF_CODEC_CAP_*.
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
Copy only "properties" fields from src to dst.
Definition: packet.c:391
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
unsigned properties
Properties of the stream that gets decoded.
Definition: avcodec.h:1800
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: frame.c:111
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition: avcodec.h:1510
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
#define atomic_store_explicit(object, desired, order)
Definition: stdatomic.h:90
#define FFMIN(a, b)
Definition: macros.h:49
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition: frame.c:635
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:608
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1552
const char * name
Name of the codec implementation.
Definition: codec.h:194
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:702
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:657
int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around ff_get_buffer() for frame-multithreaded codecs.
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
@ NEEDS_CLOSE
FFCodec->close needs to be called.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1479
int64_t frame_num
Frame counter, set by libavcodec.
Definition: avcodec.h:2035
DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, pthread_init_cnt,(OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),(OFF(async_cond)))
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
void avcodec_flush_buffers(AVCodecContext *avctx)
Reset the internal codec state / flush internal buffers.
Definition: avcodec.c:364
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
int ff_frame_thread_init(AVCodecContext *avctx)
struct AVCodecInternal * ff_decode_internal_alloc(void)
Definition: decode.c:2182
static AVFrame * decoded_frames_get_free(DecodedFrames *df)
void * opaque
Private data of the user, can be used to carry app specific stuff.
Definition: avcodec.h:487
static const char * hwaccel
Definition: ffplay.c:353
void ff_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
Definition: refstruct.c:160
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:152
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:758
main external API structure.
Definition: avcodec.h:445
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1606
int profile
profile
Definition: avcodec.h:1644
static const FFHWAccel * ffhwaccel(const AVHWAccel *codec)
static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, AVPacket *in_pkt)
static int ref[MAX_W *MAX_W]
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:576
int export_side_data
Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of metadata exported in frame,...
Definition: avcodec.h:1931
#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
int(* close)(struct AVCodecContext *)
@ INITIALIZED
Thread has been properly set up.
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
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:192
int debug
debug
Definition: avcodec.h:1400
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
int draining
decoding: AVERROR_EOF has been returned from ff_decode_get_packet(); must not be used by decoders tha...
Definition: internal.h:139
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:633
enum AVMediaType codec_type
Definition: avcodec.h:453
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
ThreadingStatus
Definition: thread.h:64
void * priv_data
Definition: avcodec.h:472
This structure stores compressed data.
Definition: packet.h:510
#define av_freep(p)
INIT_CLIP pixel * src
int width
picture width / height.
Definition: avcodec.h:618
#define flags(name, subs,...)
Definition: cbs_av1.c:482
pthread_mutex_t mutex
Mutex used to protect the contents of the PerThreadContext.
#define av_log(a,...)
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.
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:664
#define atomic_init(obj, value)
Definition: stdatomic.h:33
@ STATE_SETTING_UP
Set before the codec has called ff_thread_finish_setup().
int caps_internal
Internal hwaccel capabilities.
#define snprintf
Definition: snprintf.h:34
void * priv_data
Format private data.
Definition: avformat.h:1288
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:120
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:642
atomic_int progress[2]
static AVMutex mutex
Definition: log.c:46
pthread_cond_t progress_cond
Used by child threads to wait for progress to change.
PerThreadContext * threads
The contexts for each thread.
#define pthread_mutex_lock(a)
Definition: ffprobe.c:78
static int ff_thread_setname(const char *name)
Definition: thread.h:216