X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Futils.c;h=a36e96087ef0c6c863c94edb5013d6cfd6087591;hb=3a651f599a18b023602370b67a77eb0efa309b20;hp=4253e8cf6c8214e0d89d7c577c78088db0b52fc5;hpb=d63443b9684fa7b3e086634f7b44b203b6d9221e;p=ffmpeg diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 4253e8cf6c8..a36e96087ef 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -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; @@ -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; } @@ -560,9 +561,16 @@ 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 }, + }; frame->color_primaries = avctx->color_primaries; frame->color_trc = avctx->color_trc; @@ -578,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; @@ -664,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 @@ -889,49 +895,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; } @@ -954,7 +1000,7 @@ AVFrame *avcodec_alloc_frame(void) { AVFrame *frame = av_mallocz(sizeof(AVFrame)); - if (frame == NULL) + if (!frame) return NULL; FF_DISABLE_DEPRECATION_WARNINGS @@ -1144,6 +1190,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 +1241,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 +1263,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--; @@ -1336,6 +1397,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) { @@ -1397,6 +1465,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; } @@ -1615,6 +1687,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; } @@ -1837,6 +1914,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 +1947,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 +2018,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), @@ -2273,20 +2391,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; }