X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Futils.c;h=e8848f66094be4d35216245a9050b7d3d9a1c6a1;hb=40cf1bbacc6220a0aa6bed5c331871d43f9ce370;hp=d6019d957f7d8b4af0ff2c168c3eac4a0c900169;hpb=1b04eb20f7e3f0a71f73ba91efcc3d60a435e443;p=ffmpeg diff --git a/libavcodec/utils.c b/libavcodec/utils.c index d6019d957f7..e8848f66094 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -39,8 +39,9 @@ #include "libavutil/samplefmt.h" #include "libavutil/dict.h" #include "avcodec.h" -#include "dsputil.h" #include "libavutil/opt.h" +#include "me_cmp.h" +#include "mpegvideo.h" #include "thread.h" #include "internal.h" #include "bytestream.h" @@ -55,18 +56,6 @@ static int (*lockmgr_cb)(void **mutex, enum AVLockOp op); static void *codec_mutex; static void *avformat_mutex; -#if FF_API_FAST_MALLOC && CONFIG_SHARED && HAVE_SYMVER -FF_SYMVER(void*, av_fast_realloc, (void *ptr, unsigned int *size, size_t min_size), "LIBAVCODEC_55") -{ - return av_fast_realloc(ptr, size, min_size); -} - -FF_SYMVER(void, av_fast_malloc, (void *ptr, unsigned int *size, size_t min_size), "LIBAVCODEC_55") -{ - av_fast_malloc(ptr, size, min_size); -} -#endif - void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size) { void **p = ptr; @@ -99,8 +88,8 @@ static av_cold void avcodec_init(void) return; initialized = 1; - if (CONFIG_DSPUTIL) - ff_dsputil_static_init(); + if (CONFIG_ME_CMP) + ff_me_cmp_init_static(); } int av_codec_is_encoder(const AVCodec *codec) @@ -118,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; @@ -158,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; @@ -188,7 +177,7 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame, return 0; } -#if HAVE_NEON || ARCH_PPC || HAVE_MMX +#if HAVE_SIMD_ALIGN_16 # define STRIDE_ALIGN 16 #else # define STRIDE_ALIGN 8 @@ -210,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: @@ -484,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; } @@ -571,17 +561,22 @@ FF_ENABLE_DEPRECATION_WARNINGS 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 }, + }; -#if FF_API_AVFRAME_COLORSPACE frame->color_primaries = avctx->color_primaries; frame->color_trc = avctx->color_trc; frame->colorspace = avctx->colorspace; frame->color_range = avctx->color_range; frame->chroma_location = avctx->chroma_sample_location; -#endif frame->reordered_opaque = avctx->reordered_opaque; if (!pkt) { @@ -591,23 +586,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; @@ -677,10 +667,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 (hwaccel) { + if (hwaccel->alloc_frame) { + ret = hwaccel->alloc_frame(avctx, frame); + goto end; + } + } else + avctx->sw_pix_fmt = avctx->pix_fmt; #if FF_API_GET_BUFFER FF_DISABLE_DEPRECATION_WARNINGS @@ -734,6 +727,7 @@ do { \ ref_out = av_buffer_create(data, data_size, compat_release_buffer, \ dummy_ref, 0); \ if (!ref_out) { \ + av_buffer_unref(&dummy_ref); \ av_frame_unref(frame); \ ret = AVERROR(ENOMEM); \ goto fail; \ @@ -902,49 +896,89 @@ static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, return NULL; } +static int setup_hwaccel(AVCodecContext *avctx, + const enum AVPixelFormat fmt, + const char *name) +{ + AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt); + int ret = 0; + + if (!hwa) { + av_log(avctx, AV_LOG_ERROR, + "Could not find an AVHWAccel for the pixel format: %s", + name); + return AVERROR(ENOENT); + } + + 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 (hwa->init) { + ret = hwa->init(avctx); + if (ret < 0) { + av_freep(&avctx->internal->hwaccel_priv_data); + return ret; + } + } + + avctx->hwaccel = hwa; + + return 0; +} int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) { const AVPixFmtDescriptor *desc; - enum AVPixelFormat ret = avctx->get_format(avctx, fmt); + enum AVPixelFormat *choices; + enum AVPixelFormat ret; + unsigned n = 0; + + while (fmt[n] != AV_PIX_FMT_NONE) + ++n; + + av_assert0(n >= 1); + avctx->sw_pix_fmt = fmt[n - 1]; + av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); - desc = av_pix_fmt_desc_get(ret); - if (!desc) + choices = av_malloc_array(n + 1, sizeof(*choices)); + if (!choices) 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; + memcpy(choices, fmt, (n + 1) * sizeof(*choices)); - if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { - AVHWAccel *hwaccel; - int err; + for (;;) { + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; - 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; - } + ret = avctx->get_format(avctx, choices); - 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; + desc = av_pix_fmt_desc_get(ret); + if (!desc) { + ret = AV_PIX_FMT_NONE; + break; } - if (hwaccel->init) { - err = hwaccel->init(avctx); - if (err < 0) { - av_freep(&avctx->internal->hwaccel_priv_data); - return AV_PIX_FMT_NONE; - } - } - avctx->hwaccel = hwaccel; + 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; } @@ -967,7 +1001,7 @@ AVFrame *avcodec_alloc_frame(void) { AVFrame *frame = av_mallocz(sizeof(AVFrame)); - if (frame == NULL) + if (!frame) return NULL; FF_DISABLE_DEPRECATION_WARNINGS @@ -1016,8 +1050,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; } @@ -1131,6 +1169,15 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code 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]) @@ -1157,6 +1204,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++) @@ -1203,6 +1255,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) { @@ -1220,6 +1277,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--; @@ -1235,6 +1297,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) { @@ -1349,6 +1425,13 @@ 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) { @@ -1410,6 +1493,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; } @@ -1628,6 +1715,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; } @@ -1720,7 +1812,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]); @@ -1737,8 +1828,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; @@ -1850,6 +1947,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) @@ -1882,15 +1980,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, @@ -1920,11 +2051,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), @@ -2016,6 +2154,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: @@ -2278,7 +2417,7 @@ void av_register_hwaccel(AVHWAccel *hwaccel) hwaccel->next = NULL; } -AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel) +AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel) { return hwaccel ? hwaccel->next : first_hwaccel; } @@ -2286,20 +2425,32 @@ AVHWAccel *av_hwaccel_next(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; }