diff --git a/libavcodec/encode.c b/libavcodec/encode.c index 01b59bbf70..f7b13c8ba1 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -172,6 +172,48 @@ int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame) return 0; } +int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet) +{ + const FFCodec *const codec = ffcodec(avctx->codec); + int ret; + + ret = codec->cb.encode(avctx, avpkt, frame, got_packet); + emms_c(); + av_assert0(ret <= 0); + + if (!ret && *got_packet) { + if (avpkt->data) { + ret = av_packet_make_refcounted(avpkt); + if (ret < 0) + goto unref; + // Date returned by encoders must always be ref-counted + av_assert0(avpkt->buf); + } + + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO && + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + avpkt->pts = avpkt->dts = frame->pts; + if (frame && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + if (avpkt->pts == AV_NOPTS_VALUE) + avpkt->pts = frame->pts; + if (!avpkt->duration) + avpkt->duration = ff_samples_to_time_base(avctx, + frame->nb_samples); + } + } + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + avpkt->dts = avpkt->pts; + } + } else { +unref: + av_packet_unref(avpkt); + } + + return ret; +} + static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt) { AVCodecInternal *avci = avctx->internal; @@ -204,58 +246,18 @@ static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt) av_assert0(codec->cb_type == FF_CODEC_CB_TYPE_ENCODE); if (CONFIG_FRAME_THREAD_ENCODER && avci->frame_thread_encoder) - /* This might modify frame, but it doesn't matter, because - * the frame properties used below are not used for video - * (due to the delay inherent in frame threaded encoding, it makes - * no sense to use the properties of the current frame anyway). */ + /* This might unref frame. */ ret = ff_thread_video_encode_frame(avctx, avpkt, frame, &got_packet); else { - ret = codec->cb.encode(avctx, avpkt, frame, &got_packet); - if (avctx->codec->type == AVMEDIA_TYPE_VIDEO && !ret && got_packet && - !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - avpkt->pts = avpkt->dts = frame->pts; - } - - av_assert0(ret <= 0); - - emms_c(); - - if (!ret && got_packet) { - if (avpkt->data) { - ret = av_packet_make_refcounted(avpkt); - if (ret < 0) - goto end; - } - - if (frame && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { - if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { - if (avpkt->pts == AV_NOPTS_VALUE) - avpkt->pts = frame->pts; - if (!avpkt->duration) - avpkt->duration = ff_samples_to_time_base(avctx, - frame->nb_samples); - } - } - if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { - avpkt->dts = avpkt->pts; - } + ret = ff_encode_encode_cb(avctx, avpkt, frame, &got_packet); } if (avci->draining && !got_packet) avci->draining_done = 1; -end: - if (ret < 0 || !got_packet) - av_packet_unref(avpkt); - if (frame) av_frame_unref(frame); - if (got_packet) - // Encoders must always return ref-counted buffers. - // Side-data only packets have no data and can be not ref-counted. - av_assert0(!avpkt->data || avpkt->buf); - return ret; } diff --git a/libavcodec/encode.h b/libavcodec/encode.h index bc77918d8f..10c36435ad 100644 --- a/libavcodec/encode.h +++ b/libavcodec/encode.h @@ -75,4 +75,7 @@ int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size); */ int ff_encode_preinit(AVCodecContext *avctx); +int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet); + #endif /* AVCODEC_ENCODE_H */ diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index b5765b6343..1faaef522e 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -24,14 +24,12 @@ #include "libavutil/avassert.h" #include "libavutil/cpu.h" -#include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "libavutil/thread.h" #include "avcodec.h" -#include "codec_internal.h" +#include "encode.h" #include "internal.h" #include "pthread_internal.h" -#include "thread.h" #define MAX_THREADS 64 /* There can be as many as MAX_THREADS + 1 outstanding tasks. @@ -80,7 +78,7 @@ static void * attribute_align_arg worker(void *v){ ThreadContext *c = avctx->internal->frame_thread_encoder; while (!atomic_load(&c->exit)) { - int got_packet = 0, ret; + int ret; AVPacket *pkt; AVFrame *frame; Task *task; @@ -105,14 +103,7 @@ static void * attribute_align_arg worker(void *v){ frame = task->indata; pkt = task->outdata; - ret = ffcodec(avctx->codec)->cb.encode(avctx, pkt, frame, &got_packet); - if(got_packet) { - int ret2 = av_packet_make_refcounted(pkt); - if (ret >= 0 && ret2 < 0) - ret = ret2; - pkt->pts = pkt->dts = frame->pts; - } - task->got_packet = got_packet; + ret = ff_encode_encode_cb(avctx, pkt, frame, &task->got_packet); pthread_mutex_lock(&c->buffer_mutex); av_frame_unref(frame); pthread_mutex_unlock(&c->buffer_mutex);