mirror of https://git.ffmpeg.org/ffmpeg.git
avcodec/libaomenc: support AV_CODEC_CAP_ENCODER_RECON_FRAME
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
c6f22940e4
commit
b0cd979a0b
|
@ -1055,8 +1055,8 @@ OBJS-$(CONFIG_ALAC_AT_ENCODER) += audiotoolboxenc.o
|
|||
OBJS-$(CONFIG_ILBC_AT_ENCODER) += audiotoolboxenc.o
|
||||
OBJS-$(CONFIG_PCM_ALAW_AT_ENCODER) += audiotoolboxenc.o
|
||||
OBJS-$(CONFIG_PCM_MULAW_AT_ENCODER) += audiotoolboxenc.o
|
||||
OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o
|
||||
OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o
|
||||
OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o libaom.o
|
||||
OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o libaom.o
|
||||
OBJS-$(CONFIG_LIBARIBB24_DECODER) += libaribb24.o ass.o
|
||||
OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o
|
||||
OBJS-$(CONFIG_LIBCODEC2_DECODER) += libcodec2.o
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* AOM common functions
|
||||
*/
|
||||
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libaom.h"
|
||||
|
||||
void ff_aom_image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
|
||||
{
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < desc->nb_components; i++) {
|
||||
int w = img->d_w;
|
||||
int h = img->d_h;
|
||||
int x, y;
|
||||
|
||||
if (i) {
|
||||
w = (w + img->x_chroma_shift) >> img->x_chroma_shift;
|
||||
h = (h + img->y_chroma_shift) >> img->y_chroma_shift;
|
||||
}
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
uint16_t *src = (uint16_t *)(img->planes[i] + y * img->stride[i]);
|
||||
uint8_t *dst = pic->data[i] + y * pic->linesize[i];
|
||||
for (x = 0; x < w; x++)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* AOM common functions
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_LIBAOM_H
|
||||
#define AVCODEC_LIBAOM_H
|
||||
|
||||
#include <aom/aom_image.h>
|
||||
|
||||
#include "libavutil/frame.h"
|
||||
|
||||
void ff_aom_image_copy_16_to_8(AVFrame *pic, struct aom_image *img);
|
||||
|
||||
#endif /* AVCODEC_LIBAOM_H */
|
|
@ -33,6 +33,7 @@
|
|||
#include "avcodec.h"
|
||||
#include "codec_internal.h"
|
||||
#include "internal.h"
|
||||
#include "libaom.h"
|
||||
#include "profiles.h"
|
||||
|
||||
typedef struct AV1DecodeContext {
|
||||
|
@ -60,30 +61,6 @@ static av_cold int aom_init(AVCodecContext *avctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void image_copy_16_to_8(AVFrame *pic, struct aom_image *img)
|
||||
{
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < desc->nb_components; i++) {
|
||||
int w = img->d_w;
|
||||
int h = img->d_h;
|
||||
int x, y;
|
||||
|
||||
if (i) {
|
||||
w = (w + img->x_chroma_shift) >> img->x_chroma_shift;
|
||||
h = (h + img->y_chroma_shift) >> img->y_chroma_shift;
|
||||
}
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
uint16_t *src = (uint16_t *)(img->planes[i] + y * img->stride[i]);
|
||||
uint8_t *dst = pic->data[i] + y * pic->linesize[i];
|
||||
for (x = 0; x < w; x++)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns 0 on success, AVERROR_INVALIDDATA otherwise
|
||||
static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img)
|
||||
{
|
||||
|
@ -223,7 +200,7 @@ static int aom_decode(AVCodecContext *avctx, AVFrame *picture,
|
|||
ff_set_sar(avctx, picture->sample_aspect_ratio);
|
||||
|
||||
if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img->bit_depth == 8)
|
||||
image_copy_16_to_8(picture, img);
|
||||
ff_aom_image_copy_16_to_8(picture, img);
|
||||
else {
|
||||
const uint8_t *planes[4] = { img->planes[0], img->planes[1], img->planes[2] };
|
||||
const int stride[4] = { img->stride[0], img->stride[1], img->stride[2] };
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "libavutil/base64.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/cpu.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
|
@ -41,6 +42,7 @@
|
|||
#include "codec_internal.h"
|
||||
#include "encode.h"
|
||||
#include "internal.h"
|
||||
#include "libaom.h"
|
||||
#include "packet_internal.h"
|
||||
#include "profiles.h"
|
||||
|
||||
|
@ -208,6 +210,7 @@ static const char *const ctlidstr[] = {
|
|||
#ifdef AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX
|
||||
[AV1E_GET_TARGET_SEQ_LEVEL_IDX] = "AV1E_GET_TARGET_SEQ_LEVEL_IDX",
|
||||
#endif
|
||||
[AV1_GET_NEW_FRAME_IMAGE] = "AV1_GET_NEW_FRAME_IMAGE",
|
||||
};
|
||||
|
||||
static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
|
||||
|
@ -364,6 +367,31 @@ static av_cold int codecctl_intp(AVCodecContext *avctx,
|
|||
}
|
||||
#endif
|
||||
|
||||
static av_cold int codecctl_imgp(AVCodecContext *avctx,
|
||||
#ifdef UENUM1BYTE
|
||||
aome_enc_control_id id,
|
||||
#else
|
||||
enum aome_enc_control_id id,
|
||||
#endif
|
||||
struct aom_image *img)
|
||||
{
|
||||
AOMContext *ctx = avctx->priv_data;
|
||||
char buf[80];
|
||||
int res;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]);
|
||||
|
||||
res = aom_codec_control(&ctx->encoder, id, img);
|
||||
if (res != AOM_CODEC_OK) {
|
||||
snprintf(buf, sizeof(buf), "Failed to get %s codec control",
|
||||
ctlidstr[id]);
|
||||
log_encoder_error(avctx, buf);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int aom_free(AVCodecContext *avctx)
|
||||
{
|
||||
AOMContext *ctx = avctx->priv_data;
|
||||
|
@ -1206,6 +1234,37 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out)
|
|||
return size;
|
||||
}
|
||||
|
||||
static enum AVPixelFormat aomfmt_to_pixfmt(struct aom_image *img)
|
||||
{
|
||||
switch (img->fmt) {
|
||||
case AOM_IMG_FMT_I420:
|
||||
case AOM_IMG_FMT_I42016:
|
||||
if (img->bit_depth == 8)
|
||||
return img->monochrome ? AV_PIX_FMT_GRAY8 : AV_PIX_FMT_YUV420P;
|
||||
else if (img->bit_depth == 10)
|
||||
return img->monochrome ? AV_PIX_FMT_GRAY10 : AV_PIX_FMT_YUV420P10;
|
||||
else
|
||||
return img->monochrome ? AV_PIX_FMT_GRAY12 : AV_PIX_FMT_YUV420P12;
|
||||
case AOM_IMG_FMT_I422:
|
||||
case AOM_IMG_FMT_I42216:
|
||||
if (img->bit_depth == 8)
|
||||
return AV_PIX_FMT_YUV422P;
|
||||
else if (img->bit_depth == 10)
|
||||
return AV_PIX_FMT_YUV422P10;
|
||||
else
|
||||
return AV_PIX_FMT_YUV422P12;
|
||||
case AOM_IMG_FMT_I444:
|
||||
case AOM_IMG_FMT_I44416:
|
||||
if (img->bit_depth == 8)
|
||||
return AV_PIX_FMT_YUV444P;
|
||||
else if (img->bit_depth == 10)
|
||||
return AV_PIX_FMT_YUV444P10;
|
||||
else
|
||||
return AV_PIX_FMT_YUV444P12;
|
||||
};
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
|
||||
const AVFrame *frame, int *got_packet)
|
||||
{
|
||||
|
@ -1259,6 +1318,43 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
|
|||
}
|
||||
|
||||
*got_packet = !!coded_size;
|
||||
|
||||
if (*got_packet && avctx->flags & AV_CODEC_FLAG_RECON_FRAME) {
|
||||
AVCodecInternal *avci = avctx->internal;
|
||||
struct aom_image img;
|
||||
|
||||
av_frame_unref(avci->recon_frame);
|
||||
|
||||
res = codecctl_imgp(avctx, AV1_GET_NEW_FRAME_IMAGE, &img);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
avci->recon_frame->format = aomfmt_to_pixfmt(&img);
|
||||
if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
|
||||
av_log(ctx, AV_LOG_ERROR,
|
||||
"Unhandled reconstructed frame colorspace: %d\n",
|
||||
img.fmt);
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
avci->recon_frame->width = img.d_w;
|
||||
avci->recon_frame->height = img.d_h;
|
||||
|
||||
res = av_frame_get_buffer(avci->recon_frame, 0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
if ((img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img.bit_depth == 8)
|
||||
ff_aom_image_copy_16_to_8(avci->recon_frame, &img);
|
||||
else {
|
||||
const uint8_t *planes[4] = { img.planes[0], img.planes[1], img.planes[2] };
|
||||
const int stride[4] = { img.stride[0], img.stride[1], img.stride[2] };
|
||||
|
||||
av_image_copy(avci->recon_frame->data, avci->recon_frame->linesize, planes,
|
||||
stride, avci->recon_frame->format, img.d_w, img.d_h);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1434,6 +1530,7 @@ FFCodec ff_libaom_av1_encoder = {
|
|||
.p.type = AVMEDIA_TYPE_VIDEO,
|
||||
.p.id = AV_CODEC_ID_AV1,
|
||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
|
||||
AV_CODEC_CAP_ENCODER_RECON_FRAME |
|
||||
AV_CODEC_CAP_OTHER_THREADS,
|
||||
.p.profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
|
||||
.p.priv_class = &class_aom,
|
||||
|
|
Loading…
Reference in New Issue