X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Futils.c;h=1721c09129e8ebbfcbc677d04b3c658f1f4a0516;hb=380146924ecad2e05e9dcc5c3c2e1b5ba47c51e8;hp=7e116ed9e2536f156d6e97fe22c9986b7a889b5c;hpb=f929ab0569ff31ed5a59b0b0adb7ce09df3fca39;p=ffmpeg diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 7e116ed9e25..1721c09129e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -59,14 +59,14 @@ static void *avformat_mutex; void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size) { void **p = ptr; - if (min_size > SIZE_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { + if (min_size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { av_freep(p); *size = 0; return; } - av_fast_malloc(p, size, min_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(p, size, min_size + AV_INPUT_BUFFER_PADDING_SIZE); if (*size) - memset((uint8_t *)*p + min_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + memset((uint8_t *)*p + min_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } /* encoder management */ @@ -107,7 +107,7 @@ av_cold void avcodec_register(AVCodec *codec) AVCodec **p; avcodec_init(); p = &first_avcodec; - while (*p != NULL) + while (*p) p = &(*p)->next; *p = codec; codec->next = NULL; @@ -147,7 +147,7 @@ int ff_set_sar(AVCodecContext *avctx, AVRational sar) int ret = av_image_check_sar(avctx->width, avctx->height, sar); if (ret < 0) { - av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %d/%d\n", sar.num, sar.den); avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; return ret; @@ -199,6 +199,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUV440P: case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_GBRP: + case AV_PIX_FMT_GBRAP: case AV_PIX_FMT_GRAY8: case AV_PIX_FMT_GRAY16BE: case AV_PIX_FMT_GRAY16LE: @@ -473,7 +474,7 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) FramePool *pool = s->internal->pool; int i; - if (pic->data[0] != NULL) { + if (pic->data[0]) { av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n"); return -1; } @@ -513,12 +514,6 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags if ((ret = update_frame_pool(avctx, frame)) < 0) return ret; -#if FF_API_GET_BUFFER -FF_DISABLE_DEPRECATION_WARNINGS - frame->type = FF_BUFFER_TYPE_INTERNAL; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - switch (avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: return video_get_buffer(avctx, frame); @@ -529,40 +524,19 @@ FF_ENABLE_DEPRECATION_WARNINGS } } -#if FF_API_GET_BUFFER -FF_DISABLE_DEPRECATION_WARNINGS -int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame) -{ - return avcodec_default_get_buffer2(avctx, frame, 0); -} - -typedef struct CompatReleaseBufPriv { - AVCodecContext avctx; - AVFrame frame; -} CompatReleaseBufPriv; - -static void compat_free_buffer(void *opaque, uint8_t *data) -{ - CompatReleaseBufPriv *priv = opaque; - if (priv->avctx.release_buffer) - priv->avctx.release_buffer(&priv->avctx, &priv->frame); - av_freep(&priv); -} - -static void compat_release_buffer(void *opaque, uint8_t *data) -{ - AVBufferRef *buf = opaque; - av_buffer_unref(&buf); -} -FF_ENABLE_DEPRECATION_WARNINGS -#endif - int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { AVPacket *pkt = avctx->internal->pkt; - uint8_t *packet_sd; - int size; - AVFrameSideData *frame_sd; + int i; + struct { + enum AVPacketSideDataType packet; + enum AVFrameSideDataType frame; + } sd[] = { + { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN }, + { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, + { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, + { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, + }; frame->color_primaries = avctx->color_primaries; frame->color_trc = avctx->color_trc; @@ -578,23 +552,18 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) frame->pkt_pts = pkt->pts; - /* copy the replaygain data to the output frame */ - packet_sd = av_packet_get_side_data(pkt, AV_PKT_DATA_REPLAYGAIN, &size); - if (packet_sd) { - frame_sd = av_frame_new_side_data(frame, AV_FRAME_DATA_REPLAYGAIN, size); - if (!frame_sd) - return AVERROR(ENOMEM); - - memcpy(frame_sd->data, packet_sd, size); - } - /* copy the displaymatrix to the output frame */ - packet_sd = av_packet_get_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX, &size); - if (packet_sd) { - frame_sd = av_frame_new_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX, size); - if (!frame_sd) - return AVERROR(ENOMEM); - - memcpy(frame_sd->data, packet_sd, size); + for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) { + int size; + uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); + if (packet_sd) { + AVFrameSideData *frame_sd = av_frame_new_side_data(frame, + sd[i].frame, + size); + if (!frame_sd) + return AVERROR(ENOMEM); + + memcpy(frame_sd->data, packet_sd, size); + } } return 0; @@ -664,126 +633,13 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) if (ret < 0) return ret; - if (hwaccel && hwaccel->alloc_frame) { - ret = hwaccel->alloc_frame(avctx, frame); - goto end; - } - -#if FF_API_GET_BUFFER -FF_DISABLE_DEPRECATION_WARNINGS - /* - * Wrap an old get_buffer()-allocated buffer in an bunch of AVBuffers. - * We wrap each plane in its own AVBuffer. Each of those has a reference to - * a dummy AVBuffer as its private data, unreffing it on free. - * When all the planes are freed, the dummy buffer's free callback calls - * release_buffer(). - */ - if (avctx->get_buffer) { - CompatReleaseBufPriv *priv = NULL; - AVBufferRef *dummy_buf = NULL; - int planes, i, ret; - - if (flags & AV_GET_BUFFER_FLAG_REF) - frame->reference = 1; - - ret = avctx->get_buffer(avctx, frame); - if (ret < 0) - return ret; - - /* return if the buffers are already set up - * this would happen e.g. when a custom get_buffer() calls - * avcodec_default_get_buffer - */ - if (frame->buf[0]) - return 0; - - priv = av_mallocz(sizeof(*priv)); - if (!priv) { - ret = AVERROR(ENOMEM); - goto fail; - } - priv->avctx = *avctx; - priv->frame = *frame; - - dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, priv, 0); - if (!dummy_buf) { - ret = AVERROR(ENOMEM); - goto fail; - } - -#define WRAP_PLANE(ref_out, data, data_size) \ -do { \ - AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf); \ - if (!dummy_ref) { \ - ret = AVERROR(ENOMEM); \ - goto fail; \ - } \ - ref_out = av_buffer_create(data, data_size, compat_release_buffer, \ - dummy_ref, 0); \ - if (!ref_out) { \ - av_frame_unref(frame); \ - ret = AVERROR(ENOMEM); \ - goto fail; \ - } \ -} while (0) - - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - - planes = av_pix_fmt_count_planes(frame->format); - /* workaround for AVHWAccel plane count of 0, buf[0] is used as - check for allocated buffers: make libavcodec happy */ - if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) - planes = 1; - if (!desc || planes <= 0) { - ret = AVERROR(EINVAL); - goto fail; - } - - for (i = 0; i < planes; i++) { - int v_shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; - int plane_size = (frame->height >> v_shift) * frame->linesize[i]; - - WRAP_PLANE(frame->buf[i], frame->data[i], plane_size); - } - } else { - int planar = av_sample_fmt_is_planar(frame->format); - planes = planar ? avctx->channels : 1; - - if (planes > FF_ARRAY_ELEMS(frame->buf)) { - frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf); - frame->extended_buf = av_malloc(sizeof(*frame->extended_buf) * - frame->nb_extended_buf); - if (!frame->extended_buf) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - - for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++) - WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]); - - for (i = 0; i < frame->nb_extended_buf; i++) - WRAP_PLANE(frame->extended_buf[i], - frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)], - frame->linesize[0]); + if (hwaccel) { + if (hwaccel->alloc_frame) { + ret = hwaccel->alloc_frame(avctx, frame); + goto end; } - - av_buffer_unref(&dummy_buf); - - frame->width = avctx->width; - frame->height = avctx->height; - - return 0; - -fail: - avctx->release_buffer(avctx, frame); - av_freep(&priv); - av_buffer_unref(&dummy_buf); - return ret; - } -FF_ENABLE_DEPRECATION_WARNINGS -#endif + } else + avctx->sw_pix_fmt = avctx->pix_fmt; ret = avctx->get_buffer2(avctx, frame, flags); @@ -827,19 +683,6 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) return 0; } -#if FF_API_GET_BUFFER -void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic) -{ - av_frame_unref(pic); -} - -int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic) -{ - av_assert0(0); - return AVERROR_BUG; -} -#endif - int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) { int i; @@ -889,86 +732,91 @@ static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, return NULL; } - -int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) +static int setup_hwaccel(AVCodecContext *avctx, + const enum AVPixelFormat fmt, + const char *name) { - const AVPixFmtDescriptor *desc; - enum AVPixelFormat ret = avctx->get_format(avctx, fmt); - - desc = av_pix_fmt_desc_get(ret); - if (!desc) - return AV_PIX_FMT_NONE; - - if (avctx->hwaccel && avctx->hwaccel->uninit) - avctx->hwaccel->uninit(avctx); - av_freep(&avctx->internal->hwaccel_priv_data); - avctx->hwaccel = NULL; + AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt); + int ret = 0; - if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { - AVHWAccel *hwaccel; - int err; - - hwaccel = find_hwaccel(avctx->codec_id, ret); - if (!hwaccel) { - av_log(avctx, AV_LOG_ERROR, - "Could not find an AVHWAccel for the pixel format: %s", - desc->name); - return AV_PIX_FMT_NONE; - } + if (!hwa) { + av_log(avctx, AV_LOG_ERROR, + "Could not find an AVHWAccel for the pixel format: %s", + name); + return AVERROR(ENOENT); + } - if (hwaccel->priv_data_size) { - avctx->internal->hwaccel_priv_data = av_mallocz(hwaccel->priv_data_size); - if (!avctx->internal->hwaccel_priv_data) - return AV_PIX_FMT_NONE; - } + if (hwa->priv_data_size) { + avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size); + if (!avctx->internal->hwaccel_priv_data) + return AVERROR(ENOMEM); + } - if (hwaccel->init) { - err = hwaccel->init(avctx); - if (err < 0) { - av_freep(&avctx->internal->hwaccel_priv_data); - return AV_PIX_FMT_NONE; - } + if (hwa->init) { + ret = hwa->init(avctx); + if (ret < 0) { + av_freep(&avctx->internal->hwaccel_priv_data); + return ret; } - avctx->hwaccel = hwaccel; } - return ret; + avctx->hwaccel = hwa; + + return 0; } -#if FF_API_AVFRAME_LAVC -void avcodec_get_frame_defaults(AVFrame *frame) +int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) { - if (frame->extended_data != frame->data) - av_freep(&frame->extended_data); + const AVPixFmtDescriptor *desc; + enum AVPixelFormat *choices; + enum AVPixelFormat ret; + unsigned n = 0; - memset(frame, 0, sizeof(AVFrame)); + while (fmt[n] != AV_PIX_FMT_NONE) + ++n; - frame->pts = AV_NOPTS_VALUE; - frame->key_frame = 1; - frame->sample_aspect_ratio = (AVRational) {0, 1 }; - frame->format = -1; /* unknown */ - frame->extended_data = frame->data; -} + av_assert0(n >= 1); + avctx->sw_pix_fmt = fmt[n - 1]; + av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); -AVFrame *avcodec_alloc_frame(void) -{ - AVFrame *frame = av_mallocz(sizeof(AVFrame)); + choices = av_malloc_array(n + 1, sizeof(*choices)); + if (!choices) + return AV_PIX_FMT_NONE; - if (!frame) - return NULL; + memcpy(choices, fmt, (n + 1) * sizeof(*choices)); -FF_DISABLE_DEPRECATION_WARNINGS - avcodec_get_frame_defaults(frame); -FF_ENABLE_DEPRECATION_WARNINGS + for (;;) { + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; - return frame; -} + ret = avctx->get_format(avctx, choices); -void avcodec_free_frame(AVFrame **frame) -{ - av_frame_free(frame); + desc = av_pix_fmt_desc_get(ret); + if (!desc) { + ret = AV_PIX_FMT_NONE; + break; + } + + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + break; + + if (!setup_hwaccel(avctx, ret, desc->name)) + break; + + /* Remove failed hwaccel from choices */ + for (n = 0; choices[n] != ret; n++) + av_assert0(choices[n] != AV_PIX_FMT_NONE); + + do + choices[n] = choices[n + 1]; + while (choices[n++] != AV_PIX_FMT_NONE); + } + + av_freep(&choices); + return ret; } -#endif int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) { @@ -1003,8 +851,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code } entangled_thread_counter++; - if (entangled_thread_counter != 1) { - av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n"); + if (entangled_thread_counter != 1 && + !(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE)) { + av_log(avctx, AV_LOG_ERROR, + "Insufficient thread locking. At least %d threads are " + "calling avcodec_open2() at the same time right now.\n", + entangled_thread_counter); ret = -1; goto end; } @@ -1095,7 +947,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code } avctx->frame_number = 0; - if (avctx->codec->capabilities & CODEC_CAP_EXPERIMENTAL && + if ((avctx->codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { ret = AVERROR_EXPERIMENTAL; goto free_and_end; @@ -1113,11 +965,20 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } } - if (!HAVE_THREADS && !(codec->capabilities & CODEC_CAP_AUTO_THREADS)) + if (!HAVE_THREADS && !(codec->capabilities & AV_CODEC_CAP_AUTO_THREADS)) avctx->thread_count = 1; if (av_codec_is_encoder(avctx->codec)) { int i; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (avctx->codec->sample_fmts) { for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) { if (avctx->sample_fmt == avctx->codec->sample_fmts[i]) @@ -1144,6 +1005,11 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code ret = AVERROR(EINVAL); goto free_and_end; } + if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ420P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ422P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ440P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ444P) + avctx->color_range = AVCOL_RANGE_JPEG; } if (avctx->codec->supported_samplerates) { for (i = 0; avctx->codec->supported_samplerates[i] != 0; i++) @@ -1190,6 +1056,11 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code } } +#if FF_API_AUDIOENC_DELAY + if (av_codec_is_encoder(avctx->codec)) + avctx->delay = avctx->initial_padding; +#endif + if (av_codec_is_decoder(avctx->codec)) { /* validate channel layout from the decoder */ if (avctx->channel_layout) { @@ -1207,6 +1078,11 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code ret = AVERROR(EINVAL); goto free_and_end; } + +#if FF_API_AVCTX_TIMEBASE + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + avctx->time_base = av_inv_q(avctx->framerate); +#endif } end: entangled_thread_counter--; @@ -1222,6 +1098,20 @@ end: return ret; free_and_end: + if (avctx->codec && + (avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP)) + avctx->codec->close(avctx); + + if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) + av_opt_free(avctx->priv_data); + av_opt_free(avctx); + +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + av_dict_free(&tmp); av_freep(&avctx->priv_data); if (avctx->internal) { @@ -1235,26 +1125,16 @@ free_and_end: int ff_alloc_packet(AVPacket *avpkt, int size) { - if (size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) + if (size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) return AVERROR(EINVAL); if (avpkt->data) { AVBufferRef *buf = avpkt->buf; -#if FF_API_DESTRUCT_PACKET -FF_DISABLE_DEPRECATION_WARNINGS - void *destruct = avpkt->destruct; -FF_ENABLE_DEPRECATION_WARNINGS -#endif if (avpkt->size < size) return AVERROR(EINVAL); av_init_packet(avpkt); -#if FF_API_DESTRUCT_PACKET -FF_DISABLE_DEPRECATION_WARNINGS - avpkt->destruct = destruct; -FF_ENABLE_DEPRECATION_WARNINGS -#endif avpkt->buf = buf; avpkt->size = size; return 0; @@ -1314,7 +1194,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, *got_packet_ptr = 0; - if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { av_free_packet(avpkt); av_init_packet(avpkt); return 0; @@ -1336,12 +1216,19 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, frame = &tmp; } + /* extract audio service type metadata */ + if (frame) { + AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); + if (sd && sd->size >= sizeof(enum AVAudioServiceType)) + avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; + } + /* check for valid frame size */ if (frame) { - if (avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { + if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { if (frame->nb_samples > avctx->frame_size) return AVERROR(EINVAL); - } else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) { + } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { if (frame->nb_samples < avctx->frame_size && !avctx->internal->last_audio_frame) { ret = pad_last_frame(avctx, &padded_frame, frame); @@ -1362,7 +1249,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); if (!ret) { if (*got_packet_ptr) { - if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { if (avpkt->pts == AV_NOPTS_VALUE) avpkt->pts = frame->pts; if (!avpkt->duration) @@ -1397,6 +1284,10 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, end: av_frame_free(&padded_frame); +#if FF_API_AUDIOENC_DELAY + avctx->delay = avctx->initial_padding; +#endif + return ret; } @@ -1410,7 +1301,7 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, *got_packet_ptr = 0; - if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { av_free_packet(avpkt); av_init_packet(avpkt); avpkt->size = 0; @@ -1426,7 +1317,7 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, if (!ret) { if (!*got_packet_ptr) avpkt->size = 0; - else if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) + else if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) avpkt->pts = avpkt->dts = frame->pts; if (!user_packet && avpkt->size) { @@ -1470,7 +1361,7 @@ static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) if (!data) return 0; - if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " "changes, but PARAM_CHANGE side data was sent to it.\n"); return AVERROR(EINVAL); @@ -1583,16 +1474,18 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi av_frame_unref(picture); - if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { + if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || + (avctx->active_thread_type & FF_THREAD_FRAME)) { if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, avpkt); else { ret = avctx->codec->decode(avctx, picture, got_picture_ptr, avpkt); - picture->pkt_dts = avpkt->dts; + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) + picture->pkt_dts = avpkt->dts; /* get_buffer is supposed to set frame parameters */ - if (!(avctx->codec->capabilities & CODEC_CAP_DR1)) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { picture->sample_aspect_ratio = avctx->sample_aspect_ratio; picture->width = avctx->width; picture->height = avctx->height; @@ -1615,6 +1508,11 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi } else ret = 0; +#if FF_API_AVCTX_TIMEBASE + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + avctx->time_base = av_inv_q(avctx->framerate); +#endif + return ret; } @@ -1644,7 +1542,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, av_frame_unref(frame); - if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { + if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt); if (ret >= 0 && *got_frame_ptr) { avctx->frame_number++; @@ -1707,7 +1605,6 @@ av_cold int avcodec_close(AVCodecContext *avctx) ff_thread_free(avctx); if (avctx->codec && avctx->codec->close) avctx->codec->close(avctx); - avctx->coded_frame = NULL; av_frame_free(&avctx->internal->to_free); for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) av_buffer_pool_uninit(&pool->pools[i]); @@ -1724,8 +1621,14 @@ av_cold int avcodec_close(AVCodecContext *avctx) av_opt_free(avctx->priv_data); av_opt_free(avctx); av_freep(&avctx->priv_data); - if (av_codec_is_encoder(avctx->codec)) + if (av_codec_is_encoder(avctx->codec)) { av_freep(&avctx->extradata); +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + } avctx->codec = NULL; avctx->active_thread_type = 0; @@ -1739,7 +1642,7 @@ static AVCodec *find_encdec(enum AVCodecID id, int encoder) while (p) { if ((encoder ? av_codec_is_encoder(p) : av_codec_is_decoder(p)) && p->id == id) { - if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) { + if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) { experimental = p; } else return p; @@ -1837,6 +1740,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) const AVCodec *p; char buf1[32]; int bitrate; + int new_line = 0; AVRational display_aspect_ratio; if (enc->codec) @@ -1869,15 +1773,48 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) if (profile) snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile); - if (enc->pix_fmt != AV_PIX_FMT_NONE) { + if (enc->codec_tag) { + char tag_buf[32]; + av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag); snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %s", + " [%s / 0x%04X]", tag_buf, enc->codec_tag); + } + + av_strlcat(buf, "\n ", buf_size); + snprintf(buf + strlen(buf), buf_size - strlen(buf), + "%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" : av_get_pix_fmt_name(enc->pix_fmt)); + + if (enc->color_range != AVCOL_RANGE_UNSPECIFIED) + snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %s", + av_color_range_name(enc->color_range)); + if (enc->colorspace != AVCOL_SPC_UNSPECIFIED || + enc->color_primaries != AVCOL_PRI_UNSPECIFIED || + enc->color_trc != AVCOL_TRC_UNSPECIFIED) { + new_line = 1; + snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %s/%s/%s", + av_color_space_name(enc->colorspace), + av_color_primaries_name(enc->color_primaries), + av_color_transfer_name(enc->color_trc)); } + if (av_log_get_level() >= AV_LOG_DEBUG && + enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) + snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %s", + av_chroma_location_name(enc->chroma_sample_location)); + if (enc->width) { + av_strlcat(buf, new_line ? "\n " : ", ", buf_size); + snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %dx%d", + "%dx%d", enc->width, enc->height); + + if (av_log_get_level() >= AV_LOG_VERBOSE && + (enc->width != enc->coded_width || + enc->height != enc->coded_height)) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " (%dx%d)", enc->coded_width, enc->coded_height); + if (enc->sample_aspect_ratio.num) { av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, enc->width * enc->sample_aspect_ratio.num, @@ -1907,11 +1844,18 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) if (profile) snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile); + if (enc->codec_tag) { + char tag_buf[32]; + av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag); + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " [%s / 0x%04X]", tag_buf, enc->codec_tag); + } + + av_strlcat(buf, "\n ", buf_size); if (enc->sample_rate) { snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d Hz", enc->sample_rate); + "%d Hz, ", enc->sample_rate); } - av_strlcat(buf, ", ", buf_size); av_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout); if (enc->sample_fmt != AV_SAMPLE_FMT_NONE) { snprintf(buf + strlen(buf), buf_size - strlen(buf), @@ -1932,10 +1876,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) return; } if (encode) { - if (enc->flags & CODEC_FLAG_PASS1) + if (enc->flags & AV_CODEC_FLAG_PASS1) snprintf(buf + strlen(buf), buf_size - strlen(buf), ", pass 1"); - if (enc->flags & CODEC_FLAG_PASS2) + if (enc->flags & AV_CODEC_FLAG_PASS2) snprintf(buf + strlen(buf), buf_size - strlen(buf), ", pass 2"); } @@ -2003,6 +1947,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) case AV_CODEC_ID_PCM_ZORK: return 8; case AV_CODEC_ID_PCM_S16BE: + case AV_CODEC_ID_PCM_S16BE_PLANAR: case AV_CODEC_ID_PCM_S16LE: case AV_CODEC_ID_PCM_S16LE_PLANAR: case AV_CODEC_ID_PCM_U16BE: @@ -2273,20 +2218,32 @@ AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel) int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) { if (lockmgr_cb) { - if (lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY)) - return -1; - if (lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY)) - return -1; + // There is no good way to rollback a failure to destroy the + // mutex, so we ignore failures. + lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY); + lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY); + lockmgr_cb = NULL; + codec_mutex = NULL; + avformat_mutex = NULL; + } + + if (cb) { + void *new_codec_mutex = NULL; + void *new_avformat_mutex = NULL; + int err; + if (err = cb(&new_codec_mutex, AV_LOCK_CREATE)) { + return err > 0 ? AVERROR_UNKNOWN : err; + } + if (err = cb(&new_avformat_mutex, AV_LOCK_CREATE)) { + // Ignore failures to destroy the newly created mutex. + cb(&new_codec_mutex, AV_LOCK_DESTROY); + return err > 0 ? AVERROR_UNKNOWN : err; + } + lockmgr_cb = cb; + codec_mutex = new_codec_mutex; + avformat_mutex = new_avformat_mutex; } - lockmgr_cb = cb; - - if (lockmgr_cb) { - if (lockmgr_cb(&codec_mutex, AV_LOCK_CREATE)) - return -1; - if (lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE)) - return -1; - } return 0; } @@ -2363,20 +2320,6 @@ void ff_thread_await_progress(ThreadFrame *f, int progress, int field) #endif -enum AVMediaType avcodec_get_type(enum AVCodecID codec_id) -{ - if (codec_id <= AV_CODEC_ID_NONE) - return AVMEDIA_TYPE_UNKNOWN; - else if (codec_id < AV_CODEC_ID_FIRST_AUDIO) - return AVMEDIA_TYPE_VIDEO; - else if (codec_id < AV_CODEC_ID_FIRST_SUBTITLE) - return AVMEDIA_TYPE_AUDIO; - else if (codec_id < AV_CODEC_ID_FIRST_UNKNOWN) - return AVMEDIA_TYPE_SUBTITLE; - - return AVMEDIA_TYPE_UNKNOWN; -} - int avcodec_is_open(AVCodecContext *s) { return !!s->internal;