annotate ffmpeg/libavcodec/pthread.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2004 Roman Shaposhnik
yading@10 3 * Copyright (c) 2008 Alexander Strange (astrange@ithinksw.com)
yading@10 4 *
yading@10 5 * Many thanks to Steven M. Schultz for providing clever ideas and
yading@10 6 * to Michael Niedermayer <michaelni@gmx.at> for writing initial
yading@10 7 * implementation.
yading@10 8 *
yading@10 9 * This file is part of FFmpeg.
yading@10 10 *
yading@10 11 * FFmpeg is free software; you can redistribute it and/or
yading@10 12 * modify it under the terms of the GNU Lesser General Public
yading@10 13 * License as published by the Free Software Foundation; either
yading@10 14 * version 2.1 of the License, or (at your option) any later version.
yading@10 15 *
yading@10 16 * FFmpeg is distributed in the hope that it will be useful,
yading@10 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 19 * Lesser General Public License for more details.
yading@10 20 *
yading@10 21 * You should have received a copy of the GNU Lesser General Public
yading@10 22 * License along with FFmpeg; if not, write to the Free Software
yading@10 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 24 */
yading@10 25
yading@10 26 /**
yading@10 27 * @file
yading@10 28 * Multithreading support functions
yading@10 29 * @see doc/multithreading.txt
yading@10 30 */
yading@10 31
yading@10 32 #include "config.h"
yading@10 33
yading@10 34 #if HAVE_SCHED_GETAFFINITY
yading@10 35 #ifndef _GNU_SOURCE
yading@10 36 # define _GNU_SOURCE
yading@10 37 #endif
yading@10 38 #include <sched.h>
yading@10 39 #endif
yading@10 40 #if HAVE_GETPROCESSAFFINITYMASK
yading@10 41 #include <windows.h>
yading@10 42 #endif
yading@10 43 #if HAVE_SYSCTL
yading@10 44 #if HAVE_SYS_PARAM_H
yading@10 45 #include <sys/param.h>
yading@10 46 #endif
yading@10 47 #include <sys/types.h>
yading@10 48 #include <sys/param.h>
yading@10 49 #include <sys/sysctl.h>
yading@10 50 #endif
yading@10 51 #if HAVE_SYSCONF
yading@10 52 #include <unistd.h>
yading@10 53 #endif
yading@10 54
yading@10 55 #include "avcodec.h"
yading@10 56 #include "internal.h"
yading@10 57 #include "thread.h"
yading@10 58 #include "libavutil/avassert.h"
yading@10 59 #include "libavutil/common.h"
yading@10 60
yading@10 61 #if HAVE_PTHREADS
yading@10 62 #include <pthread.h>
yading@10 63 #elif HAVE_W32THREADS
yading@10 64 #include "w32pthreads.h"
yading@10 65 #elif HAVE_OS2THREADS
yading@10 66 #include "os2threads.h"
yading@10 67 #endif
yading@10 68
yading@10 69 typedef int (action_func)(AVCodecContext *c, void *arg);
yading@10 70 typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
yading@10 71
yading@10 72 typedef struct ThreadContext {
yading@10 73 pthread_t *workers;
yading@10 74 action_func *func;
yading@10 75 action_func2 *func2;
yading@10 76 void *args;
yading@10 77 int *rets;
yading@10 78 int rets_count;
yading@10 79 int job_count;
yading@10 80 int job_size;
yading@10 81
yading@10 82 pthread_cond_t last_job_cond;
yading@10 83 pthread_cond_t current_job_cond;
yading@10 84 pthread_mutex_t current_job_lock;
yading@10 85 int current_job;
yading@10 86 unsigned int current_execute;
yading@10 87 int done;
yading@10 88 } ThreadContext;
yading@10 89
yading@10 90 /**
yading@10 91 * Context used by codec threads and stored in their AVCodecContext thread_opaque.
yading@10 92 */
yading@10 93 typedef struct PerThreadContext {
yading@10 94 struct FrameThreadContext *parent;
yading@10 95
yading@10 96 pthread_t thread;
yading@10 97 int thread_init;
yading@10 98 pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread.
yading@10 99 pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change.
yading@10 100 pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish.
yading@10 101
yading@10 102 pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext.
yading@10 103 pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
yading@10 104
yading@10 105 AVCodecContext *avctx; ///< Context used to decode packets passed to this thread.
yading@10 106
yading@10 107 AVPacket avpkt; ///< Input packet (for decoding) or output (for encoding).
yading@10 108 uint8_t *buf; ///< backup storage for packet data when the input packet is not refcounted
yading@10 109 int allocated_buf_size; ///< Size allocated for buf
yading@10 110
yading@10 111 AVFrame frame; ///< Output frame (for decoding) or input (for encoding).
yading@10 112 int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
yading@10 113 int result; ///< The result of the last codec decode/encode() call.
yading@10 114
yading@10 115 enum {
yading@10 116 STATE_INPUT_READY, ///< Set when the thread is awaiting a packet.
yading@10 117 STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup().
yading@10 118 STATE_GET_BUFFER, /**<
yading@10 119 * Set when the codec calls get_buffer().
yading@10 120 * State is returned to STATE_SETTING_UP afterwards.
yading@10 121 */
yading@10 122 STATE_GET_FORMAT, /**<
yading@10 123 * Set when the codec calls get_format().
yading@10 124 * State is returned to STATE_SETTING_UP afterwards.
yading@10 125 */
yading@10 126 STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup().
yading@10 127 } state;
yading@10 128
yading@10 129 /**
yading@10 130 * Array of frames passed to ff_thread_release_buffer().
yading@10 131 * Frames are released after all threads referencing them are finished.
yading@10 132 */
yading@10 133 AVFrame *released_buffers;
yading@10 134 int num_released_buffers;
yading@10 135 int released_buffers_allocated;
yading@10 136
yading@10 137 AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
yading@10 138 int requested_flags; ///< flags passed to get_buffer() for requested_frame
yading@10 139
yading@10 140 const enum AVPixelFormat *available_formats; ///< Format array for get_format()
yading@10 141 enum AVPixelFormat result_format; ///< get_format() result
yading@10 142 } PerThreadContext;
yading@10 143
yading@10 144 /**
yading@10 145 * Context stored in the client AVCodecContext thread_opaque.
yading@10 146 */
yading@10 147 typedef struct FrameThreadContext {
yading@10 148 PerThreadContext *threads; ///< The contexts for each thread.
yading@10 149 PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
yading@10 150
yading@10 151 pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
yading@10 152
yading@10 153 int next_decoding; ///< The next context to submit a packet to.
yading@10 154 int next_finished; ///< The next context to return output from.
yading@10 155
yading@10 156 int delaying; /**<
yading@10 157 * Set for the first N packets, where N is the number of threads.
yading@10 158 * While it is set, ff_thread_en/decode_frame won't return any results.
yading@10 159 */
yading@10 160
yading@10 161 int die; ///< Set when threads should exit.
yading@10 162 } FrameThreadContext;
yading@10 163
yading@10 164
yading@10 165 /* H264 slice threading seems to be buggy with more than 16 threads,
yading@10 166 * limit the number of threads to 16 for automatic detection */
yading@10 167 #define MAX_AUTO_THREADS 16
yading@10 168
yading@10 169 int ff_get_logical_cpus(AVCodecContext *avctx)
yading@10 170 {
yading@10 171 int ret, nb_cpus = 1;
yading@10 172 #if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
yading@10 173 cpu_set_t cpuset;
yading@10 174
yading@10 175 CPU_ZERO(&cpuset);
yading@10 176
yading@10 177 ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);
yading@10 178 if (!ret) {
yading@10 179 nb_cpus = CPU_COUNT(&cpuset);
yading@10 180 }
yading@10 181 #elif HAVE_GETPROCESSAFFINITYMASK
yading@10 182 DWORD_PTR proc_aff, sys_aff;
yading@10 183 ret = GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff);
yading@10 184 if (ret)
yading@10 185 nb_cpus = av_popcount64(proc_aff);
yading@10 186 #elif HAVE_SYSCTL && defined(HW_NCPU)
yading@10 187 int mib[2] = { CTL_HW, HW_NCPU };
yading@10 188 size_t len = sizeof(nb_cpus);
yading@10 189
yading@10 190 ret = sysctl(mib, 2, &nb_cpus, &len, NULL, 0);
yading@10 191 if (ret == -1)
yading@10 192 nb_cpus = 0;
yading@10 193 #elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
yading@10 194 nb_cpus = sysconf(_SC_NPROC_ONLN);
yading@10 195 #elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
yading@10 196 nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
yading@10 197 #endif
yading@10 198 av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
yading@10 199
yading@10 200 if (avctx->height)
yading@10 201 nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);
yading@10 202
yading@10 203 return nb_cpus;
yading@10 204 }
yading@10 205
yading@10 206
yading@10 207 static void* attribute_align_arg worker(void *v)
yading@10 208 {
yading@10 209 AVCodecContext *avctx = v;
yading@10 210 ThreadContext *c = avctx->thread_opaque;
yading@10 211 int our_job = c->job_count;
yading@10 212 int last_execute = 0;
yading@10 213 int thread_count = avctx->thread_count;
yading@10 214 int self_id;
yading@10 215
yading@10 216 pthread_mutex_lock(&c->current_job_lock);
yading@10 217 self_id = c->current_job++;
yading@10 218 for (;;){
yading@10 219 while (our_job >= c->job_count) {
yading@10 220 if (c->current_job == thread_count + c->job_count)
yading@10 221 pthread_cond_signal(&c->last_job_cond);
yading@10 222
yading@10 223 while (last_execute == c->current_execute && !c->done)
yading@10 224 pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
yading@10 225 last_execute = c->current_execute;
yading@10 226 our_job = self_id;
yading@10 227
yading@10 228 if (c->done) {
yading@10 229 pthread_mutex_unlock(&c->current_job_lock);
yading@10 230 return NULL;
yading@10 231 }
yading@10 232 }
yading@10 233 pthread_mutex_unlock(&c->current_job_lock);
yading@10 234
yading@10 235 c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size):
yading@10 236 c->func2(avctx, c->args, our_job, self_id);
yading@10 237
yading@10 238 pthread_mutex_lock(&c->current_job_lock);
yading@10 239 our_job = c->current_job++;
yading@10 240 }
yading@10 241 }
yading@10 242
yading@10 243 static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count)
yading@10 244 {
yading@10 245 while (c->current_job != thread_count + c->job_count)
yading@10 246 pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
yading@10 247 pthread_mutex_unlock(&c->current_job_lock);
yading@10 248 }
yading@10 249
yading@10 250 static void thread_free(AVCodecContext *avctx)
yading@10 251 {
yading@10 252 ThreadContext *c = avctx->thread_opaque;
yading@10 253 int i;
yading@10 254
yading@10 255 pthread_mutex_lock(&c->current_job_lock);
yading@10 256 c->done = 1;
yading@10 257 pthread_cond_broadcast(&c->current_job_cond);
yading@10 258 pthread_mutex_unlock(&c->current_job_lock);
yading@10 259
yading@10 260 for (i=0; i<avctx->thread_count; i++)
yading@10 261 pthread_join(c->workers[i], NULL);
yading@10 262
yading@10 263 pthread_mutex_destroy(&c->current_job_lock);
yading@10 264 pthread_cond_destroy(&c->current_job_cond);
yading@10 265 pthread_cond_destroy(&c->last_job_cond);
yading@10 266 av_free(c->workers);
yading@10 267 av_freep(&avctx->thread_opaque);
yading@10 268 }
yading@10 269
yading@10 270 static int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)
yading@10 271 {
yading@10 272 ThreadContext *c= avctx->thread_opaque;
yading@10 273 int dummy_ret;
yading@10 274
yading@10 275 if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1)
yading@10 276 return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size);
yading@10 277
yading@10 278 if (job_count <= 0)
yading@10 279 return 0;
yading@10 280
yading@10 281 pthread_mutex_lock(&c->current_job_lock);
yading@10 282
yading@10 283 c->current_job = avctx->thread_count;
yading@10 284 c->job_count = job_count;
yading@10 285 c->job_size = job_size;
yading@10 286 c->args = arg;
yading@10 287 c->func = func;
yading@10 288 if (ret) {
yading@10 289 c->rets = ret;
yading@10 290 c->rets_count = job_count;
yading@10 291 } else {
yading@10 292 c->rets = &dummy_ret;
yading@10 293 c->rets_count = 1;
yading@10 294 }
yading@10 295 c->current_execute++;
yading@10 296 pthread_cond_broadcast(&c->current_job_cond);
yading@10 297
yading@10 298 avcodec_thread_park_workers(c, avctx->thread_count);
yading@10 299
yading@10 300 return 0;
yading@10 301 }
yading@10 302
yading@10 303 static int avcodec_thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count)
yading@10 304 {
yading@10 305 ThreadContext *c= avctx->thread_opaque;
yading@10 306 c->func2 = func2;
yading@10 307 return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0);
yading@10 308 }
yading@10 309
yading@10 310 static int thread_init(AVCodecContext *avctx)
yading@10 311 {
yading@10 312 int i;
yading@10 313 ThreadContext *c;
yading@10 314 int thread_count = avctx->thread_count;
yading@10 315
yading@10 316 if (!thread_count) {
yading@10 317 int nb_cpus = ff_get_logical_cpus(avctx);
yading@10 318 // use number of cores + 1 as thread count if there is more than one
yading@10 319 if (nb_cpus > 1)
yading@10 320 thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
yading@10 321 else
yading@10 322 thread_count = avctx->thread_count = 1;
yading@10 323 }
yading@10 324
yading@10 325 if (thread_count <= 1) {
yading@10 326 avctx->active_thread_type = 0;
yading@10 327 return 0;
yading@10 328 }
yading@10 329
yading@10 330 c = av_mallocz(sizeof(ThreadContext));
yading@10 331 if (!c)
yading@10 332 return -1;
yading@10 333
yading@10 334 c->workers = av_mallocz(sizeof(pthread_t)*thread_count);
yading@10 335 if (!c->workers) {
yading@10 336 av_free(c);
yading@10 337 return -1;
yading@10 338 }
yading@10 339
yading@10 340 avctx->thread_opaque = c;
yading@10 341 c->current_job = 0;
yading@10 342 c->job_count = 0;
yading@10 343 c->job_size = 0;
yading@10 344 c->done = 0;
yading@10 345 pthread_cond_init(&c->current_job_cond, NULL);
yading@10 346 pthread_cond_init(&c->last_job_cond, NULL);
yading@10 347 pthread_mutex_init(&c->current_job_lock, NULL);
yading@10 348 pthread_mutex_lock(&c->current_job_lock);
yading@10 349 for (i=0; i<thread_count; i++) {
yading@10 350 if(pthread_create(&c->workers[i], NULL, worker, avctx)) {
yading@10 351 avctx->thread_count = i;
yading@10 352 pthread_mutex_unlock(&c->current_job_lock);
yading@10 353 ff_thread_free(avctx);
yading@10 354 return -1;
yading@10 355 }
yading@10 356 }
yading@10 357
yading@10 358 avcodec_thread_park_workers(c, thread_count);
yading@10 359
yading@10 360 avctx->execute = avcodec_thread_execute;
yading@10 361 avctx->execute2 = avcodec_thread_execute2;
yading@10 362 return 0;
yading@10 363 }
yading@10 364
yading@10 365 /**
yading@10 366 * Codec worker thread.
yading@10 367 *
yading@10 368 * Automatically calls ff_thread_finish_setup() if the codec does
yading@10 369 * not provide an update_thread_context method, or if the codec returns
yading@10 370 * before calling it.
yading@10 371 */
yading@10 372 static attribute_align_arg void *frame_worker_thread(void *arg)
yading@10 373 {
yading@10 374 PerThreadContext *p = arg;
yading@10 375 FrameThreadContext *fctx = p->parent;
yading@10 376 AVCodecContext *avctx = p->avctx;
yading@10 377 const AVCodec *codec = avctx->codec;
yading@10 378
yading@10 379 pthread_mutex_lock(&p->mutex);
yading@10 380 while (1) {
yading@10 381 while (p->state == STATE_INPUT_READY && !fctx->die)
yading@10 382 pthread_cond_wait(&p->input_cond, &p->mutex);
yading@10 383
yading@10 384 if (fctx->die) break;
yading@10 385
yading@10 386 if (!codec->update_thread_context && (avctx->thread_safe_callbacks || (
yading@10 387 #if FF_API_GET_BUFFER
yading@10 388 !avctx->get_buffer &&
yading@10 389 #endif
yading@10 390 avctx->get_buffer2 == avcodec_default_get_buffer2)))
yading@10 391 ff_thread_finish_setup(avctx);
yading@10 392
yading@10 393 avcodec_get_frame_defaults(&p->frame);
yading@10 394 p->got_frame = 0;
yading@10 395 p->result = codec->decode(avctx, &p->frame, &p->got_frame, &p->avpkt);
yading@10 396
yading@10 397 /* many decoders assign whole AVFrames, thus overwriting extended_data;
yading@10 398 * make sure it's set correctly */
yading@10 399 p->frame.extended_data = p->frame.data;
yading@10 400
yading@10 401 if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
yading@10 402
yading@10 403 pthread_mutex_lock(&p->progress_mutex);
yading@10 404 #if 0 //BUFREF-FIXME
yading@10 405 for (i = 0; i < MAX_BUFFERS; i++)
yading@10 406 if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) {
yading@10 407 p->progress[i][0] = INT_MAX;
yading@10 408 p->progress[i][1] = INT_MAX;
yading@10 409 }
yading@10 410 #endif
yading@10 411 p->state = STATE_INPUT_READY;
yading@10 412
yading@10 413 pthread_cond_broadcast(&p->progress_cond);
yading@10 414 pthread_cond_signal(&p->output_cond);
yading@10 415 pthread_mutex_unlock(&p->progress_mutex);
yading@10 416 }
yading@10 417 pthread_mutex_unlock(&p->mutex);
yading@10 418
yading@10 419 return NULL;
yading@10 420 }
yading@10 421
yading@10 422 /**
yading@10 423 * Update the next thread's AVCodecContext with values from the reference thread's context.
yading@10 424 *
yading@10 425 * @param dst The destination context.
yading@10 426 * @param src The source context.
yading@10 427 * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
yading@10 428 */
yading@10 429 static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user)
yading@10 430 {
yading@10 431 int err = 0;
yading@10 432
yading@10 433 if (dst != src) {
yading@10 434 dst->time_base = src->time_base;
yading@10 435 dst->width = src->width;
yading@10 436 dst->height = src->height;
yading@10 437 dst->pix_fmt = src->pix_fmt;
yading@10 438
yading@10 439 dst->coded_width = src->coded_width;
yading@10 440 dst->coded_height = src->coded_height;
yading@10 441
yading@10 442 dst->has_b_frames = src->has_b_frames;
yading@10 443 dst->idct_algo = src->idct_algo;
yading@10 444
yading@10 445 dst->bits_per_coded_sample = src->bits_per_coded_sample;
yading@10 446 dst->sample_aspect_ratio = src->sample_aspect_ratio;
yading@10 447 dst->dtg_active_format = src->dtg_active_format;
yading@10 448
yading@10 449 dst->profile = src->profile;
yading@10 450 dst->level = src->level;
yading@10 451
yading@10 452 dst->bits_per_raw_sample = src->bits_per_raw_sample;
yading@10 453 dst->ticks_per_frame = src->ticks_per_frame;
yading@10 454 dst->color_primaries = src->color_primaries;
yading@10 455
yading@10 456 dst->color_trc = src->color_trc;
yading@10 457 dst->colorspace = src->colorspace;
yading@10 458 dst->color_range = src->color_range;
yading@10 459 dst->chroma_sample_location = src->chroma_sample_location;
yading@10 460
yading@10 461 dst->hwaccel = src->hwaccel;
yading@10 462 dst->hwaccel_context = src->hwaccel_context;
yading@10 463 }
yading@10 464
yading@10 465 if (for_user) {
yading@10 466 dst->delay = src->thread_count - 1;
yading@10 467 dst->coded_frame = src->coded_frame;
yading@10 468 } else {
yading@10 469 if (dst->codec->update_thread_context)
yading@10 470 err = dst->codec->update_thread_context(dst, src);
yading@10 471 }
yading@10 472
yading@10 473 return err;
yading@10 474 }
yading@10 475
yading@10 476 /**
yading@10 477 * Update the next thread's AVCodecContext with values set by the user.
yading@10 478 *
yading@10 479 * @param dst The destination context.
yading@10 480 * @param src The source context.
yading@10 481 * @return 0 on success, negative error code on failure
yading@10 482 */
yading@10 483 static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
yading@10 484 {
yading@10 485 #define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s);
yading@10 486 dst->flags = src->flags;
yading@10 487
yading@10 488 dst->draw_horiz_band= src->draw_horiz_band;
yading@10 489 dst->get_buffer2 = src->get_buffer2;
yading@10 490 #if FF_API_GET_BUFFER
yading@10 491 dst->get_buffer = src->get_buffer;
yading@10 492 dst->release_buffer = src->release_buffer;
yading@10 493 #endif
yading@10 494
yading@10 495 dst->opaque = src->opaque;
yading@10 496 dst->debug = src->debug;
yading@10 497 dst->debug_mv = src->debug_mv;
yading@10 498
yading@10 499 dst->slice_flags = src->slice_flags;
yading@10 500 dst->flags2 = src->flags2;
yading@10 501
yading@10 502 copy_fields(skip_loop_filter, subtitle_header);
yading@10 503
yading@10 504 dst->frame_number = src->frame_number;
yading@10 505 dst->reordered_opaque = src->reordered_opaque;
yading@10 506 dst->thread_safe_callbacks = src->thread_safe_callbacks;
yading@10 507
yading@10 508 if (src->slice_count && src->slice_offset) {
yading@10 509 if (dst->slice_count < src->slice_count) {
yading@10 510 int *tmp = av_realloc(dst->slice_offset, src->slice_count *
yading@10 511 sizeof(*dst->slice_offset));
yading@10 512 if (!tmp) {
yading@10 513 av_free(dst->slice_offset);
yading@10 514 return AVERROR(ENOMEM);
yading@10 515 }
yading@10 516 dst->slice_offset = tmp;
yading@10 517 }
yading@10 518 memcpy(dst->slice_offset, src->slice_offset,
yading@10 519 src->slice_count * sizeof(*dst->slice_offset));
yading@10 520 }
yading@10 521 dst->slice_count = src->slice_count;
yading@10 522 return 0;
yading@10 523 #undef copy_fields
yading@10 524 }
yading@10 525
yading@10 526 /// Releases the buffers that this decoding thread was the last user of.
yading@10 527 static void release_delayed_buffers(PerThreadContext *p)
yading@10 528 {
yading@10 529 FrameThreadContext *fctx = p->parent;
yading@10 530
yading@10 531 while (p->num_released_buffers > 0) {
yading@10 532 AVFrame *f;
yading@10 533
yading@10 534 pthread_mutex_lock(&fctx->buffer_mutex);
yading@10 535
yading@10 536 // fix extended data in case the caller screwed it up
yading@10 537 av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO);
yading@10 538 f = &p->released_buffers[--p->num_released_buffers];
yading@10 539 f->extended_data = f->data;
yading@10 540 av_frame_unref(f);
yading@10 541
yading@10 542 pthread_mutex_unlock(&fctx->buffer_mutex);
yading@10 543 }
yading@10 544 }
yading@10 545
yading@10 546 static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
yading@10 547 {
yading@10 548 FrameThreadContext *fctx = p->parent;
yading@10 549 PerThreadContext *prev_thread = fctx->prev_thread;
yading@10 550 const AVCodec *codec = p->avctx->codec;
yading@10 551
yading@10 552 if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0;
yading@10 553
yading@10 554 pthread_mutex_lock(&p->mutex);
yading@10 555
yading@10 556 release_delayed_buffers(p);
yading@10 557
yading@10 558 if (prev_thread) {
yading@10 559 int err;
yading@10 560 if (prev_thread->state == STATE_SETTING_UP) {
yading@10 561 pthread_mutex_lock(&prev_thread->progress_mutex);
yading@10 562 while (prev_thread->state == STATE_SETTING_UP)
yading@10 563 pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
yading@10 564 pthread_mutex_unlock(&prev_thread->progress_mutex);
yading@10 565 }
yading@10 566
yading@10 567 err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
yading@10 568 if (err) {
yading@10 569 pthread_mutex_unlock(&p->mutex);
yading@10 570 return err;
yading@10 571 }
yading@10 572 }
yading@10 573
yading@10 574 av_buffer_unref(&p->avpkt.buf);
yading@10 575 p->avpkt = *avpkt;
yading@10 576 if (avpkt->buf)
yading@10 577 p->avpkt.buf = av_buffer_ref(avpkt->buf);
yading@10 578 else {
yading@10 579 av_fast_malloc(&p->buf, &p->allocated_buf_size, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 580 p->avpkt.data = p->buf;
yading@10 581 memcpy(p->buf, avpkt->data, avpkt->size);
yading@10 582 memset(p->buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 583 }
yading@10 584
yading@10 585 p->state = STATE_SETTING_UP;
yading@10 586 pthread_cond_signal(&p->input_cond);
yading@10 587 pthread_mutex_unlock(&p->mutex);
yading@10 588
yading@10 589 /*
yading@10 590 * If the client doesn't have a thread-safe get_buffer(),
yading@10 591 * then decoding threads call back to the main thread,
yading@10 592 * and it calls back to the client here.
yading@10 593 */
yading@10 594
yading@10 595 if (!p->avctx->thread_safe_callbacks && (
yading@10 596 p->avctx->get_format != avcodec_default_get_format ||
yading@10 597 #if FF_API_GET_BUFFER
yading@10 598 p->avctx->get_buffer ||
yading@10 599 #endif
yading@10 600 p->avctx->get_buffer2 != avcodec_default_get_buffer2)) {
yading@10 601 while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) {
yading@10 602 int call_done = 1;
yading@10 603 pthread_mutex_lock(&p->progress_mutex);
yading@10 604 while (p->state == STATE_SETTING_UP)
yading@10 605 pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
yading@10 606
yading@10 607 switch (p->state) {
yading@10 608 case STATE_GET_BUFFER:
yading@10 609 p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags);
yading@10 610 break;
yading@10 611 case STATE_GET_FORMAT:
yading@10 612 p->result_format = p->avctx->get_format(p->avctx, p->available_formats);
yading@10 613 break;
yading@10 614 default:
yading@10 615 call_done = 0;
yading@10 616 break;
yading@10 617 }
yading@10 618 if (call_done) {
yading@10 619 p->state = STATE_SETTING_UP;
yading@10 620 pthread_cond_signal(&p->progress_cond);
yading@10 621 }
yading@10 622 pthread_mutex_unlock(&p->progress_mutex);
yading@10 623 }
yading@10 624 }
yading@10 625
yading@10 626 fctx->prev_thread = p;
yading@10 627 fctx->next_decoding++;
yading@10 628
yading@10 629 return 0;
yading@10 630 }
yading@10 631
yading@10 632 int ff_thread_decode_frame(AVCodecContext *avctx,
yading@10 633 AVFrame *picture, int *got_picture_ptr,
yading@10 634 AVPacket *avpkt)
yading@10 635 {
yading@10 636 FrameThreadContext *fctx = avctx->thread_opaque;
yading@10 637 int finished = fctx->next_finished;
yading@10 638 PerThreadContext *p;
yading@10 639 int err;
yading@10 640
yading@10 641 /*
yading@10 642 * Submit a packet to the next decoding thread.
yading@10 643 */
yading@10 644
yading@10 645 p = &fctx->threads[fctx->next_decoding];
yading@10 646 err = update_context_from_user(p->avctx, avctx);
yading@10 647 if (err) return err;
yading@10 648 err = submit_packet(p, avpkt);
yading@10 649 if (err) return err;
yading@10 650
yading@10 651 /*
yading@10 652 * If we're still receiving the initial packets, don't return a frame.
yading@10 653 */
yading@10 654
yading@10 655 if (fctx->delaying) {
yading@10 656 if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0;
yading@10 657
yading@10 658 *got_picture_ptr=0;
yading@10 659 if (avpkt->size)
yading@10 660 return avpkt->size;
yading@10 661 }
yading@10 662
yading@10 663 /*
yading@10 664 * Return the next available frame from the oldest thread.
yading@10 665 * If we're at the end of the stream, then we have to skip threads that
yading@10 666 * didn't output a frame, because we don't want to accidentally signal
yading@10 667 * EOF (avpkt->size == 0 && *got_picture_ptr == 0).
yading@10 668 */
yading@10 669
yading@10 670 do {
yading@10 671 p = &fctx->threads[finished++];
yading@10 672
yading@10 673 if (p->state != STATE_INPUT_READY) {
yading@10 674 pthread_mutex_lock(&p->progress_mutex);
yading@10 675 while (p->state != STATE_INPUT_READY)
yading@10 676 pthread_cond_wait(&p->output_cond, &p->progress_mutex);
yading@10 677 pthread_mutex_unlock(&p->progress_mutex);
yading@10 678 }
yading@10 679
yading@10 680 av_frame_move_ref(picture, &p->frame);
yading@10 681 *got_picture_ptr = p->got_frame;
yading@10 682 picture->pkt_dts = p->avpkt.dts;
yading@10 683
yading@10 684 /*
yading@10 685 * A later call with avkpt->size == 0 may loop over all threads,
yading@10 686 * including this one, searching for a frame to return before being
yading@10 687 * stopped by the "finished != fctx->next_finished" condition.
yading@10 688 * Make sure we don't mistakenly return the same frame again.
yading@10 689 */
yading@10 690 p->got_frame = 0;
yading@10 691
yading@10 692 if (finished >= avctx->thread_count) finished = 0;
yading@10 693 } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished);
yading@10 694
yading@10 695 update_context_from_thread(avctx, p->avctx, 1);
yading@10 696
yading@10 697 if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
yading@10 698
yading@10 699 fctx->next_finished = finished;
yading@10 700
yading@10 701 /* return the size of the consumed packet if no error occurred */
yading@10 702 return (p->result >= 0) ? avpkt->size : p->result;
yading@10 703 }
yading@10 704
yading@10 705 void ff_thread_report_progress(ThreadFrame *f, int n, int field)
yading@10 706 {
yading@10 707 PerThreadContext *p;
yading@10 708 volatile int *progress = f->progress ? (int*)f->progress->data : NULL;
yading@10 709
yading@10 710 if (!progress || progress[field] >= n) return;
yading@10 711
yading@10 712 p = f->owner->thread_opaque;
yading@10 713
yading@10 714 if (f->owner->debug&FF_DEBUG_THREADS)
yading@10 715 av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field);
yading@10 716
yading@10 717 pthread_mutex_lock(&p->progress_mutex);
yading@10 718 progress[field] = n;
yading@10 719 pthread_cond_broadcast(&p->progress_cond);
yading@10 720 pthread_mutex_unlock(&p->progress_mutex);
yading@10 721 }
yading@10 722
yading@10 723 void ff_thread_await_progress(ThreadFrame *f, int n, int field)
yading@10 724 {
yading@10 725 PerThreadContext *p;
yading@10 726 volatile int *progress = f->progress ? (int*)f->progress->data : NULL;
yading@10 727
yading@10 728 if (!progress || progress[field] >= n) return;
yading@10 729
yading@10 730 p = f->owner->thread_opaque;
yading@10 731
yading@10 732 if (f->owner->debug&FF_DEBUG_THREADS)
yading@10 733 av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress);
yading@10 734
yading@10 735 pthread_mutex_lock(&p->progress_mutex);
yading@10 736 while (progress[field] < n)
yading@10 737 pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
yading@10 738 pthread_mutex_unlock(&p->progress_mutex);
yading@10 739 }
yading@10 740
yading@10 741 void ff_thread_finish_setup(AVCodecContext *avctx) {
yading@10 742 PerThreadContext *p = avctx->thread_opaque;
yading@10 743
yading@10 744 if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
yading@10 745
yading@10 746 if(p->state == STATE_SETUP_FINISHED){
yading@10 747 av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
yading@10 748 }
yading@10 749
yading@10 750 pthread_mutex_lock(&p->progress_mutex);
yading@10 751 p->state = STATE_SETUP_FINISHED;
yading@10 752 pthread_cond_broadcast(&p->progress_cond);
yading@10 753 pthread_mutex_unlock(&p->progress_mutex);
yading@10 754 }
yading@10 755
yading@10 756 /// Waits for all threads to finish.
yading@10 757 static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
yading@10 758 {
yading@10 759 int i;
yading@10 760
yading@10 761 for (i = 0; i < thread_count; i++) {
yading@10 762 PerThreadContext *p = &fctx->threads[i];
yading@10 763
yading@10 764 if (p->state != STATE_INPUT_READY) {
yading@10 765 pthread_mutex_lock(&p->progress_mutex);
yading@10 766 while (p->state != STATE_INPUT_READY)
yading@10 767 pthread_cond_wait(&p->output_cond, &p->progress_mutex);
yading@10 768 pthread_mutex_unlock(&p->progress_mutex);
yading@10 769 }
yading@10 770 p->got_frame = 0;
yading@10 771 }
yading@10 772 }
yading@10 773
yading@10 774 static void frame_thread_free(AVCodecContext *avctx, int thread_count)
yading@10 775 {
yading@10 776 FrameThreadContext *fctx = avctx->thread_opaque;
yading@10 777 const AVCodec *codec = avctx->codec;
yading@10 778 int i;
yading@10 779
yading@10 780 park_frame_worker_threads(fctx, thread_count);
yading@10 781
yading@10 782 if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
yading@10 783 if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
yading@10 784 av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
yading@10 785 fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy;
yading@10 786 fctx->threads->avctx->internal->is_copy = 1;
yading@10 787 }
yading@10 788
yading@10 789 fctx->die = 1;
yading@10 790
yading@10 791 for (i = 0; i < thread_count; i++) {
yading@10 792 PerThreadContext *p = &fctx->threads[i];
yading@10 793
yading@10 794 pthread_mutex_lock(&p->mutex);
yading@10 795 pthread_cond_signal(&p->input_cond);
yading@10 796 pthread_mutex_unlock(&p->mutex);
yading@10 797
yading@10 798 if (p->thread_init)
yading@10 799 pthread_join(p->thread, NULL);
yading@10 800 p->thread_init=0;
yading@10 801
yading@10 802 if (codec->close)
yading@10 803 codec->close(p->avctx);
yading@10 804
yading@10 805 avctx->codec = NULL;
yading@10 806
yading@10 807 release_delayed_buffers(p);
yading@10 808 av_frame_unref(&p->frame);
yading@10 809 }
yading@10 810
yading@10 811 for (i = 0; i < thread_count; i++) {
yading@10 812 PerThreadContext *p = &fctx->threads[i];
yading@10 813
yading@10 814 pthread_mutex_destroy(&p->mutex);
yading@10 815 pthread_mutex_destroy(&p->progress_mutex);
yading@10 816 pthread_cond_destroy(&p->input_cond);
yading@10 817 pthread_cond_destroy(&p->progress_cond);
yading@10 818 pthread_cond_destroy(&p->output_cond);
yading@10 819 av_buffer_unref(&p->avpkt.buf);
yading@10 820 av_freep(&p->buf);
yading@10 821 av_freep(&p->released_buffers);
yading@10 822
yading@10 823 if (i) {
yading@10 824 av_freep(&p->avctx->priv_data);
yading@10 825 av_freep(&p->avctx->internal);
yading@10 826 av_freep(&p->avctx->slice_offset);
yading@10 827 }
yading@10 828
yading@10 829 av_freep(&p->avctx);
yading@10 830 }
yading@10 831
yading@10 832 av_freep(&fctx->threads);
yading@10 833 pthread_mutex_destroy(&fctx->buffer_mutex);
yading@10 834 av_freep(&avctx->thread_opaque);
yading@10 835 }
yading@10 836
yading@10 837 static int frame_thread_init(AVCodecContext *avctx)
yading@10 838 {
yading@10 839 int thread_count = avctx->thread_count;
yading@10 840 const AVCodec *codec = avctx->codec;
yading@10 841 AVCodecContext *src = avctx;
yading@10 842 FrameThreadContext *fctx;
yading@10 843 int i, err = 0;
yading@10 844
yading@10 845 if (!thread_count) {
yading@10 846 int nb_cpus = ff_get_logical_cpus(avctx);
yading@10 847 if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
yading@10 848 nb_cpus = 1;
yading@10 849 // use number of cores + 1 as thread count if there is more than one
yading@10 850 if (nb_cpus > 1)
yading@10 851 thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
yading@10 852 else
yading@10 853 thread_count = avctx->thread_count = 1;
yading@10 854 }
yading@10 855
yading@10 856 if (thread_count <= 1) {
yading@10 857 avctx->active_thread_type = 0;
yading@10 858 return 0;
yading@10 859 }
yading@10 860
yading@10 861 avctx->thread_opaque = fctx = av_mallocz(sizeof(FrameThreadContext));
yading@10 862
yading@10 863 fctx->threads = av_mallocz(sizeof(PerThreadContext) * thread_count);
yading@10 864 pthread_mutex_init(&fctx->buffer_mutex, NULL);
yading@10 865 fctx->delaying = 1;
yading@10 866
yading@10 867 for (i = 0; i < thread_count; i++) {
yading@10 868 AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
yading@10 869 PerThreadContext *p = &fctx->threads[i];
yading@10 870
yading@10 871 pthread_mutex_init(&p->mutex, NULL);
yading@10 872 pthread_mutex_init(&p->progress_mutex, NULL);
yading@10 873 pthread_cond_init(&p->input_cond, NULL);
yading@10 874 pthread_cond_init(&p->progress_cond, NULL);
yading@10 875 pthread_cond_init(&p->output_cond, NULL);
yading@10 876
yading@10 877 p->parent = fctx;
yading@10 878 p->avctx = copy;
yading@10 879
yading@10 880 if (!copy) {
yading@10 881 err = AVERROR(ENOMEM);
yading@10 882 goto error;
yading@10 883 }
yading@10 884
yading@10 885 *copy = *src;
yading@10 886 copy->thread_opaque = p;
yading@10 887 copy->pkt = &p->avpkt;
yading@10 888
yading@10 889 if (!i) {
yading@10 890 src = copy;
yading@10 891
yading@10 892 if (codec->init)
yading@10 893 err = codec->init(copy);
yading@10 894
yading@10 895 update_context_from_thread(avctx, copy, 1);
yading@10 896 } else {
yading@10 897 copy->priv_data = av_malloc(codec->priv_data_size);
yading@10 898 if (!copy->priv_data) {
yading@10 899 err = AVERROR(ENOMEM);
yading@10 900 goto error;
yading@10 901 }
yading@10 902 memcpy(copy->priv_data, src->priv_data, codec->priv_data_size);
yading@10 903 copy->internal = av_malloc(sizeof(AVCodecInternal));
yading@10 904 if (!copy->internal) {
yading@10 905 err = AVERROR(ENOMEM);
yading@10 906 goto error;
yading@10 907 }
yading@10 908 *copy->internal = *src->internal;
yading@10 909 copy->internal->is_copy = 1;
yading@10 910
yading@10 911 if (codec->init_thread_copy)
yading@10 912 err = codec->init_thread_copy(copy);
yading@10 913 }
yading@10 914
yading@10 915 if (err) goto error;
yading@10 916
yading@10 917 err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
yading@10 918 p->thread_init= !err;
yading@10 919 if(!p->thread_init)
yading@10 920 goto error;
yading@10 921 }
yading@10 922
yading@10 923 return 0;
yading@10 924
yading@10 925 error:
yading@10 926 frame_thread_free(avctx, i+1);
yading@10 927
yading@10 928 return err;
yading@10 929 }
yading@10 930
yading@10 931 void ff_thread_flush(AVCodecContext *avctx)
yading@10 932 {
yading@10 933 int i;
yading@10 934 FrameThreadContext *fctx = avctx->thread_opaque;
yading@10 935
yading@10 936 if (!avctx->thread_opaque) return;
yading@10 937
yading@10 938 park_frame_worker_threads(fctx, avctx->thread_count);
yading@10 939 if (fctx->prev_thread) {
yading@10 940 if (fctx->prev_thread != &fctx->threads[0])
yading@10 941 update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);
yading@10 942 if (avctx->codec->flush)
yading@10 943 avctx->codec->flush(fctx->threads[0].avctx);
yading@10 944 }
yading@10 945
yading@10 946 fctx->next_decoding = fctx->next_finished = 0;
yading@10 947 fctx->delaying = 1;
yading@10 948 fctx->prev_thread = NULL;
yading@10 949 for (i = 0; i < avctx->thread_count; i++) {
yading@10 950 PerThreadContext *p = &fctx->threads[i];
yading@10 951 // Make sure decode flush calls with size=0 won't return old frames
yading@10 952 p->got_frame = 0;
yading@10 953 av_frame_unref(&p->frame);
yading@10 954
yading@10 955 release_delayed_buffers(p);
yading@10 956 }
yading@10 957 }
yading@10 958
yading@10 959 int ff_thread_can_start_frame(AVCodecContext *avctx)
yading@10 960 {
yading@10 961 PerThreadContext *p = avctx->thread_opaque;
yading@10 962 if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP &&
yading@10 963 (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks && (
yading@10 964 #if FF_API_GET_BUFFER
yading@10 965 avctx->get_buffer ||
yading@10 966 #endif
yading@10 967 avctx->get_buffer2 != avcodec_default_get_buffer2)))) {
yading@10 968 return 0;
yading@10 969 }
yading@10 970 return 1;
yading@10 971 }
yading@10 972
yading@10 973 static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)
yading@10 974 {
yading@10 975 PerThreadContext *p = avctx->thread_opaque;
yading@10 976 int err;
yading@10 977
yading@10 978 f->owner = avctx;
yading@10 979
yading@10 980 ff_init_buffer_info(avctx, f->f);
yading@10 981
yading@10 982 if (!(avctx->active_thread_type & FF_THREAD_FRAME))
yading@10 983 return ff_get_buffer(avctx, f->f, flags);
yading@10 984
yading@10 985 if (p->state != STATE_SETTING_UP &&
yading@10 986 (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks && (
yading@10 987 #if FF_API_GET_BUFFER
yading@10 988 avctx->get_buffer ||
yading@10 989 #endif
yading@10 990 avctx->get_buffer2 != avcodec_default_get_buffer2)))) {
yading@10 991 av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
yading@10 992 return -1;
yading@10 993 }
yading@10 994
yading@10 995 if (avctx->internal->allocate_progress) {
yading@10 996 int *progress;
yading@10 997 f->progress = av_buffer_alloc(2 * sizeof(int));
yading@10 998 if (!f->progress) {
yading@10 999 return AVERROR(ENOMEM);
yading@10 1000 }
yading@10 1001 progress = (int*)f->progress->data;
yading@10 1002
yading@10 1003 progress[0] = progress[1] = -1;
yading@10 1004 }
yading@10 1005
yading@10 1006 pthread_mutex_lock(&p->parent->buffer_mutex);
yading@10 1007
yading@10 1008 if (avctx->thread_safe_callbacks || (
yading@10 1009 #if FF_API_GET_BUFFER
yading@10 1010 !avctx->get_buffer &&
yading@10 1011 #endif
yading@10 1012 avctx->get_buffer2 == avcodec_default_get_buffer2)) {
yading@10 1013 err = ff_get_buffer(avctx, f->f, flags);
yading@10 1014 } else {
yading@10 1015 pthread_mutex_lock(&p->progress_mutex);
yading@10 1016 p->requested_frame = f->f;
yading@10 1017 p->requested_flags = flags;
yading@10 1018 p->state = STATE_GET_BUFFER;
yading@10 1019 pthread_cond_broadcast(&p->progress_cond);
yading@10 1020
yading@10 1021 while (p->state != STATE_SETTING_UP)
yading@10 1022 pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
yading@10 1023
yading@10 1024 err = p->result;
yading@10 1025
yading@10 1026 pthread_mutex_unlock(&p->progress_mutex);
yading@10 1027
yading@10 1028 if (!avctx->codec->update_thread_context)
yading@10 1029 ff_thread_finish_setup(avctx);
yading@10 1030 }
yading@10 1031
yading@10 1032 if (err)
yading@10 1033 av_buffer_unref(&f->progress);
yading@10 1034
yading@10 1035 pthread_mutex_unlock(&p->parent->buffer_mutex);
yading@10 1036
yading@10 1037 return err;
yading@10 1038 }
yading@10 1039
yading@10 1040 enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
yading@10 1041 {
yading@10 1042 enum AVPixelFormat res;
yading@10 1043 PerThreadContext *p = avctx->thread_opaque;
yading@10 1044 if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks ||
yading@10 1045 avctx->get_format == avcodec_default_get_format)
yading@10 1046 return avctx->get_format(avctx, fmt);
yading@10 1047 if (p->state != STATE_SETTING_UP) {
yading@10 1048 av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n");
yading@10 1049 return -1;
yading@10 1050 }
yading@10 1051 pthread_mutex_lock(&p->progress_mutex);
yading@10 1052 p->available_formats = fmt;
yading@10 1053 p->state = STATE_GET_FORMAT;
yading@10 1054 pthread_cond_broadcast(&p->progress_cond);
yading@10 1055
yading@10 1056 while (p->state != STATE_SETTING_UP)
yading@10 1057 pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
yading@10 1058
yading@10 1059 res = p->result_format;
yading@10 1060
yading@10 1061 pthread_mutex_unlock(&p->progress_mutex);
yading@10 1062
yading@10 1063 return res;
yading@10 1064 }
yading@10 1065
yading@10 1066 int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
yading@10 1067 {
yading@10 1068 int ret = thread_get_buffer_internal(avctx, f, flags);
yading@10 1069 if (ret < 0)
yading@10 1070 av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
yading@10 1071 return ret;
yading@10 1072 }
yading@10 1073
yading@10 1074 void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
yading@10 1075 {
yading@10 1076 PerThreadContext *p = avctx->thread_opaque;
yading@10 1077 FrameThreadContext *fctx;
yading@10 1078 AVFrame *dst, *tmp;
yading@10 1079 int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
yading@10 1080 avctx->thread_safe_callbacks ||
yading@10 1081 (
yading@10 1082 #if FF_API_GET_BUFFER
yading@10 1083 !avctx->get_buffer &&
yading@10 1084 #endif
yading@10 1085 avctx->get_buffer2 == avcodec_default_get_buffer2);
yading@10 1086
yading@10 1087 if (!f->f->data[0])
yading@10 1088 return;
yading@10 1089
yading@10 1090 if (avctx->debug & FF_DEBUG_BUFFERS)
yading@10 1091 av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
yading@10 1092
yading@10 1093 av_buffer_unref(&f->progress);
yading@10 1094 f->owner = NULL;
yading@10 1095
yading@10 1096 if (can_direct_free) {
yading@10 1097 av_frame_unref(f->f);
yading@10 1098 return;
yading@10 1099 }
yading@10 1100
yading@10 1101 fctx = p->parent;
yading@10 1102 pthread_mutex_lock(&fctx->buffer_mutex);
yading@10 1103
yading@10 1104 if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers))
yading@10 1105 goto fail;
yading@10 1106 tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
yading@10 1107 (p->num_released_buffers + 1) *
yading@10 1108 sizeof(*p->released_buffers));
yading@10 1109 if (!tmp)
yading@10 1110 goto fail;
yading@10 1111 p->released_buffers = tmp;
yading@10 1112
yading@10 1113 dst = &p->released_buffers[p->num_released_buffers];
yading@10 1114 av_frame_move_ref(dst, f->f);
yading@10 1115
yading@10 1116 p->num_released_buffers++;
yading@10 1117
yading@10 1118 fail:
yading@10 1119 pthread_mutex_unlock(&fctx->buffer_mutex);
yading@10 1120 }
yading@10 1121
yading@10 1122 /**
yading@10 1123 * Set the threading algorithms used.
yading@10 1124 *
yading@10 1125 * Threading requires more than one thread.
yading@10 1126 * Frame threading requires entire frames to be passed to the codec,
yading@10 1127 * and introduces extra decoding delay, so is incompatible with low_delay.
yading@10 1128 *
yading@10 1129 * @param avctx The context.
yading@10 1130 */
yading@10 1131 static void validate_thread_parameters(AVCodecContext *avctx)
yading@10 1132 {
yading@10 1133 int frame_threading_supported = (avctx->codec->capabilities & CODEC_CAP_FRAME_THREADS)
yading@10 1134 && !(avctx->flags & CODEC_FLAG_TRUNCATED)
yading@10 1135 && !(avctx->flags & CODEC_FLAG_LOW_DELAY)
yading@10 1136 && !(avctx->flags2 & CODEC_FLAG2_CHUNKS);
yading@10 1137 if (avctx->thread_count == 1) {
yading@10 1138 avctx->active_thread_type = 0;
yading@10 1139 } else if (frame_threading_supported && (avctx->thread_type & FF_THREAD_FRAME)) {
yading@10 1140 avctx->active_thread_type = FF_THREAD_FRAME;
yading@10 1141 } else if (avctx->codec->capabilities & CODEC_CAP_SLICE_THREADS &&
yading@10 1142 avctx->thread_type & FF_THREAD_SLICE) {
yading@10 1143 avctx->active_thread_type = FF_THREAD_SLICE;
yading@10 1144 } else if (!(avctx->codec->capabilities & CODEC_CAP_AUTO_THREADS)) {
yading@10 1145 avctx->thread_count = 1;
yading@10 1146 avctx->active_thread_type = 0;
yading@10 1147 }
yading@10 1148
yading@10 1149 if (avctx->thread_count > MAX_AUTO_THREADS)
yading@10 1150 av_log(avctx, AV_LOG_WARNING,
yading@10 1151 "Application has requested %d threads. Using a thread count greater than %d is not recommended.\n",
yading@10 1152 avctx->thread_count, MAX_AUTO_THREADS);
yading@10 1153 }
yading@10 1154
yading@10 1155 int ff_thread_init(AVCodecContext *avctx)
yading@10 1156 {
yading@10 1157 if (avctx->thread_opaque) {
yading@10 1158 av_log(avctx, AV_LOG_ERROR, "avcodec_thread_init is ignored after avcodec_open\n");
yading@10 1159 return -1;
yading@10 1160 }
yading@10 1161
yading@10 1162 #if HAVE_W32THREADS
yading@10 1163 w32thread_init();
yading@10 1164 #endif
yading@10 1165
yading@10 1166 if (avctx->codec) {
yading@10 1167 validate_thread_parameters(avctx);
yading@10 1168
yading@10 1169 if (avctx->active_thread_type&FF_THREAD_SLICE)
yading@10 1170 return thread_init(avctx);
yading@10 1171 else if (avctx->active_thread_type&FF_THREAD_FRAME)
yading@10 1172 return frame_thread_init(avctx);
yading@10 1173 }
yading@10 1174
yading@10 1175 return 0;
yading@10 1176 }
yading@10 1177
yading@10 1178 void ff_thread_free(AVCodecContext *avctx)
yading@10 1179 {
yading@10 1180 if (avctx->active_thread_type&FF_THREAD_FRAME)
yading@10 1181 frame_thread_free(avctx, avctx->thread_count);
yading@10 1182 else
yading@10 1183 thread_free(avctx);
yading@10 1184 }