You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	avcodec: remove FF_API_THREAD_SAFE_CALLBACKS
Signed-off-by: James Almer <jamrial@gmail.com> Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
		
				
					committed by
					
						 Anton Khirnov
						Anton Khirnov
					
				
			
			
				
	
			
			
			
						parent
						
							2f9cd88617
						
					
				
				
					commit
					e0786a8eeb
				
			| @@ -2804,11 +2804,6 @@ static int init_input_stream(InputStream *ist, char *error, int error_len) | ||||
|  | ||||
|         ist->dec_ctx->opaque                = ist; | ||||
|         ist->dec_ctx->get_format            = get_format; | ||||
| #if LIBAVCODEC_VERSION_MAJOR < 60 | ||||
|         AV_NOWARN_DEPRECATED({ | ||||
|         ist->dec_ctx->thread_safe_callbacks = 1; | ||||
|         }) | ||||
| #endif | ||||
|  | ||||
|         if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE && | ||||
|            (ist->decoding_needed & DECODING_FOR_OST)) { | ||||
|   | ||||
| @@ -1526,27 +1526,6 @@ typedef struct AVCodecContext { | ||||
|      */ | ||||
|     int active_thread_type; | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|     /** | ||||
|      * Set by the client if its custom get_buffer() callback can be called | ||||
|      * synchronously from another thread, which allows faster multithreaded decoding. | ||||
|      * draw_horiz_band() will be called from other threads regardless of this setting. | ||||
|      * Ignored if the default get_buffer() is used. | ||||
|      * - encoding: Set by user. | ||||
|      * - decoding: Set by user. | ||||
|      * | ||||
|      * @deprecated the custom get_buffer2() callback should always be | ||||
|      *   thread-safe. Thread-unsafe get_buffer2() implementations will be | ||||
|      *   invalid starting with LIBAVCODEC_VERSION_MAJOR=60; in other words, | ||||
|      *   libavcodec will behave as if this field was always set to 1. | ||||
|      *   Callers that want to be forward compatible with future libavcodec | ||||
|      *   versions should wrap access to this field in | ||||
|      *     `#if LIBAVCODEC_VERSION_MAJOR < 60` | ||||
|      */ | ||||
|     attribute_deprecated | ||||
|     int thread_safe_callbacks; | ||||
| #endif | ||||
|  | ||||
|     /** | ||||
|      * The codec may call this to execute several independent things. | ||||
|      * It will return only after finishing all tasks. | ||||
|   | ||||
| @@ -1604,19 +1604,6 @@ int ff_decode_preinit(AVCodecContext *avctx) | ||||
|      * free the already allocated subtitle_header before overwriting it */ | ||||
|     av_freep(&avctx->subtitle_header); | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     if ((avctx->thread_type & FF_THREAD_FRAME) && | ||||
|         avctx->get_buffer2 != avcodec_default_get_buffer2 && | ||||
|         !avctx->thread_safe_callbacks) { | ||||
|         av_log(avctx, AV_LOG_WARNING, "Requested frame threading with a " | ||||
|                "custom get_buffer2() implementation which is not marked as " | ||||
|                "thread safe. This is not supported anymore, make your " | ||||
|                "callback thread-safe.\n"); | ||||
|     } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
|     if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) { | ||||
|         av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n", | ||||
|                avctx->codec->max_lowres); | ||||
|   | ||||
| @@ -259,10 +259,9 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt, | ||||
| unref: | ||||
|         av_packet_unref(avpkt); | ||||
|     } | ||||
| #if !FF_API_THREAD_SAFE_CALLBACKS | ||||
|  | ||||
|     if (frame) | ||||
|         av_frame_unref(frame); | ||||
| #endif | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
| @@ -303,10 +302,6 @@ static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt) | ||||
|         ret = ff_thread_video_encode_frame(avctx, avpkt, frame, &got_packet); | ||||
|     else { | ||||
|         ret = ff_encode_encode_cb(avctx, avpkt, frame, &got_packet); | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|         if (frame) | ||||
|             av_frame_unref(frame); | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     if (avci->draining && !got_packet) | ||||
|   | ||||
| @@ -48,9 +48,6 @@ typedef struct{ | ||||
|  | ||||
| typedef struct{ | ||||
|     AVCodecContext *parent_avctx; | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|     pthread_mutex_t buffer_mutex; | ||||
| #endif | ||||
|  | ||||
|     pthread_mutex_t task_fifo_mutex; /* Used to guard (next_)task_index */ | ||||
|     pthread_cond_t task_fifo_cond; | ||||
| @@ -70,15 +67,9 @@ typedef struct{ | ||||
| } ThreadContext; | ||||
|  | ||||
| #define OFF(member) offsetof(ThreadContext, member) | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| DEFINE_OFFSET_ARRAY(ThreadContext, thread_ctx, pthread_init_cnt, | ||||
|                     (OFF(buffer_mutex), OFF(task_fifo_mutex), OFF(finished_task_mutex)), | ||||
|                     (OFF(task_fifo_cond), OFF(finished_task_cond))); | ||||
| #else | ||||
| DEFINE_OFFSET_ARRAY(ThreadContext, thread_ctx, pthread_init_cnt, | ||||
|                     (OFF(task_fifo_mutex), OFF(finished_task_mutex)), | ||||
|                     (OFF(task_fifo_cond),  OFF(finished_task_cond))); | ||||
| #endif | ||||
| #undef OFF | ||||
|  | ||||
| static void * attribute_align_arg worker(void *v){ | ||||
| @@ -112,11 +103,6 @@ static void * attribute_align_arg worker(void *v){ | ||||
|         pkt   = task->outdata; | ||||
|  | ||||
|         ret = ff_encode_encode_cb(avctx, pkt, frame, &task->got_packet); | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|         pthread_mutex_lock(&c->buffer_mutex); | ||||
|         av_frame_unref(frame); | ||||
|         pthread_mutex_unlock(&c->buffer_mutex); | ||||
| #endif | ||||
|         pthread_mutex_lock(&c->finished_task_mutex); | ||||
|         task->return_code = ret; | ||||
|         task->finished    = 1; | ||||
| @@ -124,13 +110,7 @@ static void * attribute_align_arg worker(void *v){ | ||||
|         pthread_mutex_unlock(&c->finished_task_mutex); | ||||
|     } | ||||
| end: | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|     pthread_mutex_lock(&c->buffer_mutex); | ||||
| #endif | ||||
|     avcodec_close(avctx); | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|     pthread_mutex_unlock(&c->buffer_mutex); | ||||
| #endif | ||||
|     av_freep(&avctx); | ||||
|     return NULL; | ||||
| } | ||||
|   | ||||
| @@ -99,22 +99,6 @@ typedef struct PerThreadContext { | ||||
|  | ||||
|     atomic_int state; | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|     /** | ||||
|      * Array of frames passed to ff_thread_release_buffer(). | ||||
|      * Frames are released after all threads referencing them are finished. | ||||
|      */ | ||||
|     AVFrame **released_buffers; | ||||
|     int   num_released_buffers; | ||||
|     int       released_buffers_allocated; | ||||
|  | ||||
|     AVFrame *requested_frame;       ///< AVFrame the codec passed to get_buffer() | ||||
|     int      requested_flags;       ///< flags passed to get_buffer() for requested_frame | ||||
|  | ||||
|     const enum AVPixelFormat *available_formats; ///< Format array for get_format() | ||||
|     enum AVPixelFormat result_format;            ///< get_format() result | ||||
| #endif | ||||
|  | ||||
|     int die;                        ///< Set when the thread should exit. | ||||
|  | ||||
|     int hwaccel_serializing; | ||||
| @@ -156,11 +140,6 @@ typedef struct FrameThreadContext { | ||||
|     void            *stash_hwaccel_priv; | ||||
| } FrameThreadContext; | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| #define THREAD_SAFE_CALLBACKS(avctx) \ | ||||
| ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2) | ||||
| #endif | ||||
|  | ||||
| static void async_lock(FrameThreadContext *fctx) | ||||
| { | ||||
|     pthread_mutex_lock(&fctx->async_mutex); | ||||
| @@ -212,14 +191,8 @@ static attribute_align_arg void *frame_worker_thread(void *arg) | ||||
|  | ||||
|         if (p->die) break; | ||||
|  | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|         if (!codec->update_thread_context | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|             && THREAD_SAFE_CALLBACKS(avctx) | ||||
| #endif | ||||
|             ) | ||||
|         if (!codec->update_thread_context) | ||||
|             ff_thread_finish_setup(avctx); | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
|  | ||||
|         /* If a decoder supports hwaccel, then it must call ff_get_format(). | ||||
|          * Since that call must happen before ff_thread_finish_setup(), the | ||||
| @@ -394,11 +367,6 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     dst->reordered_opaque = src->reordered_opaque; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     dst->thread_safe_callbacks = src->thread_safe_callbacks; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
|     if (src->slice_count && src->slice_offset) { | ||||
| @@ -421,29 +389,6 @@ FF_ENABLE_DEPRECATION_WARNINGS | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| /// Releases the buffers that this decoding thread was the last user of. | ||||
| static void release_delayed_buffers(PerThreadContext *p) | ||||
| { | ||||
|     FrameThreadContext *fctx = p->parent; | ||||
|  | ||||
|     while (p->num_released_buffers > 0) { | ||||
|         AVFrame *f; | ||||
|  | ||||
|         pthread_mutex_lock(&fctx->buffer_mutex); | ||||
|  | ||||
|         // fix extended data in case the caller screwed it up | ||||
|         av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO || | ||||
|                    p->avctx->codec_type == AVMEDIA_TYPE_AUDIO); | ||||
|         f = p->released_buffers[--p->num_released_buffers]; | ||||
|         f->extended_data = f->data; | ||||
|         av_frame_unref(f); | ||||
|  | ||||
|         pthread_mutex_unlock(&fctx->buffer_mutex); | ||||
|     } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, | ||||
|                          AVPacket *avpkt) | ||||
| { | ||||
| @@ -466,10 +411,6 @@ static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, | ||||
|                           (p->avctx->debug & FF_DEBUG_THREADS) != 0, | ||||
|                           memory_order_relaxed); | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|     release_delayed_buffers(p); | ||||
| #endif | ||||
|  | ||||
|     if (prev_thread) { | ||||
|         int err; | ||||
|         if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) { | ||||
| @@ -504,44 +445,6 @@ static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, | ||||
|     pthread_cond_signal(&p->input_cond); | ||||
|     pthread_mutex_unlock(&p->mutex); | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     /* | ||||
|      * If the client doesn't have a thread-safe get_buffer(), | ||||
|      * then decoding threads call back to the main thread, | ||||
|      * and it calls back to the client here. | ||||
|      */ | ||||
|  | ||||
|     if (!p->avctx->thread_safe_callbacks && ( | ||||
|          p->avctx->get_format != avcodec_default_get_format || | ||||
|          p->avctx->get_buffer2 != avcodec_default_get_buffer2)) { | ||||
|         while (atomic_load(&p->state) != STATE_SETUP_FINISHED && atomic_load(&p->state) != STATE_INPUT_READY) { | ||||
|             int call_done = 1; | ||||
|             pthread_mutex_lock(&p->progress_mutex); | ||||
|             while (atomic_load(&p->state) == STATE_SETTING_UP) | ||||
|                 pthread_cond_wait(&p->progress_cond, &p->progress_mutex); | ||||
|  | ||||
|             switch (atomic_load_explicit(&p->state, memory_order_acquire)) { | ||||
|             case STATE_GET_BUFFER: | ||||
|                 p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); | ||||
|                 break; | ||||
|             case STATE_GET_FORMAT: | ||||
|                 p->result_format = ff_get_format(p->avctx, p->available_formats); | ||||
|                 break; | ||||
|             default: | ||||
|                 call_done = 0; | ||||
|                 break; | ||||
|             } | ||||
|             if (call_done) { | ||||
|                 atomic_store(&p->state, STATE_SETTING_UP); | ||||
|                 pthread_cond_signal(&p->progress_cond); | ||||
|             } | ||||
|             pthread_mutex_unlock(&p->progress_mutex); | ||||
|         } | ||||
|     } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
|     fctx->prev_thread = p; | ||||
|     fctx->next_decoding++; | ||||
|  | ||||
| @@ -772,12 +675,6 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) | ||||
|             if (codec->close && p->thread_init != UNINITIALIZED) | ||||
|                 codec->close(ctx); | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|             release_delayed_buffers(p); | ||||
|             for (int j = 0; j < p->released_buffers_allocated; j++) | ||||
|                 av_frame_free(&p->released_buffers[j]); | ||||
|             av_freep(&p->released_buffers); | ||||
| #endif | ||||
|             if (ctx->priv_data) { | ||||
|                 if (codec->p.priv_class) | ||||
|                     av_opt_free(ctx->priv_data); | ||||
| @@ -975,10 +872,6 @@ void ff_thread_flush(AVCodecContext *avctx) | ||||
|         av_frame_unref(p->frame); | ||||
|         p->result = 0; | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|         release_delayed_buffers(p); | ||||
| #endif | ||||
|  | ||||
|         if (ffcodec(avctx->codec)->flush) | ||||
|             ffcodec(avctx->codec)->flush(p->avctx); | ||||
|     } | ||||
| @@ -987,16 +880,12 @@ void ff_thread_flush(AVCodecContext *avctx) | ||||
| int ff_thread_can_start_frame(AVCodecContext *avctx) | ||||
| { | ||||
|     PerThreadContext *p = avctx->internal->thread_ctx; | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|  | ||||
|     if ((avctx->active_thread_type&FF_THREAD_FRAME) && atomic_load(&p->state) != STATE_SETTING_UP && | ||||
|         (ffcodec(avctx->codec)->update_thread_context | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|          || !THREAD_SAFE_CALLBACKS(avctx) | ||||
| #endif | ||||
|          )) { | ||||
|         ffcodec(avctx->codec)->update_thread_context) { | ||||
|         return 0; | ||||
|     } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
|  | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| @@ -1011,80 +900,20 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, AVFrame *f, int fla | ||||
|     p = avctx->internal->thread_ctx; | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     if (atomic_load(&p->state) != STATE_SETTING_UP && | ||||
|         (ffcodec(avctx->codec)->update_thread_context | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
|          || !THREAD_SAFE_CALLBACKS(avctx) | ||||
| #endif | ||||
|          )) { | ||||
|         ffcodec(avctx->codec)->update_thread_context) { | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
|         av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     pthread_mutex_lock(&p->parent->buffer_mutex); | ||||
| #if !FF_API_THREAD_SAFE_CALLBACKS | ||||
|     err = ff_get_buffer(avctx, f, flags); | ||||
| #else | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     if (THREAD_SAFE_CALLBACKS(avctx)) { | ||||
|         err = ff_get_buffer(avctx, f, flags); | ||||
|     } else { | ||||
|         pthread_mutex_lock(&p->progress_mutex); | ||||
|         p->requested_frame = f; | ||||
|         p->requested_flags = flags; | ||||
|         atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release); | ||||
|         pthread_cond_broadcast(&p->progress_cond); | ||||
|  | ||||
|         while (atomic_load(&p->state) != STATE_SETTING_UP) | ||||
|             pthread_cond_wait(&p->progress_cond, &p->progress_mutex); | ||||
|  | ||||
|         err = p->result; | ||||
|  | ||||
|         pthread_mutex_unlock(&p->progress_mutex); | ||||
|  | ||||
|     } | ||||
|     if (!THREAD_SAFE_CALLBACKS(avctx) && !ffcodec(avctx->codec)->update_thread_context) | ||||
|         ff_thread_finish_setup(avctx); | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
|     pthread_mutex_unlock(&p->parent->buffer_mutex); | ||||
|  | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
| enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) | ||||
| { | ||||
|     enum AVPixelFormat res; | ||||
|     PerThreadContext *p; | ||||
|     if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks || | ||||
|         avctx->get_format == avcodec_default_get_format) | ||||
|         return ff_get_format(avctx, fmt); | ||||
|  | ||||
|     p = avctx->internal->thread_ctx; | ||||
|     if (atomic_load(&p->state) != STATE_SETTING_UP) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n"); | ||||
|         return -1; | ||||
|     } | ||||
|     pthread_mutex_lock(&p->progress_mutex); | ||||
|     p->available_formats = fmt; | ||||
|     atomic_store(&p->state, STATE_GET_FORMAT); | ||||
|     pthread_cond_broadcast(&p->progress_cond); | ||||
|  | ||||
|     while (atomic_load(&p->state) != STATE_SETTING_UP) | ||||
|         pthread_cond_wait(&p->progress_cond, &p->progress_mutex); | ||||
|  | ||||
|     res = p->result_format; | ||||
|  | ||||
|     pthread_mutex_unlock(&p->progress_mutex); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
| int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags) | ||||
| { | ||||
|     int ret = thread_get_buffer_internal(avctx, f, flags); | ||||
| @@ -1126,69 +955,13 @@ int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) | ||||
|  | ||||
| void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) | ||||
| { | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     PerThreadContext *p; | ||||
|     FrameThreadContext *fctx; | ||||
|     AVFrame *dst; | ||||
|     int ret = 0; | ||||
|     int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) || | ||||
|                           THREAD_SAFE_CALLBACKS(avctx); | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
|     if (!f) | ||||
|         return; | ||||
|  | ||||
|     if (avctx->debug & FF_DEBUG_BUFFERS) | ||||
|         av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f); | ||||
|  | ||||
| #if !FF_API_THREAD_SAFE_CALLBACKS | ||||
|     av_frame_unref(f); | ||||
| #else | ||||
|     // when the frame buffers are not allocated, just reset it to clean state | ||||
|     if (can_direct_free || !f->buf[0]) { | ||||
|         av_frame_unref(f); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     p    = avctx->internal->thread_ctx; | ||||
|     fctx = p->parent; | ||||
|     pthread_mutex_lock(&fctx->buffer_mutex); | ||||
|  | ||||
|     if (p->num_released_buffers == p->released_buffers_allocated) { | ||||
|         AVFrame **tmp = av_realloc_array(p->released_buffers, p->released_buffers_allocated + 1, | ||||
|                                          sizeof(*p->released_buffers)); | ||||
|         if (tmp) { | ||||
|             tmp[p->released_buffers_allocated] = av_frame_alloc(); | ||||
|             p->released_buffers = tmp; | ||||
|         } | ||||
|  | ||||
|         if (!tmp || !tmp[p->released_buffers_allocated]) { | ||||
|             ret = AVERROR(ENOMEM); | ||||
|             goto fail; | ||||
|         } | ||||
|         p->released_buffers_allocated++; | ||||
|     } | ||||
|  | ||||
|     dst = p->released_buffers[p->num_released_buffers]; | ||||
|     av_frame_move_ref(dst, f); | ||||
|  | ||||
|     p->num_released_buffers++; | ||||
|  | ||||
| fail: | ||||
|     pthread_mutex_unlock(&fctx->buffer_mutex); | ||||
|  | ||||
|     // make sure the frame is clean even if we fail to free it | ||||
|     // this leaks, but it is better than crashing | ||||
|     if (ret < 0) { | ||||
|         av_log(avctx, AV_LOG_ERROR, "Could not queue a frame for freeing, this will leak\n"); | ||||
|         memset(f->buf, 0, sizeof(f->buf)); | ||||
|         if (f->extended_buf) | ||||
|             memset(f->extended_buf, 0, f->nb_extended_buf * sizeof(*f->extended_buf)); | ||||
|         av_frame_unref(f); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f) | ||||
|   | ||||
| @@ -62,19 +62,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, AVFrame *picture, | ||||
|  */ | ||||
| void ff_thread_finish_setup(AVCodecContext *avctx); | ||||
|  | ||||
| #if FF_API_THREAD_SAFE_CALLBACKS | ||||
| /** | ||||
|  * Wrapper around get_format() for frame-multithreaded codecs. | ||||
|  * Call this function instead of avctx->get_format(). | ||||
|  * Cannot be called after the codec has called ff_thread_finish_setup(). | ||||
|  * | ||||
|  * @param avctx The current context. | ||||
|  * @param fmt The list of available formats. | ||||
|  */ | ||||
| enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt); | ||||
| #else | ||||
| #define ff_thread_get_format ff_get_format | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Wrapper around get_buffer() for frame-multithreaded codecs. | ||||
|   | ||||
| @@ -913,11 +913,6 @@ int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src) | ||||
|  | ||||
| #if !HAVE_THREADS | ||||
|  | ||||
| enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) | ||||
| { | ||||
|     return ff_get_format(avctx, fmt); | ||||
| } | ||||
|  | ||||
| int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags) | ||||
| { | ||||
|     return ff_get_buffer(avctx, f, flags); | ||||
|   | ||||
| @@ -37,7 +37,6 @@ | ||||
|  * at once through the bump. This improves the git bisect-ability of the change. | ||||
|  */ | ||||
|  | ||||
| #define FF_API_THREAD_SAFE_CALLBACKS (LIBAVCODEC_VERSION_MAJOR < 60) | ||||
| #define FF_API_DEBUG_MV          (LIBAVCODEC_VERSION_MAJOR < 60) | ||||
| #define FF_API_GET_FRAME_CLASS     (LIBAVCODEC_VERSION_MAJOR < 60) | ||||
| #define FF_API_AUTO_THREADS        (LIBAVCODEC_VERSION_MAJOR < 60) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user