#include <stdint.h>
#include "avcodec.h"
-#include "hwaccel.h"
+#include "hwconfig.h"
#include "internal.h"
#include "pthread_internal.h"
#include "thread.h"
* 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 **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
}
dst->hwaccel_flags = src->hwaccel_flags;
+
+ if (!!dst->internal->pool != !!src->internal->pool ||
+ (dst->internal->pool && dst->internal->pool->data != src->internal->pool->data)) {
+ av_buffer_unref(&dst->internal->pool);
+
+ if (src->internal->pool) {
+ dst->internal->pool = av_buffer_ref(src->internal->pool);
+ if (!dst->internal->pool)
+ return AVERROR(ENOMEM);
+ }
+ }
}
if (for_user) {
- dst->delay = src->thread_count - 1;
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
dst->coded_frame = src->coded_frame;
*/
static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
{
-#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s);
dst->flags = src->flags;
dst->draw_horiz_band= src->draw_horiz_band;
dst->flags2 = src->flags2;
dst->export_side_data = src->export_side_data;
- copy_fields(skip_loop_filter, subtitle_header);
+ dst->skip_loop_filter = src->skip_loop_filter;
+ dst->skip_idct = src->skip_idct;
+ dst->skip_frame = src->skip_frame;
dst->frame_number = src->frame_number;
dst->reordered_opaque = src->reordered_opaque;
}
dst->slice_count = src->slice_count;
return 0;
-#undef copy_fields
}
/// Releases the buffers that this decoding thread was the last user of.
// 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 = p->released_buffers[--p->num_released_buffers];
f->extended_data = f->data;
av_frame_unref(f);
{
FrameThreadContext *fctx = avctx->internal->thread_ctx;
const AVCodec *codec = avctx->codec;
- int i;
+ int i, j;
park_frame_worker_threads(fctx, thread_count);
pthread_cond_destroy(&p->progress_cond);
pthread_cond_destroy(&p->output_cond);
av_packet_unref(&p->avpkt);
+
+ for (j = 0; j < p->released_buffers_allocated; j++)
+ av_frame_free(&p->released_buffers[j]);
av_freep(&p->released_buffers);
- if (i && p->avctx) {
+ if (p->avctx) {
if (codec->priv_class)
av_opt_free(p->avctx->priv_data);
av_freep(&p->avctx->priv_data);
}
if (p->avctx) {
+ av_buffer_unref(&p->avctx->internal->pool);
av_freep(&p->avctx->internal);
av_buffer_unref(&p->avctx->hw_frames_ctx);
}
fctx->async_lock = 1;
fctx->delaying = 1;
+ if (codec->type == AVMEDIA_TYPE_VIDEO)
+ avctx->delay = src->thread_count - 1;
+
for (i = 0; i < thread_count; i++) {
AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
PerThreadContext *p = &fctx->threads[i];
copy->internal->thread_ctx = p;
copy->internal->last_pkt_props = &p->avpkt;
- if (i) {
+ copy->delay = avctx->delay;
+
+ if (codec->priv_data_size) {
copy->priv_data = av_mallocz(codec->priv_data_size);
if (!copy->priv_data) {
err = AVERROR(ENOMEM);
if (err < 0)
goto error;
}
- copy->internal->is_copy = 1;
}
+ if (i)
+ copy->internal->is_copy = 1;
+
if (codec->init)
err = codec->init(copy);
{
PerThreadContext *p = avctx->internal->thread_ctx;
FrameThreadContext *fctx;
- AVFrame *dst, *tmp;
+ AVFrame *dst;
int ret = 0;
int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
THREAD_SAFE_CALLBACKS(avctx);
fctx = p->parent;
pthread_mutex_lock(&fctx->buffer_mutex);
- if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers)) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
- (p->num_released_buffers + 1) *
- sizeof(*p->released_buffers));
- if (!tmp) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ 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++;
}
- p->released_buffers = tmp;
- dst = &p->released_buffers[p->num_released_buffers];
+ dst = p->released_buffers[p->num_released_buffers];
av_frame_move_ref(dst, f->f);
p->num_released_buffers++;