From: Anton Khirnov <anton@khirnov.net> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] [PATCH 2/3] Provided support for MPEG-5 EVC (Essential Video Coding) codec Date: Fri, 01 Jul 2022 11:46:46 +0200 Message-ID: <165666880602.10358.13818155906416078223@lain.khirnov.net> (raw) In-Reply-To: <00bb01d88604$29cbc180$7d634480$@samsung.com> Quoting Dawid Kozinski (2022-06-22 08:49:04) > - Added xeve encoder wrapper > - Added xevd dencoder wrapper > - Added documentation for xeve and xevd wrappers > - Added parser for EVC format > - Changes in project configuration file and libavcodec Makefile > > Signed-off-by: Dawid Kozinski <d.kozinski@samsung.com> > --- > configure | 8 + > doc/decoders.texi | 24 ++ > doc/encoders.texi | 112 ++++++ > doc/general_contents.texi | 19 + > libavcodec/Makefile | 3 + > libavcodec/allcodecs.c | 2 + > libavcodec/avcodec.h | 3 + > libavcodec/evc_parser.c | 527 ++++++++++++++++++++++++++ > libavcodec/libxevd.c | 440 ++++++++++++++++++++++ > libavcodec/libxeve.c | 753 ++++++++++++++++++++++++++++++++++++++ > libavcodec/parsers.c | 1 + > 11 files changed, 1892 insertions(+) > create mode 100644 libavcodec/evc_parser.c > create mode 100644 libavcodec/libxevd.c > create mode 100644 libavcodec/libxeve.c Numerous violations of our coding style, such as - keywords (if, for, etc.) should be followed by a space before parentheses - opening brace for blocks inside functions should be on the same line as their keyword (if, for, etc.) - useless extra parentheses in if()s I will not point out each instance, please find and fix those. > diff --git a/doc/encoders.texi b/doc/encoders.texi > index 1850c99fe9..245df680d2 100644 > --- a/doc/encoders.texi > +++ b/doc/encoders.texi > @@ -2892,6 +2892,118 @@ ffmpeg -i input -c:v libxavs2 -xavs2-params RdoqLevel=0 output.avs2 > @end example > @end table > > +@section libxeve > + > +eXtra-fast Essential Video Encoder (XEVE) MPEG-5 EVC encoder wrapper. > + > +This encoder requires the presence of the libxeve headers and library > +during configuration. You need to explicitly configure the build with > +@option{--enable-libxeve}. > + > +@float NOTE > +Many libxeve encoder options are mapped to FFmpeg global codec options, > +while unique encoder options are provided through private options. > +Additionally the xeve-params private options allows one to pass a list > +of key=value tuples as accepted by the libxeve @code{parse_xeve_params} function. > +@end float > + > +The xeve project website is at @url{https://github.com/mpeg5/xeve}. > + > +@subsection Options > + > +The following options are supported by the libxeve wrapper. > +The xeve-equivalent options or values are listed in parentheses for easy migration. > + > +@float NOTE > +To reduce the duplication of documentation, only the private options > +and some others requiring special attention are documented here. For > +the documentation of the undocumented generic options, see > +@ref{codec-options,,the Codec Options chapter}. > +@end float > + > +@float NOTE > +To get a more accurate and extensive documentation of the libxeve options, > +invoke the command @code{xeve_app --help} or consult the libxeve documentation. > +@end float > + > +@table @option > +@item b (@emph{bitrate}) > +Set target video bitrate in bits/s. > +Note that FFmpeg’s b option is expressed in bits/s, while xeve’s bitrate is in kilobits/s. Looks broken. > diff --git a/libavcodec/libxeve.c b/libavcodec/libxeve.c > new file mode 100644 > index 0000000000..e115ce63d2 > --- /dev/null > +++ b/libavcodec/libxeve.c > +/** > + * The structure stores all the states associated with the instance of Xeve MPEG-5 EVC encoder > + */ > +typedef struct XeveContext { > + const AVClass *class; > + > + XEVE id; // XEVE instance identifier > + XEVE_CDSC cdsc; // coding parameters i.e profile, width & height of input frame, num of therads, frame rate ... > + XEVE_BITB bitb; // bitstream buffer (output) > + XEVE_STAT stat; // encoding status (output) > + XEVE_IMGB imgb; // image buffer (input) > + > + State state; // encoder state (skipping, encoding, bumping) > + > + // Chroma subsampling > + int width_luma; > + int height_luma; > + int width_chroma; > + int height_chroma; All these are only used in init, no need to store them in the context. > +/** > + * Gets Xeve pre-defined preset > + * > + * @param preset string describing Xeve encoder preset (fast, medium, slow, placebo) > + * @return XEVE pre-defined profile on success, negative value on failure > + */ > +static int get_preset_id(const char *preset) > +{ > + if((!strcmp(preset, "fast"))) > + return XEVE_PRESET_FAST; > + else if (!strcmp(preset, "medium")) > + return XEVE_PRESET_MEDIUM; > + else if (!strcmp(preset, "slow")) > + return XEVE_PRESET_SLOW; > + else if (!strcmp(preset, "placebo")) > + return XEVE_PRESET_PLACEBO; > + else > + return AVERROR(EINVAL); > +} This parsing is unnecessary, change the relevant option into an int and add named constants for it (see e.g. "coder" in libx264.c and many others). Same for tune. > +/** > + * Convert FFmpeg pixel format (AVPixelFormat) into XEVE pre-defined color space > + * > + * @param[in] px_fmt pixel format (@see https://ffmpeg.org/doxygen/trunk/pixfmt_8h.html#a9a8e335cf3be472042bc9f0cf80cd4c5) > + * > + * @return XEVE pre-defined color space (@see xeve.h) on success, XEVE_CF_UNKNOWN on failure > + */ > +static int xeve_color_space(enum AVPixelFormat av_pix_fmt) IIUC the "xeve_" namespace is used by the library, so we should not declare any such names ourselves. Use "libxeve_" or something. > +/** > + * Parse : separated list of key=value parameters > + * > + * @param[in] avctx context for logger > + * @param[in] key > + * @param[in] value > + * @param[out] cdsc contains all Xeve MPEG-5 EVC encoder encoder parameters that > + * should be initialized before the encoder is use > + * > + * @return 0 on success, negative value on failure > + */ > +static int parse_xeve_params(AVCodecContext *avctx, const char *key, const char *value, XEVE_CDSC* cdsc) What is the point of parsing options here instead of declaring them as AVOptions? Especially when vbv-bufsize can already be set using the global "bufsize" option. > + xeve_color_fmt(avctx->pix_fmt, &xectx->color_format); > + > +#if AV_HAVE_BIGENDIAN > + cdsc->param.cs = XEVE_CS_SET(xectx->color_format, cdsc->param.codec_bit_depth, 1); > +#else > + cdsc->param.cs = XEVE_CS_SET(xectx->color_format, cdsc->param.codec_bit_depth, 0); > +#endif just pass AV_HAVE_BIGENDIAN as the last macro parameter, no need for #ifs > +static int set_extra_config(AVCodecContext* avctx, XEVE id, XeveContext *ctx) > +{ > + int ret, size, value; > + size = 4; > + > + // embed SEI messages identifying encoder parameters and command line arguments > + // - 0: off\n" > + // - 1: emit sei info" > + // > + // SEI - Supplemental enhancement information contains information > + // that is not necessary to decode the samples of coded pictures from VCL NAL units. > + // Some SEI message information is required to check bitstream conformance > + // and for output timing decoder conformance. > + // @see ISO_IEC_23094-1_2020 7.4.3.5 > + // @see ISO_IEC_23094-1_2020 Annex D > + ret = xeve_config(id, XEVE_CFG_SET_SEI_CMD, &value, &size); // sei_cmd_info Is this not reading value, which is uninitialized? > +/** > + * Encode raw data frame into EVC packet > + * > + * @param[in] avctx codec context > + * @param[out] pkt output AVPacket containing encoded data > + * @param[in] frame AVFrame containing the raw data to be encoded > + * @param[out] got_packet encoder sets to 0 or 1 to indicate that a > + * non-empty packet was returned in pkt > + * > + * @return 0 on success, negative error code on failure > + */ > +static int libxeve_encode(AVCodecContext *avctx, AVPacket *avpkt, > + const AVFrame *frame, int *got_packet) > +{ > + XeveContext *xectx = avctx->priv_data; > + int ret = -1; > + int xeve_cs; > + > + if(xectx->state == STATE_SKIPPING && frame ) { > + xectx->state = STATE_ENCODING; // Entering encoding process > + } else if(xectx->state == STATE_ENCODING && frame == NULL) { This state switching looks wrong. frame will be NULL only at the end of encoding. It should never happen that libxeve_encode() is called with frame==NULL and then later with frame!=NULL. Also, the logic might be simpler if you used the receive_packet callback rather than encode. > + if (setup_bumping(xectx->id) == 0) > + xectx->state = STATE_BUMPING; // Entering bumping process > + else { > + av_log(avctx, AV_LOG_ERROR, "Failed to setup bumping\n"); > + xectx->state = STATE_SKIPPING; > + } > + } > + > + if(xectx->state == STATE_ENCODING) { > + const AVPixFmtDescriptor *pixel_fmt_desc = av_pix_fmt_desc_get (frame->format); > + if(!pixel_fmt_desc) { > + av_log(avctx, AV_LOG_ERROR, "Invalid pixel format descriptor for pixel format: %s\n", av_get_pix_fmt_name(avctx->pix_fmt)); > + return AVERROR_INVALIDDATA; > + } This seems unused. > + > + xeve_cs = xeve_color_space(avctx->pix_fmt); > + if(xeve_cs != XEVE_CS_YCBCR420 && xeve_cs != XEVE_CS_YCBCR420_10LE) { > + av_log(avctx, AV_LOG_ERROR, "Invalid pixel format: %s\n", av_get_pix_fmt_name(avctx->pix_fmt)); > + return AVERROR_INVALIDDATA; > + } This should be done once during encoder init. Also declaring a list of supported pixel formats in the FFCodec struct guarantees that you will only get one of those formats, so you don't need to check for it yourself. > + > + { > + int i; > + XEVE_IMGB *imgb = NULL; > + > + imgb = &xectx->imgb; > + > + for (i = 0; i < imgb->np; i++) { > + imgb->a[i] = frame->data[i]; > + imgb->s[i] = frame->linesize[i]; > + } How does the ownership semantics work here? Does libxeve make a copy? > + if(xectx->id == NULL) { > + av_log(avctx, AV_LOG_ERROR, "Invalid XEVE encoder\n"); > + return AVERROR_INVALIDDATA; > + } Can this happen? > + > + imgb->ts[0] = frame->pts; > + imgb->ts[1] = 0; Will a proper dts value be generated by the library? -- 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".
next prev parent reply other threads:[~2022-07-01 9:46 UTC|newest] Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <CGME20220622064904eucas1p19bbbc922c4f1b734730c48169bada35a@eucas1p1.samsung.com> 2022-06-22 6:49 ` Dawid Kozinski 2022-07-01 9:46 ` Anton Khirnov [this message] [not found] <CGME20220512060536eucas1p262e353ab046a9c672e44aec493ef7d4f@eucas1p2.samsung.com> 2022-05-12 6:05 ` Dawid Kozinski 2022-06-01 11:41 ` Andreas Rheinhardt [not found] <CGME20220420123208eucas1p1359df4487ab7f4a7edde29b4f80cdfdc@eucas1p1.samsung.com> 2022-04-20 12:32 ` Dawid Kozinski [not found] <CGME20220420095424eucas1p13b9dc5cacc7b763a05ac32ca25b14e69@eucas1p1.samsung.com> 2022-04-20 9:54 ` Dawid Kozinski
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=165666880602.10358.13818155906416078223@lain.khirnov.net \ --to=anton@khirnov.net \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
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