X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Favcodec.c;h=c4083919bb9403cff23ebe1a7705e966c9934fd0;hb=d07534b5f5f20b4f780f5b0284aca6354da00695;hp=13fe3d4ebfe026def264cda58b6ec2e2389fa2c6;hpb=e3156fa7c2b85e9b8d1dfe6a92b0920624c0e65c;p=ffmpeg diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 13fe3d4ebfe..c4083919bb9 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -26,6 +26,7 @@ #include "config.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" #include "libavutil/opt.h" @@ -101,13 +102,6 @@ static void unlock_avcodec(const AVCodec *codec) ff_mutex_unlock(&codec_mutex); } -#if FF_API_LOCKMGR -int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) -{ - return 0; -} -#endif - static int64_t get_bit_rate(AVCodecContext *ctx) { int64_t bit_rate; @@ -187,15 +181,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code } avctx->internal = avci; -#if FF_API_OLD_ENCDEC - avci->to_free = av_frame_alloc(); - avci->compat_decode_frame = av_frame_alloc(); - avci->compat_encode_packet = av_packet_alloc(); - if (!avci->to_free || !avci->compat_decode_frame || !avci->compat_encode_packet) { - ret = AVERROR(ENOMEM); - goto free_and_end; - } -#endif avci->buffer_frame = av_frame_alloc(); avci->buffer_pkt = av_packet_alloc(); avci->es.in_frame = av_frame_alloc(); @@ -270,14 +255,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code ret = AVERROR(EINVAL); goto free_and_end; } - if (av_codec_is_decoder(codec) && - codec->type == AVMEDIA_TYPE_AUDIO && - !(codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF) && - avctx->channels == 0) { - av_log(avctx, AV_LOG_ERROR, "Decoder requires channel count but channels not set\n"); - ret = AVERROR(EINVAL); - goto free_and_end; - } if (avctx->sample_rate < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid sample rate: %d\n", avctx->sample_rate); @@ -315,6 +292,13 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code avctx->time_base.den = avctx->sample_rate; } + if (av_codec_is_encoder(avctx->codec)) + ret = ff_encode_preinit(avctx); + else + ret = ff_decode_preinit(avctx); + if (ret < 0) + goto free_and_end; + if (!HAVE_THREADS) av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n"); @@ -336,13 +320,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code if (!HAVE_THREADS && !(codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS)) avctx->thread_count = 1; - if (av_codec_is_encoder(avctx->codec)) - ret = ff_encode_preinit(avctx); - else - ret = ff_decode_preinit(avctx); - if (ret < 0) - goto free_and_end; - if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) || avci->frame_thread_encoder)) { ret = avctx->codec->init(avctx); @@ -406,6 +383,8 @@ free_and_end: avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP))) avctx->codec->close(avctx); + if (CONFIG_FRAME_THREAD_ENCODER && avci->frame_thread_encoder) + ff_frame_thread_encoder_free(avctx); if (HAVE_THREADS && avci->thread_ctx) ff_thread_free(avctx); @@ -414,24 +393,15 @@ free_and_end: av_opt_free(avctx); if (av_codec_is_encoder(avctx->codec)) { -#if FF_API_CODED_FRAME -FF_DISABLE_DEPRECATION_WARNINGS - av_frame_free(&avctx->coded_frame); -FF_ENABLE_DEPRECATION_WARNINGS -#endif av_freep(&avctx->extradata); avctx->extradata_size = 0; } av_dict_free(&tmp); av_freep(&avctx->priv_data); - av_freep(&avctx->subtitle_header); + if (av_codec_is_decoder(avctx->codec)) + av_freep(&avctx->subtitle_header); -#if FF_API_OLD_ENCDEC - av_frame_free(&avci->to_free); - av_frame_free(&avci->compat_decode_frame); - av_packet_free(&avci->compat_encode_packet); -#endif av_frame_free(&avci->buffer_frame); av_packet_free(&avci->buffer_pkt); av_packet_free(&avci->last_pkt_props); @@ -471,10 +441,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx) avci->draining_done = 0; avci->nb_draining_errors = 0; av_frame_unref(avci->buffer_frame); -#if FF_API_OLD_ENCDEC - av_frame_unref(avci->compat_decode_frame); - av_packet_unref(avci->compat_encode_packet); -#endif av_packet_unref(avci->buffer_pkt); av_packet_unref(avci->last_pkt_props); @@ -499,13 +465,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx) if (av_codec_is_decoder(avctx->codec)) av_bsf_flush(avci->bsf); - -#if FF_API_OLD_ENCDEC -FF_DISABLE_DEPRECATION_WARNINGS - if (!avctx->refcounted_frames) - av_frame_unref(avci->to_free); -FF_ENABLE_DEPRECATION_WARNINGS -#endif } void avsubtitle_free(AVSubtitle *sub) @@ -535,45 +494,39 @@ av_cold int avcodec_close(AVCodecContext *avctx) return 0; if (avcodec_is_open(avctx)) { + AVCodecInternal *avci = avctx->internal; + if (CONFIG_FRAME_THREAD_ENCODER && - avctx->internal->frame_thread_encoder && avctx->thread_count > 1) { + avci->frame_thread_encoder && avctx->thread_count > 1) { ff_frame_thread_encoder_free(avctx); } - if (HAVE_THREADS && avctx->internal->thread_ctx) + if (HAVE_THREADS && avci->thread_ctx) ff_thread_free(avctx); if (avctx->codec && avctx->codec->close) avctx->codec->close(avctx); - avctx->internal->byte_buffer_size = 0; - av_freep(&avctx->internal->byte_buffer); -#if FF_API_OLD_ENCDEC - av_frame_free(&avctx->internal->to_free); - av_frame_free(&avctx->internal->compat_decode_frame); - av_packet_free(&avctx->internal->compat_encode_packet); -#endif - av_frame_free(&avctx->internal->buffer_frame); - av_packet_free(&avctx->internal->buffer_pkt); - av_packet_unref(avctx->internal->last_pkt_props); - while (av_fifo_size(avctx->internal->pkt_props) >= - sizeof(*avctx->internal->last_pkt_props)) { - av_fifo_generic_read(avctx->internal->pkt_props, - avctx->internal->last_pkt_props, - sizeof(*avctx->internal->last_pkt_props), - NULL); - av_packet_unref(avctx->internal->last_pkt_props); + avci->byte_buffer_size = 0; + av_freep(&avci->byte_buffer); + av_frame_free(&avci->buffer_frame); + av_packet_free(&avci->buffer_pkt); + av_packet_unref(avci->last_pkt_props); + while (av_fifo_size(avci->pkt_props) >= sizeof(*avci->last_pkt_props)) { + av_fifo_generic_read(avci->pkt_props, avci->last_pkt_props, + sizeof(*avci->last_pkt_props), NULL); + av_packet_unref(avci->last_pkt_props); } - av_packet_free(&avctx->internal->last_pkt_props); - av_fifo_freep(&avctx->internal->pkt_props); + av_packet_free(&avci->last_pkt_props); + av_fifo_freep(&avci->pkt_props); - av_packet_free(&avctx->internal->ds.in_pkt); - av_frame_free(&avctx->internal->es.in_frame); + av_packet_free(&avci->ds.in_pkt); + av_frame_free(&avci->es.in_frame); - av_buffer_unref(&avctx->internal->pool); + av_buffer_unref(&avci->pool); if (avctx->hwaccel && avctx->hwaccel->uninit) avctx->hwaccel->uninit(avctx); - av_freep(&avctx->internal->hwaccel_priv_data); + av_freep(&avci->hwaccel_priv_data); - av_bsf_free(&avctx->internal->bsf); + av_bsf_free(&avci->bsf); av_freep(&avctx->internal); } @@ -592,84 +545,94 @@ av_cold int avcodec_close(AVCodecContext *avctx) av_freep(&avctx->priv_data); 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 - } + } else if (av_codec_is_decoder(avctx->codec)) + av_freep(&avctx->subtitle_header); + avctx->codec = NULL; avctx->active_thread_type = 0; return 0; } +static const char *unknown_if_null(const char *str) +{ + return str ? str : "unknown"; +} + void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { const char *codec_type; const char *codec_name; const char *profile = NULL; + AVBPrint bprint; int64_t bitrate; int new_line = 0; AVRational display_aspect_ratio; const char *separator = enc->dump_separator ? (const char *)enc->dump_separator : ", "; + const char *str; if (!buf || buf_size <= 0) return; + av_bprint_init_for_buffer(&bprint, buf, buf_size); codec_type = av_get_media_type_string(enc->codec_type); codec_name = avcodec_get_name(enc->codec_id); profile = avcodec_profile_name(enc->codec_id, enc->profile); - snprintf(buf, buf_size, "%s: %s", codec_type ? codec_type : "unknown", - codec_name); + av_bprintf(&bprint, "%s: %s", codec_type ? codec_type : "unknown", + codec_name); buf[0] ^= 'a' ^ 'A'; /* first letter in uppercase */ if (enc->codec && strcmp(enc->codec->name, codec_name)) - snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", enc->codec->name); + av_bprintf(&bprint, " (%s)", enc->codec->name); if (profile) - snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile); + av_bprintf(&bprint, " (%s)", profile); if ( enc->codec_type == AVMEDIA_TYPE_VIDEO && av_log_get_level() >= AV_LOG_VERBOSE && enc->refs) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d reference frame%s", - enc->refs, enc->refs > 1 ? "s" : ""); + av_bprintf(&bprint, ", %d reference frame%s", + enc->refs, enc->refs > 1 ? "s" : ""); if (enc->codec_tag) - snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s / 0x%04X)", - av_fourcc2str(enc->codec_tag), enc->codec_tag); + av_bprintf(&bprint, " (%s / 0x%04X)", + av_fourcc2str(enc->codec_tag), enc->codec_tag); switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: { - char detail[256] = "("; + unsigned len; + + av_bprintf(&bprint, "%s%s", separator, + enc->pix_fmt == AV_PIX_FMT_NONE ? "none" : + unknown_if_null(av_get_pix_fmt_name(enc->pix_fmt))); + + av_bprint_chars(&bprint, '(', 1); + len = bprint.len; - av_strlcat(buf, separator, buf_size); + /* The following check ensures that '(' has been written + * and therefore allows us to erase it if it turns out + * to be unnecessary. */ + if (!av_bprint_is_complete(&bprint)) + return; - 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->bits_per_raw_sample && enc->pix_fmt != AV_PIX_FMT_NONE && enc->bits_per_raw_sample < av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth) - av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample); - if (enc->color_range != AVCOL_RANGE_UNSPECIFIED) - av_strlcatf(detail, sizeof(detail), "%s, ", - av_color_range_name(enc->color_range)); + av_bprintf(&bprint, "%d bpc, ", enc->bits_per_raw_sample); + if (enc->color_range != AVCOL_RANGE_UNSPECIFIED && + (str = av_color_range_name(enc->color_range))) + av_bprintf(&bprint, "%s, ", str); if (enc->colorspace != AVCOL_SPC_UNSPECIFIED || enc->color_primaries != AVCOL_PRI_UNSPECIFIED || enc->color_trc != AVCOL_TRC_UNSPECIFIED) { - if (enc->colorspace != (int)enc->color_primaries || - enc->colorspace != (int)enc->color_trc) { + const char *col = unknown_if_null(av_color_space_name(enc->colorspace)); + const char *pri = unknown_if_null(av_color_primaries_name(enc->color_primaries)); + const char *trc = unknown_if_null(av_color_transfer_name(enc->color_trc)); + if (strcmp(col, pri) || strcmp(col, trc)) { new_line = 1; - av_strlcatf(detail, sizeof(detail), "%s/%s/%s, ", - av_color_space_name(enc->colorspace), - av_color_primaries_name(enc->color_primaries), - av_color_transfer_name(enc->color_trc)); + av_bprintf(&bprint, "%s/%s/%s, ", col, pri, trc); } else - av_strlcatf(detail, sizeof(detail), "%s, ", - av_get_colorspace_name(enc->colorspace)); + av_bprintf(&bprint, "%s, ", col); } if (enc->field_order != AV_FIELD_UNKNOWN) { @@ -683,119 +646,108 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) else if (enc->field_order == AV_FIELD_BT) field_order = "bottom coded first (swapped)"; - av_strlcatf(detail, sizeof(detail), "%s, ", field_order); + av_bprintf(&bprint, "%s, ", field_order); } if (av_log_get_level() >= AV_LOG_VERBOSE && - enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) - av_strlcatf(detail, sizeof(detail), "%s, ", - av_chroma_location_name(enc->chroma_sample_location)); - - if (strlen(detail) > 1) { - detail[strlen(detail) - 2] = 0; - av_strlcatf(buf, buf_size, "%s)", detail); + enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED && + (str = av_chroma_location_name(enc->chroma_sample_location))) + av_bprintf(&bprint, "%s, ", str); + + if (len == bprint.len) { + bprint.str[len - 1] = '\0'; + bprint.len--; + } else { + if (bprint.len - 2 < bprint.size) { + /* Erase the last ", " */ + bprint.len -= 2; + bprint.str[bprint.len] = '\0'; + } + av_bprint_chars(&bprint, ')', 1); } } if (enc->width) { - av_strlcat(buf, new_line ? separator : ", ", buf_size); - - snprintf(buf + strlen(buf), buf_size - strlen(buf), - "%dx%d", - enc->width, enc->height); + av_bprintf(&bprint, "%s%dx%d", new_line ? separator : ", ", + 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); + av_bprintf(&bprint, " (%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 * (int64_t)enc->sample_aspect_ratio.num, enc->height * (int64_t)enc->sample_aspect_ratio.den, 1024 * 1024); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " [SAR %d:%d DAR %d:%d]", + av_bprintf(&bprint, " [SAR %d:%d DAR %d:%d]", enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den, display_aspect_ratio.num, display_aspect_ratio.den); } if (av_log_get_level() >= AV_LOG_DEBUG) { int g = av_gcd(enc->time_base.num, enc->time_base.den); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d/%d", - enc->time_base.num / g, enc->time_base.den / g); + av_bprintf(&bprint, ", %d/%d", + enc->time_base.num / g, enc->time_base.den / g); } } if (encode) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", q=%d-%d", enc->qmin, enc->qmax); + av_bprintf(&bprint, ", q=%d-%d", enc->qmin, enc->qmax); } else { if (enc->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", Closed Captions"); + av_bprintf(&bprint, ", Closed Captions"); if (enc->properties & FF_CODEC_PROPERTY_LOSSLESS) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", lossless"); + av_bprintf(&bprint, ", lossless"); } break; case AVMEDIA_TYPE_AUDIO: - av_strlcat(buf, separator, buf_size); + av_bprintf(&bprint, "%s", separator); if (enc->sample_rate) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - "%d Hz, ", enc->sample_rate); + av_bprintf(&bprint, "%d Hz, ", enc->sample_rate); } - 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), - ", %s", av_get_sample_fmt_name(enc->sample_fmt)); + av_bprint_channel_layout(&bprint, enc->channels, enc->channel_layout); + if (enc->sample_fmt != AV_SAMPLE_FMT_NONE && + (str = av_get_sample_fmt_name(enc->sample_fmt))) { + av_bprintf(&bprint, ", %s", str); } if ( enc->bits_per_raw_sample > 0 && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%d bit)", enc->bits_per_raw_sample); + av_bprintf(&bprint, " (%d bit)", enc->bits_per_raw_sample); if (av_log_get_level() >= AV_LOG_VERBOSE) { if (enc->initial_padding) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", delay %d", enc->initial_padding); + av_bprintf(&bprint, ", delay %d", enc->initial_padding); if (enc->trailing_padding) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", padding %d", enc->trailing_padding); + av_bprintf(&bprint, ", padding %d", enc->trailing_padding); } break; case AVMEDIA_TYPE_DATA: if (av_log_get_level() >= AV_LOG_DEBUG) { int g = av_gcd(enc->time_base.num, enc->time_base.den); if (g) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d/%d", - enc->time_base.num / g, enc->time_base.den / g); + av_bprintf(&bprint, ", %d/%d", + enc->time_base.num / g, enc->time_base.den / g); } break; case AVMEDIA_TYPE_SUBTITLE: if (enc->width) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %dx%d", enc->width, enc->height); + av_bprintf(&bprint, ", %dx%d", enc->width, enc->height); break; default: return; } if (encode) { if (enc->flags & AV_CODEC_FLAG_PASS1) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", pass 1"); + av_bprintf(&bprint, ", pass 1"); if (enc->flags & AV_CODEC_FLAG_PASS2) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", pass 2"); + av_bprintf(&bprint, ", pass 2"); } bitrate = get_bit_rate(enc); if (bitrate != 0) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %"PRId64" kb/s", bitrate / 1000); + av_bprintf(&bprint, ", %"PRId64" kb/s", bitrate / 1000); } else if (enc->rc_max_rate > 0) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", max. %"PRId64" kb/s", enc->rc_max_rate / 1000); + av_bprintf(&bprint, ", max. %"PRId64" kb/s", enc->rc_max_rate / 1000); } }