[FFmpeg-devel] [PATCH 81/87] avcodec: Move all AVCodecParser.split functions to remove_extradata_bsf
John Stebbins
jstebbins at jetheaddev.com
Thu May 12 18:14:20 EEST 2022
Hi all,
I know this happened quite some time ago, but we just noticed the
change.
This effectively disables the public API AVCodecParser.split for these
codecs. HandBrake uses this API to split out extradata for a few
codecs. Any chance we can bring these back? Otherwise, we will have to
replicate this code in HandBrake 😕️
On Mon, 2021-04-19 at 11:10 -0300, James Almer wrote:
> From: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
>
> The remove_extradata bsf is the only user of these functions.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
> ---
> libavcodec/Makefile | 4 +-
> libavcodec/av1_parser.c | 25 +---
> libavcodec/avs2_parser.c | 1 -
> libavcodec/avs3_parser.c | 1 -
> libavcodec/cavs_parser.c | 1 -
> libavcodec/h264_parser.c | 38 ------
> libavcodec/hevc_parser.c | 34 -----
> libavcodec/mpeg4video_parser.c | 1 -
> libavcodec/mpegvideo_parser.c | 18 ---
> libavcodec/parser.c | 14 ---
> libavcodec/remove_extradata_bsf.c | 201 +++++++++++++++++++++++++---
> --
> libavcodec/vc1_parser.c | 19 ---
> 12 files changed, 171 insertions(+), 186 deletions(-)
>
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index a640c548e5..c19a3cb60d 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -1075,7 +1075,7 @@ OBJS-$(CONFIG_AAC_PARSER) +=
> aac_parser.o aac_ac3_parser.o \
> mpeg4audio.o
> OBJS-$(CONFIG_AC3_PARSER) += ac3tab.o aac_ac3_parser.o
> OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o
> -OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o av1_parse.o
> +OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o
> OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o
> OBJS-$(CONFIG_AVS3_PARSER) += avs3_parser.o
> OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o
> @@ -1159,7 +1159,7 @@ OBJS-$(CONFIG_NULL_BSF) +=
> null_bsf.o
> OBJS-$(CONFIG_OPUS_METADATA_BSF) += opus_metadata_bsf.o
> OBJS-$(CONFIG_PCM_RECHUNK_BSF) += pcm_rechunk_bsf.o
> OBJS-$(CONFIG_PRORES_METADATA_BSF) += prores_metadata_bsf.o
> -OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o
> +OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o
> av1_parse.o
> OBJS-$(CONFIG_SETTS_BSF) += setts_bsf.o
> OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o
> OBJS-$(CONFIG_TRACE_HEADERS_BSF) += trace_headers_bsf.o
> diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c
> index 578f5293c8..b6c8004ee3 100644
> --- a/libavcodec/av1_parser.c
> +++ b/libavcodec/av1_parser.c
> @@ -20,7 +20,7 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> */
>
> -#include "av1_parse.h"
> +#include "libavutil/avassert.h"
> #include "cbs.h"
> #include "cbs_av1.h"
> #include "internal.h"
> @@ -205,33 +205,10 @@ static void
> av1_parser_close(AVCodecParserContext *ctx)
> ff_cbs_close(&s->cbc);
> }
>
> -static int av1_parser_split(AVCodecContext *avctx,
> - const uint8_t *buf, int buf_size)
> -{
> - AV1OBU obu;
> - const uint8_t *ptr = buf, *end = buf + buf_size;
> -
> - while (ptr < end) {
> - int len = ff_av1_extract_obu(&obu, ptr, buf_size, avctx);
> - if (len < 0)
> - break;
> -
> - if (obu.type == AV1_OBU_FRAME_HEADER ||
> - obu.type == AV1_OBU_FRAME) {
> - return ptr - buf;
> - }
> - ptr += len;
> - buf_size -= len;
> - }
> -
> - return 0;
> -}
> -
> const AVCodecParser ff_av1_parser = {
> .codec_ids = { AV_CODEC_ID_AV1 },
> .priv_data_size = sizeof(AV1ParseContext),
> .parser_init = av1_parser_init,
> .parser_close = av1_parser_close,
> .parser_parse = av1_parser_parse,
> - .split = av1_parser_split,
> };
> diff --git a/libavcodec/avs2_parser.c b/libavcodec/avs2_parser.c
> index 059faf77c5..b7d5d7774e 100644
> --- a/libavcodec/avs2_parser.c
> +++ b/libavcodec/avs2_parser.c
> @@ -91,5 +91,4 @@ const AVCodecParser ff_avs2_parser = {
> .priv_data_size = sizeof(ParseContext),
> .parser_parse = avs2_parse,
> .parser_close = ff_parse_close,
> - .split = ff_mpeg4video_split,
> };
> diff --git a/libavcodec/avs3_parser.c b/libavcodec/avs3_parser.c
> index b0e720a844..1a05ea042e 100644
> --- a/libavcodec/avs3_parser.c
> +++ b/libavcodec/avs3_parser.c
> @@ -175,5 +175,4 @@ const AVCodecParser ff_avs3_parser = {
> .priv_data_size = sizeof(ParseContext),
> .parser_parse = avs3_parse,
> .parser_close = ff_parse_close,
> - .split = ff_mpeg4video_split,
> };
> diff --git a/libavcodec/cavs_parser.c b/libavcodec/cavs_parser.c
> index 20adca1dbc..03f392c2e5 100644
> --- a/libavcodec/cavs_parser.c
> +++ b/libavcodec/cavs_parser.c
> @@ -102,5 +102,4 @@ const AVCodecParser ff_cavsvideo_parser = {
> .priv_data_size = sizeof(ParseContext),
> .parser_parse = cavsvideo_parse,
> .parser_close = ff_parse_close,
> - .split = ff_mpeg4video_split,
> };
> diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
> index 880ccb50fa..d3c56cc188 100644
> --- a/libavcodec/h264_parser.c
> +++ b/libavcodec/h264_parser.c
> @@ -644,43 +644,6 @@ static int h264_parse(AVCodecParserContext *s,
> return next;
> }
>
> -static int h264_split(AVCodecContext *avctx,
> - const uint8_t *buf, int buf_size)
> -{
> - uint32_t state = -1;
> - int has_sps = 0;
> - int has_pps = 0;
> - const uint8_t *ptr = buf, *end = buf + buf_size;
> - int nalu_type;
> -
> - while (ptr < end) {
> - ptr = avpriv_find_start_code(ptr, end, &state);
> - if ((state & 0xFFFFFF00) != 0x100)
> - break;
> - nalu_type = state & 0x1F;
> - if (nalu_type == H264_NAL_SPS) {
> - has_sps = 1;
> - } else if (nalu_type == H264_NAL_PPS)
> - has_pps = 1;
> - /* else if (nalu_type == 0x01 ||
> - * nalu_type == 0x02 ||
> - * nalu_type == 0x05) {
> - * }
> - */
> - else if ((nalu_type != H264_NAL_SEI || has_pps) &&
> - nalu_type != H264_NAL_AUD && nalu_type !=
> H264_NAL_SPS_EXT &&
> - nalu_type != 0x0f) {
> - if (has_sps) {
> - while (ptr - 4 > buf && ptr[-5] == 0)
> - ptr--;
> - return ptr - 4 - buf;
> - }
> - }
> - }
> -
> - return 0;
> -}
> -
> static void h264_close(AVCodecParserContext *s)
> {
> H264ParseContext *p = s->priv_data;
> @@ -708,5 +671,4 @@ const AVCodecParser ff_h264_parser = {
> .parser_init = init,
> .parser_parse = h264_parse,
> .parser_close = h264_close,
> - .split = h264_split,
> };
> diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
> index 320d4eb562..c944a6aacd 100644
> --- a/libavcodec/hevc_parser.c
> +++ b/libavcodec/hevc_parser.c
> @@ -336,39 +336,6 @@ static int hevc_parse(AVCodecParserContext *s,
> AVCodecContext *avctx,
> return next;
> }
>
> -// Split after the parameter sets at the beginning of the stream if
> they exist.
> -static int hevc_split(AVCodecContext *avctx, const uint8_t *buf, int
> buf_size)
> -{
> - const uint8_t *ptr = buf, *end = buf + buf_size;
> - uint32_t state = -1;
> - int has_vps = 0;
> - int has_sps = 0;
> - int has_pps = 0;
> - int nut;
> -
> - while (ptr < end) {
> - ptr = avpriv_find_start_code(ptr, end, &state);
> - if ((state >> 8) != START_CODE)
> - break;
> - nut = (state >> 1) & 0x3F;
> - if (nut == HEVC_NAL_VPS)
> - has_vps = 1;
> - else if (nut == HEVC_NAL_SPS)
> - has_sps = 1;
> - else if (nut == HEVC_NAL_PPS)
> - has_pps = 1;
> - else if ((nut != HEVC_NAL_SEI_PREFIX || has_pps) &&
> - nut != HEVC_NAL_AUD) {
> - if (has_vps && has_sps) {
> - while (ptr - 4 > buf && ptr[-5] == 0)
> - ptr--;
> - return ptr - 4 - buf;
> - }
> - }
> - }
> - return 0;
> -}
> -
> static void hevc_parser_close(AVCodecParserContext *s)
> {
> HEVCParserContext *ctx = s->priv_data;
> @@ -385,5 +352,4 @@ const AVCodecParser ff_hevc_parser = {
> .priv_data_size = sizeof(HEVCParserContext),
> .parser_parse = hevc_parse,
> .parser_close = hevc_parser_close,
> - .split = hevc_split,
> };
> diff --git a/libavcodec/mpeg4video_parser.c
> b/libavcodec/mpeg4video_parser.c
> index afa10c7727..1b0e2555da 100644
> --- a/libavcodec/mpeg4video_parser.c
> +++ b/libavcodec/mpeg4video_parser.c
> @@ -159,5 +159,4 @@ const AVCodecParser ff_mpeg4video_parser = {
> .parser_init = mpeg4video_parse_init,
> .parser_parse = mpeg4video_parse,
> .parser_close = ff_parse_close,
> - .split = ff_mpeg4video_split,
> };
> diff --git a/libavcodec/mpegvideo_parser.c
> b/libavcodec/mpegvideo_parser.c
> index 4e4f569b13..7864224643 100644
> --- a/libavcodec/mpegvideo_parser.c
> +++ b/libavcodec/mpegvideo_parser.c
> @@ -213,23 +213,6 @@ static int mpegvideo_parse(AVCodecParserContext
> *s,
> return next;
> }
>
> -static int mpegvideo_split(AVCodecContext *avctx,
> - const uint8_t *buf, int buf_size)
> -{
> - int i;
> - uint32_t state= -1;
> - int found=0;
> -
> - for(i=0; i<buf_size; i++){
> - state= (state<<8) | buf[i];
> - if(state == 0x1B3){
> - found=1;
> - }else if(found && state != 0x1B5 && state < 0x200 && state
> >= 0x100)
> - return i-3;
> - }
> - return 0;
> -}
> -
> static int mpegvideo_parse_init(AVCodecParserContext *s)
> {
> s->pict_type = AV_PICTURE_TYPE_NONE; // first frame might be
> partial
> @@ -242,5 +225,4 @@ const AVCodecParser ff_mpegvideo_parser = {
> .parser_init = mpegvideo_parse_init,
> .parser_parse = mpegvideo_parse,
> .parser_close = ff_parse_close,
> - .split = mpegvideo_split,
> };
> diff --git a/libavcodec/parser.c b/libavcodec/parser.c
> index f81a62d592..fc57246965 100644
> --- a/libavcodec/parser.c
> +++ b/libavcodec/parser.c
> @@ -285,17 +285,3 @@ void ff_parse_close(AVCodecParserContext *s)
>
> av_freep(&pc->buffer);
> }
> -
> -int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf,
> int buf_size)
> -{
> - uint32_t state = -1;
> - const uint8_t *ptr = buf, *end = buf + buf_size;
> -
> - while (ptr < end) {
> - ptr = avpriv_find_start_code(ptr, end, &state);
> - if (state == 0x1B3 || state == 0x1B6)
> - return ptr - 4 - buf;
> - }
> -
> - return 0;
> -}
> diff --git a/libavcodec/remove_extradata_bsf.c
> b/libavcodec/remove_extradata_bsf.c
> index 5783b075f0..1d5f193f89 100644
> --- a/libavcodec/remove_extradata_bsf.c
> +++ b/libavcodec/remove_extradata_bsf.c
> @@ -21,9 +21,13 @@
> #include "libavutil/log.h"
> #include "libavutil/opt.h"
>
> -#include "avcodec.h"
> +#include "av1_parse.h"
> #include "bsf.h"
> #include "bsf_internal.h"
> +#include "h264.h"
> +#include "hevc.h"
> +#include "internal.h"
> +#include "vc1_common.h"
>
> enum RemoveFreq {
> REMOVE_FREQ_KEYFRAME,
> @@ -31,63 +35,196 @@ enum RemoveFreq {
> REMOVE_FREQ_NONKEYFRAME,
> };
>
> +#define START_CODE 0x000001
> +
> typedef struct RemoveExtradataContext {
> const AVClass *class;
> int freq;
> -
> - AVCodecParserContext *parser;
> - AVCodecContext *avctx;
> } RemoveExtradataContext;
>
> -static int remove_extradata(AVBSFContext *ctx, AVPacket *pkt)
> +static int av1_split(const uint8_t *buf, int buf_size, void *logctx)
> {
> - RemoveExtradataContext *s = ctx->priv_data;
> + AV1OBU obu;
> + const uint8_t *ptr = buf, *end = buf + buf_size;
>
> - int ret;
> + while (ptr < end) {
> + int len = ff_av1_extract_obu(&obu, ptr, buf_size, logctx);
> + if (len < 0)
> + break;
>
> - ret = ff_bsf_get_packet_ref(ctx, pkt);
> - if (ret < 0)
> - return ret;
> + if (obu.type == AV1_OBU_FRAME_HEADER ||
> + obu.type == AV1_OBU_FRAME) {
> + return ptr - buf;
> + }
> + ptr += len;
> + buf_size -= len;
> + }
> +
> + return 0;
> +}
>
> - if (s->parser && s->parser->parser->split) {
> - if (s->freq == REMOVE_FREQ_ALL ||
> - (s->freq == REMOVE_FREQ_NONKEYFRAME && !(pkt->flags &
> AV_PKT_FLAG_KEY)) ||
> - (s->freq == REMOVE_FREQ_KEYFRAME && pkt->flags &
> AV_PKT_FLAG_KEY)) {
> - int i = s->parser->parser->split(s->avctx, pkt->data,
> pkt->size);
> - pkt->data += i;
> - pkt->size -= i;
> +static int h264_split(const uint8_t *buf, int buf_size)
> +{
> + const uint8_t *ptr = buf, *end = buf + buf_size;
> + uint32_t state = -1;
> + int has_sps = 0;
> + int has_pps = 0;
> + int nalu_type;
> +
> + while (ptr < end) {
> + ptr = avpriv_find_start_code(ptr, end, &state);
> + if ((state & 0xFFFFFF00) != 0x100)
> + break;
> + nalu_type = state & 0x1F;
> + if (nalu_type == H264_NAL_SPS) {
> + has_sps = 1;
> + } else if (nalu_type == H264_NAL_PPS)
> + has_pps = 1;
> + /* else if (nalu_type == 0x01 ||
> + * nalu_type == 0x02 ||
> + * nalu_type == 0x05) {
> + * }
> + */
> + else if ((nalu_type != H264_NAL_SEI || has_pps) &&
> + nalu_type != H264_NAL_AUD && nalu_type !=
> H264_NAL_SPS_EXT &&
> + nalu_type != 0x0f) {
> + if (has_sps) {
> + while (ptr - 4 > buf && ptr[-5] == 0)
> + ptr--;
> + return ptr - 4 - buf;
> + }
> }
> }
>
> return 0;
> }
>
> -static int remove_extradata_init(AVBSFContext *ctx)
> +// Split after the parameter sets at the beginning of the stream if
> they exist.
> +static int hevc_split(const uint8_t *buf, int buf_size)
> {
> - RemoveExtradataContext *s = ctx->priv_data;
> - int ret;
> + const uint8_t *ptr = buf, *end = buf + buf_size;
> + uint32_t state = -1;
> + int has_vps = 0;
> + int has_sps = 0;
> + int has_pps = 0;
> + int nut;
> +
> + while (ptr < end) {
> + ptr = avpriv_find_start_code(ptr, end, &state);
> + if ((state >> 8) != START_CODE)
> + break;
> + nut = (state >> 1) & 0x3F;
> + if (nut == HEVC_NAL_VPS)
> + has_vps = 1;
> + else if (nut == HEVC_NAL_SPS)
> + has_sps = 1;
> + else if (nut == HEVC_NAL_PPS)
> + has_pps = 1;
> + else if ((nut != HEVC_NAL_SEI_PREFIX || has_pps) &&
> + nut != HEVC_NAL_AUD) {
> + if (has_vps && has_sps) {
> + while (ptr - 4 > buf && ptr[-5] == 0)
> + ptr--;
> + return ptr - 4 - buf;
> + }
> + }
> + }
> + return 0;
> +}
>
> - s->parser = av_parser_init(ctx->par_in->codec_id);
> +static int mpegvideo_split(const uint8_t *buf, int buf_size)
> +{
> + uint32_t state = -1;
> + int found = 0;
> +
> + for (int i = 0; i < buf_size; i++) {
> + state = (state << 8) | buf[i];
> + if (state == 0x1B3) {
> + found = 1;
> + } else if (found && state != 0x1B5 && state < 0x200 && state
> >= 0x100)
> + return i - 3;
> + }
> + return 0;
> +}
>
> - if (s->parser) {
> - s->avctx = avcodec_alloc_context3(NULL);
> - if (!s->avctx)
> - return AVERROR(ENOMEM);
> +static int mpeg4video_split(const uint8_t *buf, int buf_size)
> +{
> + const uint8_t *ptr = buf, *end = buf + buf_size;
> + uint32_t state = -1;
>
> - ret = avcodec_parameters_to_context(s->avctx, ctx->par_in);
> - if (ret < 0)
> - return ret;
> + while (ptr < end) {
> + ptr = avpriv_find_start_code(ptr, end, &state);
> + if (state == 0x1B3 || state == 0x1B6)
> + return ptr - 4 - buf;
> }
>
> return 0;
> }
>
> -static void remove_extradata_close(AVBSFContext *ctx)
> +static int vc1_split(const uint8_t *buf, int buf_size)
> +{
> + const uint8_t *ptr = buf, *end = buf + buf_size;
> + uint32_t state = -1;
> + int charged = 0;
> +
> + while (ptr < end) {
> + ptr = avpriv_find_start_code(ptr, end, &state);
> + if (state == VC1_CODE_SEQHDR || state ==
> VC1_CODE_ENTRYPOINT) {
> + charged = 1;
> + } else if (charged && IS_MARKER(state))
> + return ptr - 4 - buf;
> + }
> +
> + return 0;
> +}
> +
> +static int remove_extradata(AVBSFContext *ctx, AVPacket *pkt)
> {
> RemoveExtradataContext *s = ctx->priv_data;
>
> - avcodec_free_context(&s->avctx);
> - av_parser_close(s->parser);
> + int ret;
> +
> + ret = ff_bsf_get_packet_ref(ctx, pkt);
> + if (ret < 0)
> + return ret;
> +
> + if (s->freq == REMOVE_FREQ_ALL ||
> + (s->freq == REMOVE_FREQ_NONKEYFRAME && !(pkt->flags &
> AV_PKT_FLAG_KEY)) ||
> + (s->freq == REMOVE_FREQ_KEYFRAME && pkt->flags &
> AV_PKT_FLAG_KEY)) {
> + int i;
> +
> + switch (ctx->par_in->codec_id) {
> + case AV_CODEC_ID_AV1:
> + i = av1_split(pkt->data, pkt->size, ctx);
> + break;
> + case AV_CODEC_ID_AVS2:
> + case AV_CODEC_ID_AVS3:
> + case AV_CODEC_ID_CAVS:
> + case AV_CODEC_ID_MPEG4:
> + i = mpeg4video_split(pkt->data, pkt->size);
> + break;
> + case AV_CODEC_ID_H264:
> + i = h264_split(pkt->data, pkt->size);
> + break;
> + case AV_CODEC_ID_HEVC:
> + i = hevc_split(pkt->data, pkt->size);
> + break;
> + case AV_CODEC_ID_MPEG1VIDEO:
> + case AV_CODEC_ID_MPEG2VIDEO:
> + i = mpegvideo_split(pkt->data, pkt->size);
> + break;
> + case AV_CODEC_ID_VC1:
> + i = vc1_split(pkt->data, pkt->size);
> + break;
> + default:
> + i = 0;
> + }
> +
> + pkt->data += i;
> + pkt->size -= i;
> + }
> +
> + return 0;
> }
>
> #define OFFSET(x) offsetof(RemoveExtradataContext, x)
> @@ -112,7 +249,5 @@ const AVBitStreamFilter ff_remove_extradata_bsf =
> {
> .name = "remove_extra",
> .priv_data_size = sizeof(RemoveExtradataContext),
> .priv_class = &remove_extradata_class,
> - .init = remove_extradata_init,
> - .close = remove_extradata_close,
> .filter = remove_extradata,
> };
> diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
> index 0f17d299e1..00896ddb09 100644
> --- a/libavcodec/vc1_parser.c
> +++ b/libavcodec/vc1_parser.c
> @@ -256,24 +256,6 @@ static int vc1_parse(AVCodecParserContext *s,
> return next;
> }
>
> -static int vc1_split(AVCodecContext *avctx,
> - const uint8_t *buf, int buf_size)
> -{
> - uint32_t state = -1;
> - int charged = 0;
> - const uint8_t *ptr = buf, *end = buf + buf_size;
> -
> - while (ptr < end) {
> - ptr = avpriv_find_start_code(ptr, end, &state);
> - if (state == VC1_CODE_SEQHDR || state ==
> VC1_CODE_ENTRYPOINT) {
> - charged = 1;
> - } else if (charged && IS_MARKER(state))
> - return ptr - 4 - buf;
> - }
> -
> - return 0;
> -}
> -
> static av_cold int vc1_parse_init(AVCodecParserContext *s)
> {
> VC1ParseContext *vpc = s->priv_data;
> @@ -293,5 +275,4 @@ const AVCodecParser ff_vc1_parser = {
> .parser_init = vc1_parse_init,
> .parser_parse = vc1_parse,
> .parser_close = ff_parse_close,
> - .split = vc1_split,
> };
More information about the ffmpeg-devel
mailing list