* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdatomic.h>
+
#include "frame_thread_encoder.h"
#include "libavutil/fifo.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
#include "libavutil/thread.h"
#include "avcodec.h"
#include "internal.h"
unsigned finished_task_index;
pthread_t worker[MAX_THREADS];
- int exit;
+ atomic_int exit;
} ThreadContext;
static void * attribute_align_arg worker(void *v){
ThreadContext *c = avctx->internal->frame_thread_encoder;
AVPacket *pkt = NULL;
- while(!c->exit){
+ while (!atomic_load(&c->exit)) {
int got_packet, ret;
AVFrame *frame;
Task task;
- if(!pkt) pkt= av_mallocz(sizeof(*pkt));
+ if(!pkt) pkt = av_packet_alloc();
if(!pkt) continue;
av_init_packet(pkt);
pthread_mutex_lock(&c->task_fifo_mutex);
- while (av_fifo_size(c->task_fifo) <= 0 || c->exit) {
- if(c->exit){
+ while (av_fifo_size(c->task_fifo) <= 0 || atomic_load(&c->exit)) {
+ if (atomic_load(&c->exit)) {
pthread_mutex_unlock(&c->task_fifo_mutex);
goto end;
}
pthread_mutex_init(&c->buffer_mutex, NULL);
pthread_cond_init(&c->task_fifo_cond, NULL);
pthread_cond_init(&c->finished_task_cond, NULL);
+ atomic_init(&c->exit, 0);
for(i=0; i<avctx->thread_count ; i++){
AVDictionary *tmp = NULL;
+ int ret;
void *tmpv;
AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec);
if(!thread_avctx)
goto fail;
tmpv = thread_avctx->priv_data;
*thread_avctx = *avctx;
+ ret = av_opt_copy(thread_avctx, avctx);
+ if (ret < 0)
+ goto fail;
thread_avctx->priv_data = tmpv;
thread_avctx->internal = NULL;
- memcpy(thread_avctx->priv_data, avctx->priv_data, avctx->codec->priv_data_size);
+ if (avctx->codec->priv_class) {
+ int ret = av_opt_copy(thread_avctx->priv_data, avctx->priv_data);
+ if (ret < 0)
+ goto fail;
+ } else
+ memcpy(thread_avctx->priv_data, avctx->priv_data, avctx->codec->priv_data_size);
thread_avctx->thread_count = 1;
thread_avctx->active_thread_type &= ~FF_THREAD_FRAME;
ThreadContext *c= avctx->internal->frame_thread_encoder;
pthread_mutex_lock(&c->task_fifo_mutex);
- c->exit = 1;
+ atomic_store(&c->exit, 1);
pthread_cond_broadcast(&c->task_fifo_cond);
pthread_mutex_unlock(&c->task_fifo_mutex);
pthread_mutex_unlock(&c->task_fifo_mutex);
c->task_index = (c->task_index+1) % BUFFER_SIZE;
-
- if(!c->finished_tasks[c->finished_task_index].outdata && (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)
- return 0;
}
- if(c->task_index == c->finished_task_index)
- return 0;
-
pthread_mutex_lock(&c->finished_task_mutex);
+ if (c->task_index == c->finished_task_index ||
+ (frame && !c->finished_tasks[c->finished_task_index].outdata &&
+ (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)) {
+ pthread_mutex_unlock(&c->finished_task_mutex);
+ return 0;
+ }
+
while (!c->finished_tasks[c->finished_task_index].outdata) {
pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex);
}