static av_cold int libkvazaar_init(AVCodecContext *avctx) { LibkvazaarContext *const ctx = avctx->priv_data; const kvz_api *const api = ctx->api = kvz_api_get(8); kvz_config *cfg = NULL; kvz_encoder *enc = NULL; /* Kvazaar requires width and height to be multiples of eight. */ if (avctx->width % 8 || avctx->height % 8) { av_log(avctx, AV_LOG_ERROR, "Video dimensions are not a multiple of 8 (%dx%d).\n", avctx->width, avctx->height); return AVERROR(ENOSYS); } ctx->config = cfg = api->config_alloc(); if (!cfg) { av_log(avctx, AV_LOG_ERROR, "Could not allocate kvazaar config structure.\n"); return AVERROR(ENOMEM); } if (!api->config_init(cfg)) { av_log(avctx, AV_LOG_ERROR, "Could not initialize kvazaar config structure.\n"); return AVERROR_BUG; } cfg->width = avctx->width; cfg->height = avctx->height; if (avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { av_log(avctx, AV_LOG_ERROR, "Could not set framerate for kvazaar: integer overflow\n"); return AVERROR(EINVAL); } cfg->framerate_num = avctx->time_base.den; cfg->framerate_denom = avctx->time_base.num * avctx->ticks_per_frame; cfg->target_bitrate = avctx->bit_rate; cfg->vui.sar_width = avctx->sample_aspect_ratio.num; cfg->vui.sar_height = avctx->sample_aspect_ratio.den; if (ctx->kvz_params) { AVDictionary *dict = NULL; if (!av_dict_parse_string(&dict, ctx->kvz_params, "=", ",", 0)) { AVDictionaryEntry *entry = NULL; while ((entry = av_dict_get(dict, "", entry, AV_DICT_IGNORE_SUFFIX))) { if (!api->config_parse(cfg, entry->key, entry->value)) { av_log(avctx, AV_LOG_WARNING, "Invalid option: %s=%s.\n", entry->key, entry->value); } } av_dict_free(&dict); } } ctx->encoder = enc = api->encoder_open(cfg); if (!enc) { av_log(avctx, AV_LOG_ERROR, "Could not open kvazaar encoder.\n"); return AVERROR_BUG; } if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { kvz_data_chunk *data_out = NULL; kvz_data_chunk *chunk = NULL; uint32_t len_out; uint8_t *p; if (!api->encoder_headers(enc, &data_out, &len_out)) return AVERROR(ENOMEM); avctx->extradata = p = av_mallocz(len_out + AV_INPUT_BUFFER_PADDING_SIZE); if (!p) { ctx->api->chunk_free(data_out); return AVERROR(ENOMEM); } avctx->extradata_size = len_out; for (chunk = data_out; chunk != NULL; chunk = chunk->next) { memcpy(p, chunk->data, chunk->len); p += chunk->len; } ctx->api->chunk_free(data_out); } return 0; }
static av_cold int libkvazaar_init(AVCodecContext *avctx) { int retval = 0; kvz_config *cfg = NULL; kvz_encoder *enc = NULL; const kvz_api *const api = kvz_api_get(8); LibkvazaarContext *const ctx = avctx->priv_data; // Kvazaar requires width and height to be multiples of eight. if (avctx->width % 8 || avctx->height % 8) { av_log(avctx, AV_LOG_ERROR, "Video dimensions are not a multiple of 8.\n"); retval = AVERROR_INVALIDDATA; goto done; } cfg = api->config_alloc(); if (!cfg) { av_log(avctx, AV_LOG_ERROR, "Could not allocate kvazaar config structure.\n"); retval = AVERROR(ENOMEM); goto done; } if (!api->config_init(cfg)) { av_log(avctx, AV_LOG_ERROR, "Could not initialize kvazaar config structure.\n"); retval = AVERROR_EXTERNAL; goto done; } cfg->width = avctx->width; cfg->height = avctx->height; cfg->framerate = avctx->time_base.den / (double)(avctx->time_base.num * avctx->ticks_per_frame); cfg->target_bitrate = avctx->bit_rate; cfg->vui.sar_width = avctx->sample_aspect_ratio.num; cfg->vui.sar_height = avctx->sample_aspect_ratio.den; if (ctx->kvz_params) { AVDictionary *dict = NULL; if (!av_dict_parse_string(&dict, ctx->kvz_params, "=", ",", 0)) { AVDictionaryEntry *entry = NULL; while ((entry = av_dict_get(dict, "", entry, AV_DICT_IGNORE_SUFFIX))) { if (!api->config_parse(cfg, entry->key, entry->value)) { av_log(avctx, AV_LOG_WARNING, "Invalid option: %s=%s.\n", entry->key, entry->value); } } av_dict_free(&dict); } } enc = api->encoder_open(cfg); if (!enc) { av_log(avctx, AV_LOG_ERROR, "Could not open kvazaar encoder.\n"); retval = AVERROR_EXTERNAL; goto done; } ctx->api = api; ctx->encoder = enc; ctx->config = cfg; enc = NULL; cfg = NULL; done: api->config_destroy(cfg); api->encoder_close(enc); return retval; }