* [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames
@ 2022-07-17 19:26 Anton Khirnov
2022-07-17 19:26 ` [FFmpeg-devel] [PATCH 2/4] lavc: add API for exporting reconstructed frames from encoders Anton Khirnov
` (3 more replies)
0 siblings, 4 replies; 26+ messages in thread
From: Anton Khirnov @ 2022-07-17 19:26 UTC (permalink / raw)
To: ffmpeg-devel
This is an easy way to make a refcounted frame from a non-refcounted
one.
---
doc/APIchanges | 5 +++++
libavutil/frame.c | 3 ---
libavutil/frame.h | 3 ++-
libavutil/version.h | 2 +-
4 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/doc/APIchanges b/doc/APIchanges
index f9a1484bbc..4e218af94e 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,11 @@ libavutil: 2021-04-27
API changes, most recent first:
+2022-07-xx - xxxxxxxxxx - lavu 57.30.100 - frame.h
+ av_frame_make_writable() may now be called on non-refcounted
+ frames and will make a refcounted copy out of them.
+ Previously an error was returned in such cases.
+
-------- 8< --------- FFmpeg 5.1 was cut here -------- 8< ---------
2022-06-12 - 7cae3d8b76 - lavf 59.25.100 - avio.h
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 4c16488c66..7408817e1f 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -542,9 +542,6 @@ int av_frame_make_writable(AVFrame *frame)
AVFrame tmp;
int ret;
- if (!frame->buf[0])
- return AVERROR(EINVAL);
-
if (av_frame_is_writable(frame))
return 0;
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 33fac2054c..cc55d67e3c 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -818,7 +818,8 @@ int av_frame_is_writable(AVFrame *frame);
* Ensure that the frame data is writable, avoiding data copy if possible.
*
* Do nothing if the frame is writable, allocate new buffers and copy the data
- * if it is not.
+ * if it is not. Non-refcounted frames behave as non-writable, i.e. a copy
+ * is always made.
*
* @return 0 on success, a negative AVERROR on error.
*
diff --git a/libavutil/version.h b/libavutil/version.h
index f185322550..734d3f8330 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 57
-#define LIBAVUTIL_VERSION_MINOR 29
+#define LIBAVUTIL_VERSION_MINOR 30
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* [FFmpeg-devel] [PATCH 2/4] lavc: add API for exporting reconstructed frames from encoders
2022-07-17 19:26 [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames Anton Khirnov
@ 2022-07-17 19:26 ` Anton Khirnov
2022-07-18 12:35 ` James Almer
2022-07-17 19:26 ` [FFmpeg-devel] [PATCH 3/4] lavc/mpegvideo_enc: support AV_CODEC_CAP_ENCODER_RECON_FRAME Anton Khirnov
` (2 subsequent siblings)
3 siblings, 1 reply; 26+ messages in thread
From: Anton Khirnov @ 2022-07-17 19:26 UTC (permalink / raw)
To: ffmpeg-devel
---
doc/APIchanges | 5 +++++
libavcodec/avcodec.c | 10 ++++++++++
libavcodec/avcodec.h | 20 ++++++++++++++++----
libavcodec/codec.h | 8 ++++++++
libavcodec/decode.c | 2 +-
libavcodec/decode.h | 5 +++++
libavcodec/encode.c | 25 +++++++++++++++++++++++++
libavcodec/encode.h | 5 +++++
libavcodec/internal.h | 8 ++++++++
libavcodec/options_table.h | 1 +
libavcodec/version.h | 2 +-
11 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/doc/APIchanges b/doc/APIchanges
index 4e218af94e..b50fece404 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,11 @@ libavutil: 2021-04-27
API changes, most recent first:
+2022-07-xx - xxxxxxxxxx - lavc 59.40.100 - avcodec.h codec.h
+ Add AV_CODEC_FLAG_RECON_FRAME and AV_CODEC_CAP_ENCODER_RECON_FRAME.
+ avcodec_receive_frame() may now be used on encoders when
+ AV_CODEC_FLAG_RECON_FRAME is active.
+
2022-07-xx - xxxxxxxxxx - lavu 57.30.100 - frame.h
av_frame_make_writable() may now be called on non-refcounted
frames and will make a refcounted copy out of them.
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 5f6e71a39e..e25273cb4e 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -390,6 +390,8 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
}
if (avci->in_frame)
av_frame_unref(avci->in_frame);
+ if (avci->recon_frame)
+ av_frame_unref(avci->recon_frame);
} else {
av_packet_unref(avci->last_pkt_props);
while (av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1) >= 0)
@@ -470,6 +472,7 @@ av_cold int avcodec_close(AVCodecContext *avctx)
av_packet_free(&avci->in_pkt);
av_frame_free(&avci->in_frame);
+ av_frame_free(&avci->recon_frame);
av_buffer_unref(&avci->pool);
@@ -716,3 +719,10 @@ int avcodec_is_open(AVCodecContext *s)
{
return !!s->internal;
}
+
+int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+ if (av_codec_is_decoder(avctx->codec))
+ return ff_decode_receive_frame(avctx, frame);
+ return ff_encode_receive_frame(avctx, frame);
+}
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index cb5c25bf63..04e9d33493 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -231,6 +231,16 @@ typedef struct RcOverride{
* decoded frame in stream.
*/
#define AV_CODEC_FLAG_DROPCHANGED (1 << 5)
+/**
+ * Request the encoder to output reconstructed frames, i.e. frames that would be
+ * produced by decoding the encoded bistream. These frames may be retrieved by
+ * calling avcodec_receive_frame() immediately after a successful call to
+ * avcodec_receive_packet().
+ *
+ * Should only be used with encoders flagged with the
+ * AV_CODEC_CAP_ENCODER_RECON_FRAME capability.
+ */
+#define AV_CODEC_FLAG_RECON_FRAME (1 << 6)
/**
* Use internal 2pass ratecontrol in first pass mode.
*/
@@ -2595,21 +2605,23 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
/**
- * Return decoded output data from a decoder.
+ * Return decoded output data from a decoder or encoder (when the
+ * AV_CODEC_FLAG_RECON_FRAME flag is used).
*
* @param avctx codec context
* @param frame This will be set to a reference-counted video or audio
* frame (depending on the decoder type) allocated by the
- * decoder. Note that the function will always call
+ * codec. Note that the function will always call
* av_frame_unref(frame) before doing anything else.
*
* @return
* 0: success, a frame was returned
* AVERROR(EAGAIN): output is not available in this state - user must try
* to send new input
- * AVERROR_EOF: the decoder has been fully flushed, and there will be
+ * AVERROR_EOF: the codec has been fully flushed, and there will be
* no more output frames
- * AVERROR(EINVAL): codec not opened, or it is an encoder
+ * AVERROR(EINVAL): codec not opened, or it is an encoder without
+ * the AV_CODEC_FLAG_RECON_FRAME flag enabled
* AVERROR_INPUT_CHANGED: current decoded frame has changed parameters
* with respect to first decoded frame. Applicable
* when flag AV_CODEC_FLAG_DROPCHANGED is set.
diff --git a/libavcodec/codec.h b/libavcodec/codec.h
index 03e8be90a2..77a1a3f5a2 100644
--- a/libavcodec/codec.h
+++ b/libavcodec/codec.h
@@ -182,6 +182,14 @@
*/
#define AV_CODEC_CAP_ENCODER_FLUSH (1 << 21)
+/**
+ * The encoder is able to output reconstructed frame data, i.e. raw frames that
+ * would be produced by decoding the encoded bitstream.
+ *
+ * Reconstructed frame output is enabled by the AV_CODEC_FLAG_RECON_FRAME flag.
+ */
+#define AV_CODEC_CAP_ENCODER_RECON_FRAME (1 << 22)
+
/**
* AVProfile.
*/
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 1893caa6a6..03f3d4e3a2 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -636,7 +636,7 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame)
AV_FRAME_CROP_UNALIGNED : 0);
}
-int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{
AVCodecInternal *avci = avctx->internal;
int ret, changed;
diff --git a/libavcodec/decode.h b/libavcodec/decode.h
index 1b40f714e1..f7828fbff4 100644
--- a/libavcodec/decode.h
+++ b/libavcodec/decode.h
@@ -53,6 +53,11 @@ typedef struct FrameDecodeData {
void (*hwaccel_priv_free)(void *priv);
} FrameDecodeData;
+/**
+ * avcodec_receive_frame() implementation for decoders.
+ */
+int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame);
+
/**
* Called by decoders to get the next packet for decoding.
*
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 1f39ab1a2f..f15309ce09 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -594,6 +594,18 @@ int ff_encode_preinit(AVCodecContext *avctx)
return AVERROR(ENOMEM);
}
+ if ((avctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ if (!(avctx->codec->capabilities & AV_CODEC_CAP_ENCODER_RECON_FRAME)) {
+ av_log(avctx, AV_LOG_ERROR, "Reconstructed frame output requested "
+ "from an encoder not supporting it\n");
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame = av_frame_alloc();
+ if (!avci->recon_frame)
+ return AVERROR(ENOMEM);
+ }
+
return 0;
}
@@ -630,3 +642,16 @@ int ff_encode_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
return 0;
}
+
+int ff_encode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+ AVCodecInternal *avci = avctx->internal;
+
+ if (!avci->recon_frame)
+ return AVERROR(EINVAL);
+ if (!avci->recon_frame->buf[0])
+ return avci->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);
+
+ av_frame_move_ref(frame, avci->recon_frame);
+ return 0;
+}
diff --git a/libavcodec/encode.h b/libavcodec/encode.h
index b2536bf0f3..bc77918d8f 100644
--- a/libavcodec/encode.h
+++ b/libavcodec/encode.h
@@ -26,6 +26,11 @@
#include "avcodec.h"
#include "packet.h"
+/**
+ * avcodec_receive_frame() implementation for encoders.
+ */
+int ff_encode_receive_frame(AVCodecContext *avctx, AVFrame *frame);
+
/**
* Called by encoders to get the next frame for encoding.
*
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 17e1de8127..fb93d42aa1 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -103,6 +103,14 @@ typedef struct AVCodecInternal {
*/
AVFrame *in_frame;
+ /**
+ * When the AV_CODEC_FLAG_RECON_FRAME flag is used. the encoder should store
+ * here the reconstructed frame corresponding to the last returned packet.
+ *
+ * Not allocated in other cases.
+ */
+ AVFrame *recon_frame;
+
/**
* If this is set, then FFCodec->close (if existing) needs to be called
* for the parent AVCodecContext.
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index e72b4d12b6..35a94c0227 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -57,6 +57,7 @@ static const AVOption avcodec_options[] = {
{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
+{"recon_frame", "export reconstructed frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_RECON_FRAME}, .unit = "flags"},
{"pass1", "use internal 2-pass ratecontrol in first pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
diff --git a/libavcodec/version.h b/libavcodec/version.h
index f2f14eaed1..19f3f4a272 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
#include "version_major.h"
-#define LIBAVCODEC_VERSION_MINOR 39
+#define LIBAVCODEC_VERSION_MINOR 40
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* [FFmpeg-devel] [PATCH 3/4] lavc/mpegvideo_enc: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-17 19:26 [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames Anton Khirnov
2022-07-17 19:26 ` [FFmpeg-devel] [PATCH 2/4] lavc: add API for exporting reconstructed frames from encoders Anton Khirnov
@ 2022-07-17 19:26 ` Anton Khirnov
2022-07-17 19:27 ` [FFmpeg-devel] [PATCH 4/4] lavc/libx264: " Anton Khirnov
2022-07-18 12:24 ` [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames James Almer
3 siblings, 0 replies; 26+ messages in thread
From: Anton Khirnov @ 2022-07-17 19:26 UTC (permalink / raw)
To: ffmpeg-devel
---
libavcodec/flvenc.c | 1 +
libavcodec/h261enc.c | 1 +
libavcodec/ituh263enc.c | 3 ++-
libavcodec/mjpegenc.c | 4 +++-
libavcodec/mpeg12enc.c | 6 ++++--
libavcodec/mpeg4videoenc.c | 3 ++-
libavcodec/mpegvideo_enc.c | 8 ++++++++
libavcodec/msmpeg4enc.c | 3 +++
libavcodec/rv10enc.c | 1 +
libavcodec/rv20enc.c | 1 +
libavcodec/speedhqenc.c | 1 +
libavcodec/wmv2enc.c | 1 +
12 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index 74ed321e27..7dca36f118 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -103,6 +103,7 @@ const FFCodec ff_flv_encoder = {
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE},
};
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 007bb4aa30..6f955143e6 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -411,6 +411,7 @@ const FFCodec ff_h261_encoder = {
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
};
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 2fcd001dba..0e80b4244b 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -903,6 +903,7 @@ const FFCodec ff_h263_encoder = {
.p.id = AV_CODEC_ID_H263,
.p.pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE},
.p.priv_class = &h263_class,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(MpegEncContext),
.init = ff_mpv_encode_init,
@@ -933,7 +934,7 @@ const FFCodec ff_h263p_encoder = {
.p.id = AV_CODEC_ID_H263P,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.p.priv_class = &h263p_class,
- .p.capabilities = AV_CODEC_CAP_SLICE_THREADS,
+ .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(MpegEncContext),
.init = ff_mpv_encode_init,
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 27217441a3..633074d8f6 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -651,7 +651,8 @@ const FFCodec ff_mjpeg_encoder = {
.init = ff_mpv_encode_init,
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = mjpeg_encode_close,
- .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
+ .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
@@ -681,6 +682,7 @@ const FFCodec ff_amv_encoder = {
FF_CODEC_ENCODE_CB(amv_encode_picture),
.close = mjpeg_encode_close,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE
},
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 09d63ff7dc..419fb59c28 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -1230,7 +1230,8 @@ const FFCodec ff_mpeg1video_encoder = {
.p.supported_framerates = ff_mpeg12_frame_rate_tab + 1,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
- .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
+ .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.p.priv_class = &mpeg1_class,
};
@@ -1248,7 +1249,8 @@ const FFCodec ff_mpeg2video_encoder = {
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_YUV422P,
AV_PIX_FMT_NONE },
- .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
+ .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.p.priv_class = &mpeg2_class,
};
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 8f0452de3a..be398d7e4a 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -1401,7 +1401,8 @@ const FFCodec ff_mpeg4_encoder = {
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
- .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
+ .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.p.priv_class = &mpeg4enc_class,
};
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index c9d9e2a764..0562c35d27 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1781,6 +1781,14 @@ vbv_retry:
(avctx->flags&AV_CODEC_FLAG_PSNR) ? MPEGVIDEO_MAX_PLANES : 0,
s->pict_type);
+ if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME) {
+ AVCodecInternal *avci = avctx->internal;
+ av_frame_unref(avci->recon_frame);
+ ret = av_frame_ref(avci->recon_frame, s->current_picture.f);
+ if (ret < 0)
+ return ret;
+ }
+
if (avctx->flags & AV_CODEC_FLAG_PASS1)
assert(put_bits_count(&s->pb) == s->header_bits + s->mv_bits +
s->misc_bits + s->i_tex_bits +
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index e597dbbb4e..6d79ff7e2c 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -683,6 +683,7 @@ const FFCodec ff_msmpeg4v2_encoder = {
.p.id = AV_CODEC_ID_MSMPEG4V2,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.p.priv_class = &ff_mpv_enc_class,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(MSMPEG4EncContext),
.init = ff_mpv_encode_init,
@@ -697,6 +698,7 @@ const FFCodec ff_msmpeg4v3_encoder = {
.p.id = AV_CODEC_ID_MSMPEG4V3,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.p.priv_class = &ff_mpv_enc_class,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(MSMPEG4EncContext),
.init = ff_mpv_encode_init,
@@ -711,6 +713,7 @@ const FFCodec ff_wmv1_encoder = {
.p.id = AV_CODEC_ID_WMV1,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.p.priv_class = &ff_mpv_enc_class,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.priv_data_size = sizeof(MSMPEG4EncContext),
.init = ff_mpv_encode_init,
diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c
index 7560e6026a..e5271a1e7c 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -76,5 +76,6 @@ const FFCodec ff_rv10_encoder = {
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
};
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index 422188e21a..d391173006 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -73,5 +73,6 @@ const FFCodec ff_rv20_encoder = {
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
};
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index 7a53d86945..d1250201d2 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -288,6 +288,7 @@ const FFCodec ff_speedhq_encoder = {
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_NONE
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 88211ac179..52660612e5 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -244,6 +244,7 @@ const FFCodec ff_wmv2_encoder = {
FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
.close = ff_mpv_encode_end,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+ .p.capabilities = AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
};
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* [FFmpeg-devel] [PATCH 4/4] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-17 19:26 [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames Anton Khirnov
2022-07-17 19:26 ` [FFmpeg-devel] [PATCH 2/4] lavc: add API for exporting reconstructed frames from encoders Anton Khirnov
2022-07-17 19:26 ` [FFmpeg-devel] [PATCH 3/4] lavc/mpegvideo_enc: support AV_CODEC_CAP_ENCODER_RECON_FRAME Anton Khirnov
@ 2022-07-17 19:27 ` Anton Khirnov
2022-07-17 22:06 ` Michael Niedermayer
2022-07-19 12:47 ` [FFmpeg-devel] [PATCH v2] " Anton Khirnov
2022-07-18 12:24 ` [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames James Almer
3 siblings, 2 replies; 26+ messages in thread
From: Anton Khirnov @ 2022-07-17 19:27 UTC (permalink / raw)
To: ffmpeg-devel
---
libavcodec/libx264.c | 50 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 98ec030865..b27006c030 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -311,6 +311,23 @@ static void free_picture(AVCodecContext *ctx)
pic->extra_sei.num_payloads = 0;
}
+static enum AVPixelFormat csp_to_pixfmt(int csp)
+{
+ switch (csp) {
+ case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
+ case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
+ case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
+ case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
+ case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
+ case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
+ case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
+ case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
+ case X264_CSP_NV12: return AV_PIX_FMT_NV12;
+ case X264_CSP_NV16: return AV_PIX_FMT_NV16;
+ };
+ return AV_PIX_FMT_NONE;
+}
+
static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
int *got_packet)
{
@@ -496,6 +513,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
return AVERROR_EXTERNAL;
+ if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ AVCodecInternal *avci = ctx->internal;
+
+ av_frame_unref(avci->recon_frame);
+
+ avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
+ if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Unhandled reconstructed frame colorspace: %d\n",
+ pic_out.img.i_csp);
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame->width = ctx->width;
+ avci->recon_frame->height = ctx->height;
+ for (int i = 0; i < pic_out.img.i_plane; i++) {
+ avci->recon_frame->data[i] = pic_out.img.plane[i];
+ avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
+ }
+
+ ret = av_frame_make_writable(avci->recon_frame);
+ if (ret < 0) {
+ av_frame_unref(avci->recon_frame);
+ return ret;
+ }
+ }
+
ret = encode_nals(ctx, pkt, nal, nnal);
if (ret < 0)
return ret;
@@ -928,6 +972,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
+ if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
+ x4->params.b_full_recon = 1;
+
if(x4->x264opts){
const char *p= x4->x264opts;
while(p){
@@ -1223,7 +1270,8 @@ FFCodec ff_libx264_encoder = {
.p.id = AV_CODEC_ID_H264,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_OTHER_THREADS |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.priv_class = &x264_class,
.p.wrapper_name = "libx264",
.priv_data_size = sizeof(X264Context),
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH 4/4] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-17 19:27 ` [FFmpeg-devel] [PATCH 4/4] lavc/libx264: " Anton Khirnov
@ 2022-07-17 22:06 ` Michael Niedermayer
2022-07-18 7:12 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
2022-07-19 12:47 ` [FFmpeg-devel] [PATCH v2] " Anton Khirnov
1 sibling, 1 reply; 26+ messages in thread
From: Michael Niedermayer @ 2022-07-17 22:06 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 705 bytes --]
On Sun, Jul 17, 2022 at 09:27:00PM +0200, Anton Khirnov wrote:
> ---
> libavcodec/libx264.c | 50 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 49 insertions(+), 1 deletion(-)
breaks build on ubuntu
libavcodec/libx264.c: In function ‘csp_to_pixfmt’:
libavcodec/libx264.c:317:10: error: ‘X264_CSP_I400’ undeclared (first use in this function); did you mean ‘X264_CSP_I420’?
case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
^~~~~~~~~~~~~
X264_CSP_I420
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Observe your enemies, for they first find out your faults. -- Antisthenes
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-17 22:06 ` Michael Niedermayer
@ 2022-07-18 7:12 ` Anton Khirnov
2022-07-18 12:23 ` James Almer
2022-07-18 17:41 ` James Almer
0 siblings, 2 replies; 26+ messages in thread
From: Anton Khirnov @ 2022-07-18 7:12 UTC (permalink / raw)
To: ffmpeg-devel
---
libavcodec/libx264.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 98ec030865..5e360682e6 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -311,6 +311,25 @@ static void free_picture(AVCodecContext *ctx)
pic->extra_sei.num_payloads = 0;
}
+static enum AVPixelFormat csp_to_pixfmt(int csp)
+{
+ switch (csp) {
+#ifdef X264_CSP_I400
+ case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
+ case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
+#endif
+ case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
+ case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
+ case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
+ case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
+ case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
+ case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
+ case X264_CSP_NV12: return AV_PIX_FMT_NV12;
+ case X264_CSP_NV16: return AV_PIX_FMT_NV16;
+ };
+ return AV_PIX_FMT_NONE;
+}
+
static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
int *got_packet)
{
@@ -496,6 +515,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
return AVERROR_EXTERNAL;
+ if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ AVCodecInternal *avci = ctx->internal;
+
+ av_frame_unref(avci->recon_frame);
+
+ avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
+ if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Unhandled reconstructed frame colorspace: %d\n",
+ pic_out.img.i_csp);
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame->width = ctx->width;
+ avci->recon_frame->height = ctx->height;
+ for (int i = 0; i < pic_out.img.i_plane; i++) {
+ avci->recon_frame->data[i] = pic_out.img.plane[i];
+ avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
+ }
+
+ ret = av_frame_make_writable(avci->recon_frame);
+ if (ret < 0) {
+ av_frame_unref(avci->recon_frame);
+ return ret;
+ }
+ }
+
ret = encode_nals(ctx, pkt, nal, nnal);
if (ret < 0)
return ret;
@@ -928,6 +974,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
+ if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
+ x4->params.b_full_recon = 1;
+
if(x4->x264opts){
const char *p= x4->x264opts;
while(p){
@@ -1223,7 +1272,8 @@ FFCodec ff_libx264_encoder = {
.p.id = AV_CODEC_ID_H264,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_OTHER_THREADS |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.priv_class = &x264_class,
.p.wrapper_name = "libx264",
.priv_data_size = sizeof(X264Context),
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-18 7:12 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
@ 2022-07-18 12:23 ` James Almer
2022-07-18 18:15 ` Anton Khirnov
2022-07-19 12:43 ` Anton Khirnov
2022-07-18 17:41 ` James Almer
1 sibling, 2 replies; 26+ messages in thread
From: James Almer @ 2022-07-18 12:23 UTC (permalink / raw)
To: ffmpeg-devel
On 7/18/2022 4:12 AM, Anton Khirnov wrote:
> ---
> libavcodec/libx264.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> index 98ec030865..5e360682e6 100644
> --- a/libavcodec/libx264.c
> +++ b/libavcodec/libx264.c
> @@ -311,6 +311,25 @@ static void free_picture(AVCodecContext *ctx)
> pic->extra_sei.num_payloads = 0;
> }
>
> +static enum AVPixelFormat csp_to_pixfmt(int csp)
> +{
> + switch (csp) {
> +#ifdef X264_CSP_I400
> + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
> + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
> +#endif
> + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
> + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
> + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
> + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
> + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
> + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
We're still supporting old x264 versions, so you should add some
considerations for 9 bit pixfmts. On X264_BUILD < 153, just check the
value of x264_bit_depth.
> + case X264_CSP_NV12: return AV_PIX_FMT_NV12;
> + case X264_CSP_NV16: return AV_PIX_FMT_NV16;
Missing X264_CSP_NV21 (wrapped like X264_CSP_I400).
That aside, LGTM.
> + };
> + return AV_PIX_FMT_NONE;
> +}
> +
> static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
> int *got_packet)
> {
> @@ -496,6 +515,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
> if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
> return AVERROR_EXTERNAL;
>
> + if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
> + AVCodecInternal *avci = ctx->internal;
> +
> + av_frame_unref(avci->recon_frame);
> +
> + avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
> + if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
> + av_log(ctx, AV_LOG_ERROR,
> + "Unhandled reconstructed frame colorspace: %d\n",
> + pic_out.img.i_csp);
> + return AVERROR(ENOSYS);
> + }
> +
> + avci->recon_frame->width = ctx->width;
> + avci->recon_frame->height = ctx->height;
> + for (int i = 0; i < pic_out.img.i_plane; i++) {
> + avci->recon_frame->data[i] = pic_out.img.plane[i];
> + avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
> + }
> +
> + ret = av_frame_make_writable(avci->recon_frame);
> + if (ret < 0) {
> + av_frame_unref(avci->recon_frame);
> + return ret;
> + }
> + }
> +
> ret = encode_nals(ctx, pkt, nal, nnal);
> if (ret < 0)
> return ret;
> @@ -928,6 +974,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
> if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
> x4->params.b_repeat_headers = 0;
>
> + if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
> + x4->params.b_full_recon = 1;
> +
> if(x4->x264opts){
> const char *p= x4->x264opts;
> while(p){
> @@ -1223,7 +1272,8 @@ FFCodec ff_libx264_encoder = {
> .p.id = AV_CODEC_ID_H264,
> .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_OTHER_THREADS |
> - AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
> + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
> + AV_CODEC_CAP_ENCODER_RECON_FRAME,
> .p.priv_class = &x264_class,
> .p.wrapper_name = "libx264",
> .priv_data_size = sizeof(X264Context),
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames
2022-07-17 19:26 [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames Anton Khirnov
` (2 preceding siblings ...)
2022-07-17 19:27 ` [FFmpeg-devel] [PATCH 4/4] lavc/libx264: " Anton Khirnov
@ 2022-07-18 12:24 ` James Almer
3 siblings, 0 replies; 26+ messages in thread
From: James Almer @ 2022-07-18 12:24 UTC (permalink / raw)
To: ffmpeg-devel
On 7/17/2022 4:26 PM, Anton Khirnov wrote:
> This is an easy way to make a refcounted frame from a non-refcounted
> one.
> ---
> doc/APIchanges | 5 +++++
> libavutil/frame.c | 3 ---
> libavutil/frame.h | 3 ++-
> libavutil/version.h | 2 +-
> 4 files changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index f9a1484bbc..4e218af94e 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -14,6 +14,11 @@ libavutil: 2021-04-27
>
> API changes, most recent first:
>
> +2022-07-xx - xxxxxxxxxx - lavu 57.30.100 - frame.h
> + av_frame_make_writable() may now be called on non-refcounted
> + frames and will make a refcounted copy out of them.
> + Previously an error was returned in such cases.
> +
> -------- 8< --------- FFmpeg 5.1 was cut here -------- 8< ---------
>
> 2022-06-12 - 7cae3d8b76 - lavf 59.25.100 - avio.h
> diff --git a/libavutil/frame.c b/libavutil/frame.c
> index 4c16488c66..7408817e1f 100644
> --- a/libavutil/frame.c
> +++ b/libavutil/frame.c
> @@ -542,9 +542,6 @@ int av_frame_make_writable(AVFrame *frame)
> AVFrame tmp;
> int ret;
>
> - if (!frame->buf[0])
> - return AVERROR(EINVAL);
> -
> if (av_frame_is_writable(frame))
> return 0;
>
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index 33fac2054c..cc55d67e3c 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -818,7 +818,8 @@ int av_frame_is_writable(AVFrame *frame);
> * Ensure that the frame data is writable, avoiding data copy if possible.
> *
> * Do nothing if the frame is writable, allocate new buffers and copy the data
> - * if it is not.
> + * if it is not. Non-refcounted frames behave as non-writable, i.e. a copy
> + * is always made.
> *
> * @return 0 on success, a negative AVERROR on error.
> *
> diff --git a/libavutil/version.h b/libavutil/version.h
> index f185322550..734d3f8330 100644
> --- a/libavutil/version.h
> +++ b/libavutil/version.h
> @@ -79,7 +79,7 @@
> */
>
> #define LIBAVUTIL_VERSION_MAJOR 57
> -#define LIBAVUTIL_VERSION_MINOR 29
> +#define LIBAVUTIL_VERSION_MINOR 30
> #define LIBAVUTIL_VERSION_MICRO 100
>
> #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LGTM.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/4] lavc: add API for exporting reconstructed frames from encoders
2022-07-17 19:26 ` [FFmpeg-devel] [PATCH 2/4] lavc: add API for exporting reconstructed frames from encoders Anton Khirnov
@ 2022-07-18 12:35 ` James Almer
2022-07-18 18:05 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
0 siblings, 1 reply; 26+ messages in thread
From: James Almer @ 2022-07-18 12:35 UTC (permalink / raw)
To: ffmpeg-devel
On 7/17/2022 4:26 PM, Anton Khirnov wrote:
> diff --git a/libavcodec/encode.c b/libavcodec/encode.c
> index 1f39ab1a2f..f15309ce09 100644
> --- a/libavcodec/encode.c
> +++ b/libavcodec/encode.c
> @@ -594,6 +594,18 @@ int ff_encode_preinit(AVCodecContext *avctx)
> return AVERROR(ENOMEM);
> }
>
> + if ((avctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
> + if (!(avctx->codec->capabilities & AV_CODEC_CAP_ENCODER_RECON_FRAME)) {
> + av_log(avctx, AV_LOG_ERROR, "Reconstructed frame output requested "
> + "from an encoder not supporting it\n");
> + return AVERROR(ENOSYS);
> + }
> +
> + avci->recon_frame = av_frame_alloc();
> + if (!avci->recon_frame)
> + return AVERROR(ENOMEM);
> + }
> +
> return 0;
> }
>
> @@ -630,3 +642,16 @@ int ff_encode_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
>
> return 0;
> }
> +
> +int ff_encode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
> +{
> + AVCodecInternal *avci = avctx->internal;
> +
> + if (!avci->recon_frame)
> + return AVERROR(EINVAL);
> + if (!avci->recon_frame->buf[0])
> + return avci->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);
> +
> + av_frame_move_ref(frame, avci->recon_frame);
The API for avcodec_receive_frame() mentions frame will be unref'd first
thing, so you should do that before even the recon_frame checks.
> + return 0;
> +}
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-18 7:12 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
2022-07-18 12:23 ` James Almer
@ 2022-07-18 17:41 ` James Almer
2022-07-18 18:07 ` Anton Khirnov
1 sibling, 1 reply; 26+ messages in thread
From: James Almer @ 2022-07-18 17:41 UTC (permalink / raw)
To: ffmpeg-devel
On 7/18/2022 4:12 AM, Anton Khirnov wrote:
> ---
> libavcodec/libx264.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> index 98ec030865..5e360682e6 100644
> --- a/libavcodec/libx264.c
> +++ b/libavcodec/libx264.c
> @@ -311,6 +311,25 @@ static void free_picture(AVCodecContext *ctx)
> pic->extra_sei.num_payloads = 0;
> }
>
> +static enum AVPixelFormat csp_to_pixfmt(int csp)
> +{
> + switch (csp) {
> +#ifdef X264_CSP_I400
> + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
> + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
> +#endif
> + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
> + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
> + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
> + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
> + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
> + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
> + case X264_CSP_NV12: return AV_PIX_FMT_NV12;
> + case X264_CSP_NV16: return AV_PIX_FMT_NV16;
> + };
> + return AV_PIX_FMT_NONE;
> +}
> +
> static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
> int *got_packet)
> {
> @@ -496,6 +515,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
> if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
> return AVERROR_EXTERNAL;
>
> + if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
> + AVCodecInternal *avci = ctx->internal;
> +
> + av_frame_unref(avci->recon_frame);
> +
> + avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
> + if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
> + av_log(ctx, AV_LOG_ERROR,
> + "Unhandled reconstructed frame colorspace: %d\n",
> + pic_out.img.i_csp);
> + return AVERROR(ENOSYS);
> + }
> +
> + avci->recon_frame->width = ctx->width;
> + avci->recon_frame->height = ctx->height;
> + for (int i = 0; i < pic_out.img.i_plane; i++) {
> + avci->recon_frame->data[i] = pic_out.img.plane[i];
> + avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
> + }
> +
> + ret = av_frame_make_writable(avci->recon_frame);
Why not ff_encode_alloc_frame() for this? Can
csp_to_pixfmt(pic_out.img.i_csp) be different than ctx->pix_fmt?
> + if (ret < 0) {
> + av_frame_unref(avci->recon_frame);
> + return ret;
> + }
> + }
> +
> ret = encode_nals(ctx, pkt, nal, nnal);
> if (ret < 0)
> return ret;
> @@ -928,6 +974,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
> if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
> x4->params.b_repeat_headers = 0;
>
> + if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
> + x4->params.b_full_recon = 1;
> +
> if(x4->x264opts){
> const char *p= x4->x264opts;
> while(p){
> @@ -1223,7 +1272,8 @@ FFCodec ff_libx264_encoder = {
> .p.id = AV_CODEC_ID_H264,
> .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_OTHER_THREADS |
> - AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
> + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
> + AV_CODEC_CAP_ENCODER_RECON_FRAME,
> .p.priv_class = &x264_class,
> .p.wrapper_name = "libx264",
> .priv_data_size = sizeof(X264Context),
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* [FFmpeg-devel] [PATCH] lavc: add API for exporting reconstructed frames from encoders
2022-07-18 12:35 ` James Almer
@ 2022-07-18 18:05 ` Anton Khirnov
2022-07-18 21:29 ` James Almer
0 siblings, 1 reply; 26+ messages in thread
From: Anton Khirnov @ 2022-07-18 18:05 UTC (permalink / raw)
To: ffmpeg-devel
---
doc/APIchanges | 5 +++++
libavcodec/avcodec.c | 12 ++++++++++++
libavcodec/avcodec.h | 20 ++++++++++++++++----
libavcodec/codec.h | 8 ++++++++
libavcodec/decode.c | 4 +---
libavcodec/decode.h | 5 +++++
libavcodec/encode.c | 25 +++++++++++++++++++++++++
libavcodec/encode.h | 5 +++++
libavcodec/internal.h | 8 ++++++++
libavcodec/options_table.h | 1 +
libavcodec/version.h | 2 +-
11 files changed, 87 insertions(+), 8 deletions(-)
diff --git a/doc/APIchanges b/doc/APIchanges
index 4e218af94e..b50fece404 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,11 @@ libavutil: 2021-04-27
API changes, most recent first:
+2022-07-xx - xxxxxxxxxx - lavc 59.40.100 - avcodec.h codec.h
+ Add AV_CODEC_FLAG_RECON_FRAME and AV_CODEC_CAP_ENCODER_RECON_FRAME.
+ avcodec_receive_frame() may now be used on encoders when
+ AV_CODEC_FLAG_RECON_FRAME is active.
+
2022-07-xx - xxxxxxxxxx - lavu 57.30.100 - frame.h
av_frame_make_writable() may now be called on non-refcounted
frames and will make a refcounted copy out of them.
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 5f6e71a39e..9dd4157750 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -390,6 +390,8 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
}
if (avci->in_frame)
av_frame_unref(avci->in_frame);
+ if (avci->recon_frame)
+ av_frame_unref(avci->recon_frame);
} else {
av_packet_unref(avci->last_pkt_props);
while (av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1) >= 0)
@@ -470,6 +472,7 @@ av_cold int avcodec_close(AVCodecContext *avctx)
av_packet_free(&avci->in_pkt);
av_frame_free(&avci->in_frame);
+ av_frame_free(&avci->recon_frame);
av_buffer_unref(&avci->pool);
@@ -716,3 +719,12 @@ int avcodec_is_open(AVCodecContext *s)
{
return !!s->internal;
}
+
+int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+ av_frame_unref(frame);
+
+ if (av_codec_is_decoder(avctx->codec))
+ return ff_decode_receive_frame(avctx, frame);
+ return ff_encode_receive_frame(avctx, frame);
+}
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index cb5c25bf63..04e9d33493 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -231,6 +231,16 @@ typedef struct RcOverride{
* decoded frame in stream.
*/
#define AV_CODEC_FLAG_DROPCHANGED (1 << 5)
+/**
+ * Request the encoder to output reconstructed frames, i.e. frames that would be
+ * produced by decoding the encoded bistream. These frames may be retrieved by
+ * calling avcodec_receive_frame() immediately after a successful call to
+ * avcodec_receive_packet().
+ *
+ * Should only be used with encoders flagged with the
+ * AV_CODEC_CAP_ENCODER_RECON_FRAME capability.
+ */
+#define AV_CODEC_FLAG_RECON_FRAME (1 << 6)
/**
* Use internal 2pass ratecontrol in first pass mode.
*/
@@ -2595,21 +2605,23 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
/**
- * Return decoded output data from a decoder.
+ * Return decoded output data from a decoder or encoder (when the
+ * AV_CODEC_FLAG_RECON_FRAME flag is used).
*
* @param avctx codec context
* @param frame This will be set to a reference-counted video or audio
* frame (depending on the decoder type) allocated by the
- * decoder. Note that the function will always call
+ * codec. Note that the function will always call
* av_frame_unref(frame) before doing anything else.
*
* @return
* 0: success, a frame was returned
* AVERROR(EAGAIN): output is not available in this state - user must try
* to send new input
- * AVERROR_EOF: the decoder has been fully flushed, and there will be
+ * AVERROR_EOF: the codec has been fully flushed, and there will be
* no more output frames
- * AVERROR(EINVAL): codec not opened, or it is an encoder
+ * AVERROR(EINVAL): codec not opened, or it is an encoder without
+ * the AV_CODEC_FLAG_RECON_FRAME flag enabled
* AVERROR_INPUT_CHANGED: current decoded frame has changed parameters
* with respect to first decoded frame. Applicable
* when flag AV_CODEC_FLAG_DROPCHANGED is set.
diff --git a/libavcodec/codec.h b/libavcodec/codec.h
index 03e8be90a2..77a1a3f5a2 100644
--- a/libavcodec/codec.h
+++ b/libavcodec/codec.h
@@ -182,6 +182,14 @@
*/
#define AV_CODEC_CAP_ENCODER_FLUSH (1 << 21)
+/**
+ * The encoder is able to output reconstructed frame data, i.e. raw frames that
+ * would be produced by decoding the encoded bitstream.
+ *
+ * Reconstructed frame output is enabled by the AV_CODEC_FLAG_RECON_FRAME flag.
+ */
+#define AV_CODEC_CAP_ENCODER_RECON_FRAME (1 << 22)
+
/**
* AVProfile.
*/
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 1893caa6a6..0a40b207e8 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -636,13 +636,11 @@ static int apply_cropping(AVCodecContext *avctx, AVFrame *frame)
AV_FRAME_CROP_UNALIGNED : 0);
}
-int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{
AVCodecInternal *avci = avctx->internal;
int ret, changed;
- av_frame_unref(frame);
-
if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))
return AVERROR(EINVAL);
diff --git a/libavcodec/decode.h b/libavcodec/decode.h
index 1b40f714e1..f7828fbff4 100644
--- a/libavcodec/decode.h
+++ b/libavcodec/decode.h
@@ -53,6 +53,11 @@ typedef struct FrameDecodeData {
void (*hwaccel_priv_free)(void *priv);
} FrameDecodeData;
+/**
+ * avcodec_receive_frame() implementation for decoders.
+ */
+int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame);
+
/**
* Called by decoders to get the next packet for decoding.
*
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 1f39ab1a2f..f15309ce09 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -594,6 +594,18 @@ int ff_encode_preinit(AVCodecContext *avctx)
return AVERROR(ENOMEM);
}
+ if ((avctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ if (!(avctx->codec->capabilities & AV_CODEC_CAP_ENCODER_RECON_FRAME)) {
+ av_log(avctx, AV_LOG_ERROR, "Reconstructed frame output requested "
+ "from an encoder not supporting it\n");
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame = av_frame_alloc();
+ if (!avci->recon_frame)
+ return AVERROR(ENOMEM);
+ }
+
return 0;
}
@@ -630,3 +642,16 @@ int ff_encode_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
return 0;
}
+
+int ff_encode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+ AVCodecInternal *avci = avctx->internal;
+
+ if (!avci->recon_frame)
+ return AVERROR(EINVAL);
+ if (!avci->recon_frame->buf[0])
+ return avci->draining_done ? AVERROR_EOF : AVERROR(EAGAIN);
+
+ av_frame_move_ref(frame, avci->recon_frame);
+ return 0;
+}
diff --git a/libavcodec/encode.h b/libavcodec/encode.h
index b2536bf0f3..bc77918d8f 100644
--- a/libavcodec/encode.h
+++ b/libavcodec/encode.h
@@ -26,6 +26,11 @@
#include "avcodec.h"
#include "packet.h"
+/**
+ * avcodec_receive_frame() implementation for encoders.
+ */
+int ff_encode_receive_frame(AVCodecContext *avctx, AVFrame *frame);
+
/**
* Called by encoders to get the next frame for encoding.
*
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 17e1de8127..fb93d42aa1 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -103,6 +103,14 @@ typedef struct AVCodecInternal {
*/
AVFrame *in_frame;
+ /**
+ * When the AV_CODEC_FLAG_RECON_FRAME flag is used. the encoder should store
+ * here the reconstructed frame corresponding to the last returned packet.
+ *
+ * Not allocated in other cases.
+ */
+ AVFrame *recon_frame;
+
/**
* If this is set, then FFCodec->close (if existing) needs to be called
* for the parent AVCodecContext.
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index e72b4d12b6..35a94c0227 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -57,6 +57,7 @@ static const AVOption avcodec_options[] = {
{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
+{"recon_frame", "export reconstructed frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_RECON_FRAME}, .unit = "flags"},
{"pass1", "use internal 2-pass ratecontrol in first pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
diff --git a/libavcodec/version.h b/libavcodec/version.h
index f2f14eaed1..19f3f4a272 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
#include "version_major.h"
-#define LIBAVCODEC_VERSION_MINOR 39
+#define LIBAVCODEC_VERSION_MINOR 40
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-18 17:41 ` James Almer
@ 2022-07-18 18:07 ` Anton Khirnov
0 siblings, 0 replies; 26+ messages in thread
From: Anton Khirnov @ 2022-07-18 18:07 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Quoting James Almer (2022-07-18 19:41:27)
> Why not ff_encode_alloc_frame() for this? Can
> csp_to_pixfmt(pic_out.img.i_csp) be different than ctx->pix_fmt?
Yes, the reconstructed frame is in x264's internal format, which will
typically be some flavor of nv12, even if the input format is fully
planar.
--
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-18 12:23 ` James Almer
@ 2022-07-18 18:15 ` Anton Khirnov
2022-07-18 18:18 ` James Almer
2022-07-19 12:43 ` Anton Khirnov
1 sibling, 1 reply; 26+ messages in thread
From: Anton Khirnov @ 2022-07-18 18:15 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Quoting James Almer (2022-07-18 14:23:58)
> On 7/18/2022 4:12 AM, Anton Khirnov wrote:
> > ---
> > libavcodec/libx264.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 51 insertions(+), 1 deletion(-)
> >
> > diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> > index 98ec030865..5e360682e6 100644
> > --- a/libavcodec/libx264.c
> > +++ b/libavcodec/libx264.c
> > @@ -311,6 +311,25 @@ static void free_picture(AVCodecContext *ctx)
> > pic->extra_sei.num_payloads = 0;
> > }
> >
> > +static enum AVPixelFormat csp_to_pixfmt(int csp)
> > +{
> > + switch (csp) {
> > +#ifdef X264_CSP_I400
> > + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
> > + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
> > +#endif
> > + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
> > + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
> > + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
> > + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
> > + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
> > + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
>
> We're still supporting old x264 versions, so you should add some
> considerations for 9 bit pixfmts. On X264_BUILD < 153, just check the
> value of x264_bit_depth.
Is there much point in continuing to support 5.5 year old x264? We could
drop a lot of ugliness, including the abominable X264_init_static().
--
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-18 18:15 ` Anton Khirnov
@ 2022-07-18 18:18 ` James Almer
2022-07-18 18:29 ` Anton Khirnov
0 siblings, 1 reply; 26+ messages in thread
From: James Almer @ 2022-07-18 18:18 UTC (permalink / raw)
To: ffmpeg-devel
On 7/18/2022 3:15 PM, Anton Khirnov wrote:
> Quoting James Almer (2022-07-18 14:23:58)
>> On 7/18/2022 4:12 AM, Anton Khirnov wrote:
>>> ---
>>> libavcodec/libx264.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
>>> 1 file changed, 51 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
>>> index 98ec030865..5e360682e6 100644
>>> --- a/libavcodec/libx264.c
>>> +++ b/libavcodec/libx264.c
>>> @@ -311,6 +311,25 @@ static void free_picture(AVCodecContext *ctx)
>>> pic->extra_sei.num_payloads = 0;
>>> }
>>>
>>> +static enum AVPixelFormat csp_to_pixfmt(int csp)
>>> +{
>>> + switch (csp) {
>>> +#ifdef X264_CSP_I400
>>> + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
>>> + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
>>> +#endif
>>> + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
>>> + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
>>> + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
>>> + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
>>> + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
>>> + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
>>
>> We're still supporting old x264 versions, so you should add some
>> considerations for 9 bit pixfmts. On X264_BUILD < 153, just check the
>> value of x264_bit_depth.
>
> Is there much point in continuing to support 5.5 year old x264? We could
> drop a lot of ugliness, including the abominable X264_init_static().
Afaik we tend to support what's shipped with not yet EOL'd big distros
like Debian and Ubuntu. I assume Michael's Ubuntu setup is one of those,
and it has a libx264 without X264_CSP_I400, for example.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-18 18:18 ` James Almer
@ 2022-07-18 18:29 ` Anton Khirnov
2022-07-19 11:44 ` Michael Niedermayer
0 siblings, 1 reply; 26+ messages in thread
From: Anton Khirnov @ 2022-07-18 18:29 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Quoting James Almer (2022-07-18 20:18:16)
>
>
> On 7/18/2022 3:15 PM, Anton Khirnov wrote:
> > Quoting James Almer (2022-07-18 14:23:58)
> >> On 7/18/2022 4:12 AM, Anton Khirnov wrote:
> >>> ---
> >>> libavcodec/libx264.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
> >>> 1 file changed, 51 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> >>> index 98ec030865..5e360682e6 100644
> >>> --- a/libavcodec/libx264.c
> >>> +++ b/libavcodec/libx264.c
> >>> @@ -311,6 +311,25 @@ static void free_picture(AVCodecContext *ctx)
> >>> pic->extra_sei.num_payloads = 0;
> >>> }
> >>>
> >>> +static enum AVPixelFormat csp_to_pixfmt(int csp)
> >>> +{
> >>> + switch (csp) {
> >>> +#ifdef X264_CSP_I400
> >>> + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
> >>> + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
> >>> +#endif
> >>> + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
> >>> + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
> >>> + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
> >>> + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
> >>> + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
> >>> + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
> >>
> >> We're still supporting old x264 versions, so you should add some
> >> considerations for 9 bit pixfmts. On X264_BUILD < 153, just check the
> >> value of x264_bit_depth.
> >
> > Is there much point in continuing to support 5.5 year old x264? We could
> > drop a lot of ugliness, including the abominable X264_init_static().
>
> Afaik we tend to support what's shipped with not yet EOL'd big distros
> like Debian and Ubuntu. I assume Michael's Ubuntu setup is one of those,
> and it has a libx264 without X264_CSP_I400, for example.
Debian oldstable has libx264 155 at least.
--
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc: add API for exporting reconstructed frames from encoders
2022-07-18 18:05 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
@ 2022-07-18 21:29 ` James Almer
0 siblings, 0 replies; 26+ messages in thread
From: James Almer @ 2022-07-18 21:29 UTC (permalink / raw)
To: ffmpeg-devel
On 7/18/2022 3:05 PM, Anton Khirnov wrote:
> ---
> doc/APIchanges | 5 +++++
> libavcodec/avcodec.c | 12 ++++++++++++
> libavcodec/avcodec.h | 20 ++++++++++++++++----
> libavcodec/codec.h | 8 ++++++++
> libavcodec/decode.c | 4 +---
> libavcodec/decode.h | 5 +++++
> libavcodec/encode.c | 25 +++++++++++++++++++++++++
> libavcodec/encode.h | 5 +++++
> libavcodec/internal.h | 8 ++++++++
> libavcodec/options_table.h | 1 +
> libavcodec/version.h | 2 +-
> 11 files changed, 87 insertions(+), 8 deletions(-)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 4e218af94e..b50fece404 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -14,6 +14,11 @@ libavutil: 2021-04-27
>
> API changes, most recent first:
>
> +2022-07-xx - xxxxxxxxxx - lavc 59.40.100 - avcodec.h codec.h
> + Add AV_CODEC_FLAG_RECON_FRAME and AV_CODEC_CAP_ENCODER_RECON_FRAME.
> + avcodec_receive_frame() may now be used on encoders when
> + AV_CODEC_FLAG_RECON_FRAME is active.
> +
> 2022-07-xx - xxxxxxxxxx - lavu 57.30.100 - frame.h
> av_frame_make_writable() may now be called on non-refcounted
> frames and will make a refcounted copy out of them.
LGTM
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-18 18:29 ` Anton Khirnov
@ 2022-07-19 11:44 ` Michael Niedermayer
0 siblings, 0 replies; 26+ messages in thread
From: Michael Niedermayer @ 2022-07-19 11:44 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 2569 bytes --]
On Mon, Jul 18, 2022 at 08:29:56PM +0200, Anton Khirnov wrote:
> Quoting James Almer (2022-07-18 20:18:16)
> >
> >
> > On 7/18/2022 3:15 PM, Anton Khirnov wrote:
> > > Quoting James Almer (2022-07-18 14:23:58)
> > >> On 7/18/2022 4:12 AM, Anton Khirnov wrote:
> > >>> ---
> > >>> libavcodec/libx264.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
> > >>> 1 file changed, 51 insertions(+), 1 deletion(-)
> > >>>
> > >>> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> > >>> index 98ec030865..5e360682e6 100644
> > >>> --- a/libavcodec/libx264.c
> > >>> +++ b/libavcodec/libx264.c
> > >>> @@ -311,6 +311,25 @@ static void free_picture(AVCodecContext *ctx)
> > >>> pic->extra_sei.num_payloads = 0;
> > >>> }
> > >>>
> > >>> +static enum AVPixelFormat csp_to_pixfmt(int csp)
> > >>> +{
> > >>> + switch (csp) {
> > >>> +#ifdef X264_CSP_I400
> > >>> + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
> > >>> + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
> > >>> +#endif
> > >>> + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
> > >>> + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
> > >>> + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
> > >>> + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
> > >>> + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
> > >>> + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
> > >>
> > >> We're still supporting old x264 versions, so you should add some
> > >> considerations for 9 bit pixfmts. On X264_BUILD < 153, just check the
> > >> value of x264_bit_depth.
> > >
> > > Is there much point in continuing to support 5.5 year old x264? We could
> > > drop a lot of ugliness, including the abominable X264_init_static().
> >
> > Afaik we tend to support what's shipped with not yet EOL'd big distros
> > like Debian and Ubuntu. I assume Michael's Ubuntu setup is one of those,
> > and it has a libx264 without X264_CSP_I400, for example.
>
> Debian oldstable has libx264 155 at least.
Ubuntu 18.04LTS has 152
https://packages.ubuntu.com/search?keywords=x264&searchon=names&suite=bionic§ion=all
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
I have never wished to cater to the crowd; for what I know they do not
approve, and what they approve I do not know. -- Epicurus
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-18 12:23 ` James Almer
2022-07-18 18:15 ` Anton Khirnov
@ 2022-07-19 12:43 ` Anton Khirnov
1 sibling, 0 replies; 26+ messages in thread
From: Anton Khirnov @ 2022-07-19 12:43 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Quoting James Almer (2022-07-18 14:23:58)
> On 7/18/2022 4:12 AM, Anton Khirnov wrote:
> > ---
> > libavcodec/libx264.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 51 insertions(+), 1 deletion(-)
> >
> > diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> > index 98ec030865..5e360682e6 100644
> > --- a/libavcodec/libx264.c
> > +++ b/libavcodec/libx264.c
> > @@ -311,6 +311,25 @@ static void free_picture(AVCodecContext *ctx)
> > pic->extra_sei.num_payloads = 0;
> > }
> >
> > +static enum AVPixelFormat csp_to_pixfmt(int csp)
> > +{
> > + switch (csp) {
> > +#ifdef X264_CSP_I400
> > + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
> > + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
> > +#endif
> > + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
> > + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
> > + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
> > + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
> > + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
> > + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
>
> We're still supporting old x264 versions, so you should add some
> considerations for 9 bit pixfmts. On X264_BUILD < 153, just check the
> value of x264_bit_depth.
This will actually build even with pre-153 versions, except subsampled
(420/422) 10-bit reconstructed frames won't actually work with any
version because we lack a pixel format for them (higher-bit nv12
analogue).
--
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* [FFmpeg-devel] [PATCH v2] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-17 19:27 ` [FFmpeg-devel] [PATCH 4/4] lavc/libx264: " Anton Khirnov
2022-07-17 22:06 ` Michael Niedermayer
@ 2022-07-19 12:47 ` Anton Khirnov
2022-07-19 12:51 ` James Almer
1 sibling, 1 reply; 26+ messages in thread
From: Anton Khirnov @ 2022-07-19 12:47 UTC (permalink / raw)
To: ffmpeg-devel
---
Now tested with x264 118, the oldest supported.
---
libavcodec/libx264.c | 57 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index e8c1fb2106..04e8147276 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -311,6 +311,28 @@ static void free_picture(AVCodecContext *ctx)
pic->extra_sei.num_payloads = 0;
}
+static enum AVPixelFormat csp_to_pixfmt(int csp)
+{
+ switch (csp) {
+#ifdef X264_CSP_I400
+ case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
+ case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
+#endif
+ case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
+ case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
+ case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
+ case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
+ case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
+ case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
+ case X264_CSP_NV12: return AV_PIX_FMT_NV12;
+#ifdef X264_CSP_NV21
+ case X264_CSP_NV21: return AV_PIX_FMT_NV21;
+#endif
+ case X264_CSP_NV16: return AV_PIX_FMT_NV16;
+ };
+ return AV_PIX_FMT_NONE;
+}
+
static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
int *got_packet)
{
@@ -496,6 +518,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
return AVERROR_EXTERNAL;
+ if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ AVCodecInternal *avci = ctx->internal;
+
+ av_frame_unref(avci->recon_frame);
+
+ avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
+ if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Unhandled reconstructed frame colorspace: %d\n",
+ pic_out.img.i_csp);
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame->width = ctx->width;
+ avci->recon_frame->height = ctx->height;
+ for (int i = 0; i < pic_out.img.i_plane; i++) {
+ avci->recon_frame->data[i] = pic_out.img.plane[i];
+ avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
+ }
+
+ ret = av_frame_make_writable(avci->recon_frame);
+ if (ret < 0) {
+ av_frame_unref(avci->recon_frame);
+ return ret;
+ }
+ }
+
ret = encode_nals(ctx, pkt, nal, nnal);
if (ret < 0)
return ret;
@@ -928,6 +977,11 @@ static av_cold int X264_init(AVCodecContext *avctx)
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
+#if X264_BUILD >= 122
+ if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
+ x4->params.b_full_recon = 1;
+#endif
+
if(x4->x264opts){
const char *p= x4->x264opts;
while(p){
@@ -1223,7 +1277,8 @@ FFCodec ff_libx264_encoder = {
.p.id = AV_CODEC_ID_H264,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_OTHER_THREADS |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.priv_class = &x264_class,
.p.wrapper_name = "libx264",
.priv_data_size = sizeof(X264Context),
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-19 12:47 ` [FFmpeg-devel] [PATCH v2] " Anton Khirnov
@ 2022-07-19 12:51 ` James Almer
2022-07-19 12:57 ` Anton Khirnov
0 siblings, 1 reply; 26+ messages in thread
From: James Almer @ 2022-07-19 12:51 UTC (permalink / raw)
To: ffmpeg-devel
On 7/19/2022 9:47 AM, Anton Khirnov wrote:
> ---
> Now tested with x264 118, the oldest supported.
> ---
> libavcodec/libx264.c | 57 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 56 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> index e8c1fb2106..04e8147276 100644
> --- a/libavcodec/libx264.c
> +++ b/libavcodec/libx264.c
> @@ -311,6 +311,28 @@ static void free_picture(AVCodecContext *ctx)
> pic->extra_sei.num_payloads = 0;
> }
>
> +static enum AVPixelFormat csp_to_pixfmt(int csp)
> +{
> + switch (csp) {
> +#ifdef X264_CSP_I400
> + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
> + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
> +#endif
> + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
> + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
> + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
> + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
> + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
> + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
> + case X264_CSP_NV12: return AV_PIX_FMT_NV12;
> +#ifdef X264_CSP_NV21
> + case X264_CSP_NV21: return AV_PIX_FMT_NV21;
> +#endif
> + case X264_CSP_NV16: return AV_PIX_FMT_NV16;
> + };
> + return AV_PIX_FMT_NONE;
> +}
> +
> static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
> int *got_packet)
> {
> @@ -496,6 +518,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
> if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
> return AVERROR_EXTERNAL;
>
> + if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
> + AVCodecInternal *avci = ctx->internal;
> +
> + av_frame_unref(avci->recon_frame);
> +
> + avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
> + if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
> + av_log(ctx, AV_LOG_ERROR,
> + "Unhandled reconstructed frame colorspace: %d\n",
> + pic_out.img.i_csp);
> + return AVERROR(ENOSYS);
> + }
> +
> + avci->recon_frame->width = ctx->width;
> + avci->recon_frame->height = ctx->height;
> + for (int i = 0; i < pic_out.img.i_plane; i++) {
> + avci->recon_frame->data[i] = pic_out.img.plane[i];
> + avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
> + }
> +
> + ret = av_frame_make_writable(avci->recon_frame);
> + if (ret < 0) {
> + av_frame_unref(avci->recon_frame);
> + return ret;
> + }
> + }
> +
> ret = encode_nals(ctx, pkt, nal, nnal);
> if (ret < 0)
> return ret;
> @@ -928,6 +977,11 @@ static av_cold int X264_init(AVCodecContext *avctx)
> if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
> x4->params.b_repeat_headers = 0;
>
> +#if X264_BUILD >= 122
> + if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
> + x4->params.b_full_recon = 1;
If this is only >= 122, what will pic_out above contain in older versions?
> +#endif
> +
> if(x4->x264opts){
> const char *p= x4->x264opts;
> while(p){
> @@ -1223,7 +1277,8 @@ FFCodec ff_libx264_encoder = {
> .p.id = AV_CODEC_ID_H264,
> .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_OTHER_THREADS |
> - AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
> + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
> + AV_CODEC_CAP_ENCODER_RECON_FRAME,
> .p.priv_class = &x264_class,
> .p.wrapper_name = "libx264",
> .priv_data_size = sizeof(X264Context),
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-19 12:51 ` James Almer
@ 2022-07-19 12:57 ` Anton Khirnov
2022-07-19 18:13 ` James Almer
0 siblings, 1 reply; 26+ messages in thread
From: Anton Khirnov @ 2022-07-19 12:57 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Quoting James Almer (2022-07-19 14:51:13)
> If this is only >= 122, what will pic_out above contain in older versions?
IIUC it won't do deblocking, so the reconstructed frame won't be exactly
as decoded.
--
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-19 12:57 ` Anton Khirnov
@ 2022-07-19 18:13 ` James Almer
2022-07-28 14:24 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
0 siblings, 1 reply; 26+ messages in thread
From: James Almer @ 2022-07-19 18:13 UTC (permalink / raw)
To: ffmpeg-devel
On 7/19/2022 9:57 AM, Anton Khirnov wrote:
> Quoting James Almer (2022-07-19 14:51:13)
>> If this is only >= 122, what will pic_out above contain in older versions?
>
> IIUC it won't do deblocking, so the reconstructed frame won't be exactly
> as decoded.
That kinda defeats the purpose, and is also inconsistent. Maybe we can
signal somehow at the API level that the reconstructed frame is not
fully done? Or making the kind of reconstruction the user requests
explicit, like having the recon_frame AVOption be an enum in
AVCodecContext with defined values like full_recon (hard requirement),
partial_recon (soft requirement, may still return full recon if that's
all the encoder can generate), etc, instead of simply a flag for
avctx->flags?
Or just disabling it for libx264 this old so output/behavior is
consistent across all encoders regardless of version and the API remains
as simple as possible.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-19 18:13 ` James Almer
@ 2022-07-28 14:24 ` Anton Khirnov
2022-07-28 14:33 ` James Almer
0 siblings, 1 reply; 26+ messages in thread
From: Anton Khirnov @ 2022-07-28 14:24 UTC (permalink / raw)
To: ffmpeg-devel
Bump the version requirement to 122, which introduced b_full_recon.
---
configure | 2 +-
libavcodec/libx264.c | 55 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 6629d14099..50d73a5325 100755
--- a/configure
+++ b/configure
@@ -6674,7 +6674,7 @@ enabled libwebp && {
enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
- require_cpp_condition libx264 x264.h "X264_BUILD >= 118" && {
+ require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && {
[ "$toolchain" != "msvc" ] ||
require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
check_cpp_condition libx262 x264.h "X264_MPEG2"
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index e8c1fb2106..6afa3cdadb 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -311,6 +311,28 @@ static void free_picture(AVCodecContext *ctx)
pic->extra_sei.num_payloads = 0;
}
+static enum AVPixelFormat csp_to_pixfmt(int csp)
+{
+ switch (csp) {
+#ifdef X264_CSP_I400
+ case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
+ case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
+#endif
+ case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
+ case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
+ case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
+ case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
+ case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
+ case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
+ case X264_CSP_NV12: return AV_PIX_FMT_NV12;
+#ifdef X264_CSP_NV21
+ case X264_CSP_NV21: return AV_PIX_FMT_NV21;
+#endif
+ case X264_CSP_NV16: return AV_PIX_FMT_NV16;
+ };
+ return AV_PIX_FMT_NONE;
+}
+
static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
int *got_packet)
{
@@ -496,6 +518,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
return AVERROR_EXTERNAL;
+ if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ AVCodecInternal *avci = ctx->internal;
+
+ av_frame_unref(avci->recon_frame);
+
+ avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
+ if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Unhandled reconstructed frame colorspace: %d\n",
+ pic_out.img.i_csp);
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame->width = ctx->width;
+ avci->recon_frame->height = ctx->height;
+ for (int i = 0; i < pic_out.img.i_plane; i++) {
+ avci->recon_frame->data[i] = pic_out.img.plane[i];
+ avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
+ }
+
+ ret = av_frame_make_writable(avci->recon_frame);
+ if (ret < 0) {
+ av_frame_unref(avci->recon_frame);
+ return ret;
+ }
+ }
+
ret = encode_nals(ctx, pkt, nal, nnal);
if (ret < 0)
return ret;
@@ -928,6 +977,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
+ if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
+ x4->params.b_full_recon = 1;
+
if(x4->x264opts){
const char *p= x4->x264opts;
while(p){
@@ -1223,7 +1275,8 @@ FFCodec ff_libx264_encoder = {
.p.id = AV_CODEC_ID_H264,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_OTHER_THREADS |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.priv_class = &x264_class,
.p.wrapper_name = "libx264",
.priv_data_size = sizeof(X264Context),
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-07-28 14:24 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
@ 2022-07-28 14:33 ` James Almer
0 siblings, 0 replies; 26+ messages in thread
From: James Almer @ 2022-07-28 14:33 UTC (permalink / raw)
To: ffmpeg-devel
On 7/28/2022 11:24 AM, Anton Khirnov wrote:
> Bump the version requirement to 122, which introduced b_full_recon.
> ---
> configure | 2 +-
> libavcodec/libx264.c | 55 +++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/configure b/configure
> index 6629d14099..50d73a5325 100755
> --- a/configure
> +++ b/configure
> @@ -6674,7 +6674,7 @@ enabled libwebp && {
> enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
> enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
> enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
> - require_cpp_condition libx264 x264.h "X264_BUILD >= 118" && {
> + require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && {
> [ "$toolchain" != "msvc" ] ||
> require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
> check_cpp_condition libx262 x264.h "X264_MPEG2"
> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> index e8c1fb2106..6afa3cdadb 100644
> --- a/libavcodec/libx264.c
> +++ b/libavcodec/libx264.c
> @@ -311,6 +311,28 @@ static void free_picture(AVCodecContext *ctx)
> pic->extra_sei.num_payloads = 0;
> }
>
> +static enum AVPixelFormat csp_to_pixfmt(int csp)
> +{
> + switch (csp) {
> +#ifdef X264_CSP_I400
> + case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
> + case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
> +#endif
> + case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
> + case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
> + case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
> + case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
> + case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
> + case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
> + case X264_CSP_NV12: return AV_PIX_FMT_NV12;
> +#ifdef X264_CSP_NV21
> + case X264_CSP_NV21: return AV_PIX_FMT_NV21;
> +#endif
> + case X264_CSP_NV16: return AV_PIX_FMT_NV16;
> + };
> + return AV_PIX_FMT_NONE;
> +}
> +
> static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
> int *got_packet)
> {
> @@ -496,6 +518,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
> if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
> return AVERROR_EXTERNAL;
>
> + if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
> + AVCodecInternal *avci = ctx->internal;
> +
> + av_frame_unref(avci->recon_frame);
> +
> + avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
> + if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
> + av_log(ctx, AV_LOG_ERROR,
> + "Unhandled reconstructed frame colorspace: %d\n",
> + pic_out.img.i_csp);
> + return AVERROR(ENOSYS);
> + }
> +
> + avci->recon_frame->width = ctx->width;
> + avci->recon_frame->height = ctx->height;
> + for (int i = 0; i < pic_out.img.i_plane; i++) {
> + avci->recon_frame->data[i] = pic_out.img.plane[i];
> + avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
> + }
> +
> + ret = av_frame_make_writable(avci->recon_frame);
> + if (ret < 0) {
> + av_frame_unref(avci->recon_frame);
> + return ret;
> + }
> + }
> +
> ret = encode_nals(ctx, pkt, nal, nnal);
> if (ret < 0)
> return ret;
> @@ -928,6 +977,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
> if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
> x4->params.b_repeat_headers = 0;
>
> + if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
> + x4->params.b_full_recon = 1;
> +
> if(x4->x264opts){
> const char *p= x4->x264opts;
> while(p){
> @@ -1223,7 +1275,8 @@ FFCodec ff_libx264_encoder = {
> .p.id = AV_CODEC_ID_H264,
> .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_OTHER_THREADS |
> - AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
> + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
> + AV_CODEC_CAP_ENCODER_RECON_FRAME,
> .p.priv_class = &x264_class, > .p.wrapper_name = "libx264",
> .priv_data_size = sizeof(X264Context),
LGTM.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
2022-08-08 8:57 [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME Martin Storsjö
@ 2022-08-08 8:59 ` Martin Storsjö
0 siblings, 0 replies; 26+ messages in thread
From: Martin Storsjö @ 2022-08-08 8:59 UTC (permalink / raw)
To: ffmpeg-devel
On Mon, 8 Aug 2022, Martin Storsjö wrote:
> From: Anton Khirnov <anton@khirnov.net>
>
> Bump the version requirement to 122, which introduced b_full_recon.
> ---
> configure | 2 +-
> libavcodec/libx264.c | 55 +++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 55 insertions(+), 2 deletions(-)
Sorry, disregard, I accidentally ran send-email on the wrong branch...
// Martin
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
* [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME
@ 2022-08-08 8:57 Martin Storsjö
2022-08-08 8:59 ` Martin Storsjö
0 siblings, 1 reply; 26+ messages in thread
From: Martin Storsjö @ 2022-08-08 8:57 UTC (permalink / raw)
To: ffmpeg-devel
From: Anton Khirnov <anton@khirnov.net>
Bump the version requirement to 122, which introduced b_full_recon.
---
configure | 2 +-
libavcodec/libx264.c | 55 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index eb413a6716..700003aba3 100755
--- a/configure
+++ b/configure
@@ -6675,7 +6675,7 @@ enabled libwebp && {
enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
- require_cpp_condition libx264 x264.h "X264_BUILD >= 118" && {
+ require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && {
[ "$toolchain" != "msvc" ] ||
require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
check_cpp_condition libx262 x264.h "X264_MPEG2"
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index e8c1fb2106..6afa3cdadb 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -311,6 +311,28 @@ static void free_picture(AVCodecContext *ctx)
pic->extra_sei.num_payloads = 0;
}
+static enum AVPixelFormat csp_to_pixfmt(int csp)
+{
+ switch (csp) {
+#ifdef X264_CSP_I400
+ case X264_CSP_I400: return AV_PIX_FMT_GRAY8;
+ case X264_CSP_I400 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_GRAY10;
+#endif
+ case X264_CSP_I420: return AV_PIX_FMT_YUV420P;
+ case X264_CSP_I420 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV420P10;
+ case X264_CSP_I422: return AV_PIX_FMT_YUV422P;
+ case X264_CSP_I422 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV422P10;
+ case X264_CSP_I444: return AV_PIX_FMT_YUV444P;
+ case X264_CSP_I444 | X264_CSP_HIGH_DEPTH: return AV_PIX_FMT_YUV444P10;
+ case X264_CSP_NV12: return AV_PIX_FMT_NV12;
+#ifdef X264_CSP_NV21
+ case X264_CSP_NV21: return AV_PIX_FMT_NV21;
+#endif
+ case X264_CSP_NV16: return AV_PIX_FMT_NV16;
+ };
+ return AV_PIX_FMT_NONE;
+}
+
static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
int *got_packet)
{
@@ -496,6 +518,33 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
return AVERROR_EXTERNAL;
+ if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
+ AVCodecInternal *avci = ctx->internal;
+
+ av_frame_unref(avci->recon_frame);
+
+ avci->recon_frame->format = csp_to_pixfmt(pic_out.img.i_csp);
+ if (avci->recon_frame->format == AV_PIX_FMT_NONE) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Unhandled reconstructed frame colorspace: %d\n",
+ pic_out.img.i_csp);
+ return AVERROR(ENOSYS);
+ }
+
+ avci->recon_frame->width = ctx->width;
+ avci->recon_frame->height = ctx->height;
+ for (int i = 0; i < pic_out.img.i_plane; i++) {
+ avci->recon_frame->data[i] = pic_out.img.plane[i];
+ avci->recon_frame->linesize[i] = pic_out.img.i_stride[i];
+ }
+
+ ret = av_frame_make_writable(avci->recon_frame);
+ if (ret < 0) {
+ av_frame_unref(avci->recon_frame);
+ return ret;
+ }
+ }
+
ret = encode_nals(ctx, pkt, nal, nnal);
if (ret < 0)
return ret;
@@ -928,6 +977,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
+ if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME)
+ x4->params.b_full_recon = 1;
+
if(x4->x264opts){
const char *p= x4->x264opts;
while(p){
@@ -1223,7 +1275,8 @@ FFCodec ff_libx264_encoder = {
.p.id = AV_CODEC_ID_H264,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_OTHER_THREADS |
- AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
+ AV_CODEC_CAP_ENCODER_RECON_FRAME,
.p.priv_class = &x264_class,
.p.wrapper_name = "libx264",
.priv_data_size = sizeof(X264Context),
--
2.32.0 (Apple Git-132)
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2022-08-08 8:59 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-17 19:26 [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames Anton Khirnov
2022-07-17 19:26 ` [FFmpeg-devel] [PATCH 2/4] lavc: add API for exporting reconstructed frames from encoders Anton Khirnov
2022-07-18 12:35 ` James Almer
2022-07-18 18:05 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
2022-07-18 21:29 ` James Almer
2022-07-17 19:26 ` [FFmpeg-devel] [PATCH 3/4] lavc/mpegvideo_enc: support AV_CODEC_CAP_ENCODER_RECON_FRAME Anton Khirnov
2022-07-17 19:27 ` [FFmpeg-devel] [PATCH 4/4] lavc/libx264: " Anton Khirnov
2022-07-17 22:06 ` Michael Niedermayer
2022-07-18 7:12 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
2022-07-18 12:23 ` James Almer
2022-07-18 18:15 ` Anton Khirnov
2022-07-18 18:18 ` James Almer
2022-07-18 18:29 ` Anton Khirnov
2022-07-19 11:44 ` Michael Niedermayer
2022-07-19 12:43 ` Anton Khirnov
2022-07-18 17:41 ` James Almer
2022-07-18 18:07 ` Anton Khirnov
2022-07-19 12:47 ` [FFmpeg-devel] [PATCH v2] " Anton Khirnov
2022-07-19 12:51 ` James Almer
2022-07-19 12:57 ` Anton Khirnov
2022-07-19 18:13 ` James Almer
2022-07-28 14:24 ` [FFmpeg-devel] [PATCH] " Anton Khirnov
2022-07-28 14:33 ` James Almer
2022-07-18 12:24 ` [FFmpeg-devel] [PATCH 1/4] lavu/frame: allow calling av_frame_make_writable() on non-refcounted frames James Almer
2022-08-08 8:57 [FFmpeg-devel] [PATCH] lavc/libx264: support AV_CODEC_CAP_ENCODER_RECON_FRAME Martin Storsjö
2022-08-08 8:59 ` Martin Storsjö
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git