int lag_in_frames;
int error_resilient;
int crf;
+ int static_thresh;
} VP8Context;
/** String mappings for enum vp8e_enc_control_id */
vpx_codec_destroy(&ctx->encoder);
av_freep(&ctx->twopass_stats.buf);
- av_freep(&avctx->coded_frame);
av_freep(&avctx->stats_out);
free_frame_list(ctx->coded_frame_list);
return 0;
const struct vpx_codec_iface *iface)
{
VP8Context *ctx = avctx->priv_data;
- struct vpx_codec_enc_cfg enccfg;
+ struct vpx_codec_enc_cfg enccfg = { 0 };
int res;
av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
if (ctx->lag_in_frames >= 0)
enccfg.g_lag_in_frames = ctx->lag_in_frames;
- if (avctx->flags & CODEC_FLAG_PASS1)
+ if (avctx->flags & AV_CODEC_FLAG_PASS1)
enccfg.g_pass = VPX_RC_FIRST_PASS;
- else if (avctx->flags & CODEC_FLAG_PASS2)
+ else if (avctx->flags & AV_CODEC_FLAG_PASS2)
enccfg.g_pass = VPX_RC_LAST_PASS;
else
enccfg.g_pass = VPX_RC_ONE_PASS;
if (enccfg.g_pass == VPX_RC_FIRST_PASS)
enccfg.g_lag_in_frames = 0;
else if (enccfg.g_pass == VPX_RC_LAST_PASS) {
- int decode_size;
+ int decode_size, ret;
if (!avctx->stats_in) {
av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n");
}
ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4;
- ctx->twopass_stats.buf = av_malloc(ctx->twopass_stats.sz);
- if (!ctx->twopass_stats.buf) {
+ ret = av_reallocp(&ctx->twopass_stats.buf, ctx->twopass_stats.sz);
+ if (ret < 0) {
av_log(avctx, AV_LOG_ERROR,
"Stat buffer alloc (%zu bytes) failed\n",
ctx->twopass_stats.sz);
- return AVERROR(ENOMEM);
+ return ret;
}
decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in,
ctx->twopass_stats.sz);
/* 0-3: For non-zero values the encoder increasingly optimizes for reduced
complexity playback on low powered devices at the expense of encode
quality. */
- if (avctx->profile != FF_PROFILE_UNKNOWN)
- enccfg.g_profile = avctx->profile;
+ if (avctx->profile != FF_PROFILE_UNKNOWN)
+ enccfg.g_profile = avctx->profile;
+ else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P)
+ avctx->profile = enccfg.g_profile = FF_PROFILE_VP9_0;
+ else
+ avctx->profile = enccfg.g_profile = FF_PROFILE_VP9_1;
enccfg.g_error_resilient = ctx->error_resilient;
codecctl_int(avctx, VP8E_SET_ARNR_STRENGTH, ctx->arnr_strength);
if (ctx->arnr_type >= 0)
codecctl_int(avctx, VP8E_SET_ARNR_TYPE, ctx->arnr_type);
- codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction);
- codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices));
- codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD, avctx->mb_threshold);
+
+ if (CONFIG_LIBVPX_VP8_ENCODER && iface == &vpx_codec_vp8_cx_algo) {
+ codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction);
+ codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices));
+ }
+#if FF_API_MPV_OPT
+ FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->mb_threshold) {
+ av_log(avctx, AV_LOG_WARNING, "The mb_threshold option is deprecated, "
+ "use the static-thresh private option instead.\n");
+ ctx->static_thresh = avctx->mb_threshold;
+ }
+ FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD, ctx->static_thresh);
codecctl_int(avctx, VP8E_SET_CQ_LEVEL, ctx->crf);
//provide dummy value to initialize wrapper, values will be updated each _encode()
- vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
- (unsigned char*)1);
-
- avctx->coded_frame = av_frame_alloc();
- if (!avctx->coded_frame) {
- av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
- vp8_free(avctx);
- return AVERROR(ENOMEM);
- }
+ vpx_img_wrap(&ctx->rawimg, ff_vpx_pixfmt_to_imgfmt(avctx->pix_fmt),
+ avctx->width, avctx->height, 1, (unsigned char *)1);
+
return 0;
}
* @return a negative AVERROR on error
*/
static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
- AVPacket *pkt, AVFrame *coded_frame)
+ AVPacket *pkt)
{
int ret = ff_alloc_packet(pkt, cx_frame->sz);
if (ret >= 0) {
memcpy(pkt->data, cx_frame->buf, pkt->size);
- pkt->pts = pkt->dts = cx_frame->pts;
- coded_frame->pts = cx_frame->pts;
- coded_frame->key_frame = !!(cx_frame->flags & VPX_FRAME_IS_KEY);
-
- if (coded_frame->key_frame) {
- coded_frame->pict_type = AV_PICTURE_TYPE_I;
- pkt->flags |= AV_PKT_FLAG_KEY;
- } else
- coded_frame->pict_type = AV_PICTURE_TYPE_P;
+ pkt->pts = pkt->dts = cx_frame->pts;
+#if FF_API_CODED_FRAME
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->coded_frame->pts = cx_frame->pts;
+ avctx->coded_frame->key_frame = !!(cx_frame->flags & VPX_FRAME_IS_KEY);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ if (!!(cx_frame->flags & VPX_FRAME_IS_KEY)) {
+#if FF_API_CODED_FRAME
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ } else {
+#if FF_API_CODED_FRAME
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ }
} else {
av_log(avctx, AV_LOG_ERROR,
"Error getting output packet of size %zu.\n", cx_frame->sz);
* @return AVERROR(EINVAL) on output size error
* @return AVERROR(ENOMEM) on coded frame queue data allocation error
*/
-static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out,
- AVFrame *coded_frame)
+static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out)
{
VP8Context *ctx = avctx->priv_data;
const struct vpx_codec_cx_pkt *pkt;
if (ctx->coded_frame_list) {
struct FrameListData *cx_frame = ctx->coded_frame_list;
/* return the leading frame if we've already begun queueing */
- size = storeframe(avctx, cx_frame, pkt_out, coded_frame);
+ size = storeframe(avctx, cx_frame, pkt_out);
if (size < 0)
return size;
ctx->coded_frame_list = cx_frame->next;
provided a frame for output */
assert(!ctx->coded_frame_list);
cx_pktcpy(&cx_frame, pkt);
- size = storeframe(avctx, &cx_frame, pkt_out, coded_frame);
+ size = storeframe(avctx, &cx_frame, pkt_out);
if (size < 0)
return size;
} else {
av_log(avctx, AV_LOG_ERROR,
"Data buffer alloc (%zu bytes) failed\n",
cx_frame->sz);
+ av_freep(&cx_frame);
return AVERROR(ENOMEM);
}
memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz);
stats->sz += pkt->data.twopass_stats.sz;
break;
}
- case VPX_CODEC_PSNR_PKT: //FIXME add support for CODEC_FLAG_PSNR
+ case VPX_CODEC_PSNR_PKT: //FIXME add support for AV_CODEC_FLAG_PSNR
case VPX_CODEC_CUSTOM_PKT:
//ignore unsupported/unrecognized packet types
break;
log_encoder_error(avctx, "Error encoding frame");
return AVERROR_INVALIDDATA;
}
- coded_size = queue_frames(avctx, pkt, avctx->coded_frame);
+ coded_size = queue_frames(avctx, pkt);
- if (!frame && avctx->flags & CODEC_FLAG_PASS1) {
+ if (!frame && avctx->flags & AV_CODEC_FLAG_PASS1) {
unsigned int b64_size = AV_BASE64_SIZE(ctx->twopass_stats.sz);
avctx->stats_out = av_malloc(b64_size);
" is still done over the partition boundary.", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"},
#endif
{ "crf", "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE },
+ { "static-thresh", "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
{ NULL }
};
.init = vp8_init,
.encode2 = vp8_encode,
.close = vp8_free,
- .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.priv_class = &class_vp8,
.defaults = defaults,
#if CONFIG_LIBVPX_VP9_ENCODER
static av_cold int vp9_init(AVCodecContext *avctx)
{
- int ret;
- if ((ret = ff_vp9_check_experimental(avctx)))
- return ret;
return vpx_init(avctx, &vpx_codec_vp9_cx_algo);
}
.version = LIBAVUTIL_VERSION_INT,
};
+static const AVProfile profiles[] = {
+ { FF_PROFILE_VP9_0, "Profile 0" },
+ { FF_PROFILE_VP9_1, "Profile 1" },
+ { FF_PROFILE_VP9_2, "Profile 2" },
+ { FF_PROFILE_VP9_3, "Profile 3" },
+ { FF_PROFILE_UNKNOWN },
+};
+
AVCodec ff_libvpx_vp9_encoder = {
.name = "libvpx-vp9",
.long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"),
.init = vp9_init,
.encode2 = vp8_encode,
.close = vp8_free,
- .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
- .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+#if VPX_IMAGE_ABI_VERSION >= 3
+ AV_PIX_FMT_YUV422P,
+ AV_PIX_FMT_YUV444P,
+ AV_PIX_FMT_YUV440P,
+#endif
+ AV_PIX_FMT_NONE,
+ },
+ .profiles = NULL_IF_CONFIG_SMALL(profiles),
.priv_class = &class_vp9,
.defaults = defaults,
};