Re: [FFmpeg-devel] [PATCH] avcodec: add an AV1 parser

2018-09-24 Thread James Almer
On 9/24/2018 8:41 PM, Mark Thompson wrote:
> On 24/09/18 01:12, James Almer wrote:
>> Simple parser to set keyframes, frame type, structure, width, height, and 
>> pixel
>> format, plus stream profile and level.
>>
>> Signed-off-by: James Almer 
>> ---
>> Missing Changelog entry and version bump.
>>
>> This depends on "[PATCH v2 2/3] lavc: Add coded bitstream read/write support
>> for AV1" which should be committed in the coming days.
>>
>> The AVCodecParser.split() implementation, added for the sake of completeness,
>> is very naive and much like the h264 and hevc ones can result in useless OBUs
>> being "extracted", but since it's no longer used by libavformat to fill 
>> global
>> headers when reading raw containers it shouldn't really matter. It's pretty
>> much used only by the remove_extradata bsf at this point.
>>
>>  configure   |   1 +
>>  libavcodec/Makefile |   1 +
>>  libavcodec/av1_parser.c | 218 
>>  libavcodec/parsers.c|   1 +
>>  4 files changed, 221 insertions(+)
>>  create mode 100644 libavcodec/av1_parser.c
>>
>> diff --git a/configure b/configure
>> index ca8b599b63..b46c86ec95 100755
>> --- a/configure
>> +++ b/configure
>> @@ -3020,6 +3020,7 @@ wmv3_crystalhd_decoder_select="crystalhd"
>>  
>>  # parsers
>>  aac_parser_select="adts_header"
>> +av1_parser_select="cbs_av1"
>>  h264_parser_select="golomb h264dsp h264parse"
>>  hevc_parser_select="hevcparse"
>>  mpegaudio_parser_select="mpegaudioheader"
>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>> index b2c6995f9a..dc28892e64 100644
>> --- a/libavcodec/Makefile
>> +++ b/libavcodec/Makefile
>> @@ -1006,6 +1006,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
>>  OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o
>>  OBJS-$(CONFIG_BMP_PARSER)  += bmp_parser.o
>>  OBJS-$(CONFIG_CAVSVIDEO_PARSER)+= cavs_parser.o
>> diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c
>> new file mode 100644
>> index 00..b2e19e2119
>> --- /dev/null
>> +++ b/libavcodec/av1_parser.c
>> @@ -0,0 +1,218 @@
>> +/*
>> + * AV1 parser
>> + *
>> + * Copyright (C) 2018 James Almer 
>> + *
>> + * This file is part of FFmpeg.
>> + *
>> + * FFmpeg is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2.1 of the License, or (at your option) any later version.
>> + *
>> + * FFmpeg is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with FFmpeg; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
>> USA
>> + */
>> +
>> +#include "av1_parse.h"
>> +#include "cbs.h"
>> +#include "cbs_av1.h"
>> +#include "parser.h"
>> +
>> +typedef struct AV1ParseContext {
>> +CodedBitstreamContext *cbc;
>> +CodedBitstreamFragment temporal_unit;
>> +int parsed_extradata;
>> +} AV1ParseContext;
>> +
>> +static int av1_parser_parse(AVCodecParserContext *ctx,
>> +AVCodecContext *avctx,
>> +const uint8_t **out_data, int *out_size,
>> +const uint8_t *data, int size)
>> +{
>> +AV1ParseContext *s = ctx->priv_data;
>> +CodedBitstreamFragment *td = >temporal_unit;
>> +CodedBitstreamAV1Context *av1 = s->cbc->priv_data;
>> +int ret;
>> +
>> +*out_data = data;
>> +*out_size = size;
>> +
>> +ctx->key_frame = -1;
>> +ctx->pict_type = AV_PICTURE_TYPE_NONE;
>> +ctx->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
>> +
>> +if (avctx->extradata_size && !s->parsed_extradata) {
>> +ret = ff_cbs_read(s->cbc, td, avctx->extradata, 
>> avctx->extradata_size);
>> +if (ret < 0) {
>> +av_log(avctx, AV_LOG_ERROR, "Failed to parse extradata.\n");
>> +return size;
>> +}
>> +
>> +s->parsed_extradata = 1;

I'll move this above the ff_cbs_read() call, btw. Otherwise if it fails,
it will keep being called on every av_parser_parse2() call and no packet
will ever be parsed.

>> +
>> +ff_cbs_fragment_uninit(s->cbc, td);
>> +}
>> +
>> +ret = ff_cbs_read(s->cbc, td, data, size);
>> +if (ret < 0) {
>> +av_log(avctx, AV_LOG_ERROR, "Failed to parse temporal unit.\n");
>> +return size;
>> +}
>> +

Re: [FFmpeg-devel] [PATCH] avcodec: add an AV1 parser

2018-09-24 Thread Mark Thompson
On 24/09/18 01:12, James Almer wrote:
> Simple parser to set keyframes, frame type, structure, width, height, and 
> pixel
> format, plus stream profile and level.
> 
> Signed-off-by: James Almer 
> ---
> Missing Changelog entry and version bump.
> 
> This depends on "[PATCH v2 2/3] lavc: Add coded bitstream read/write support
> for AV1" which should be committed in the coming days.
> 
> The AVCodecParser.split() implementation, added for the sake of completeness,
> is very naive and much like the h264 and hevc ones can result in useless OBUs
> being "extracted", but since it's no longer used by libavformat to fill global
> headers when reading raw containers it shouldn't really matter. It's pretty
> much used only by the remove_extradata bsf at this point.
> 
>  configure   |   1 +
>  libavcodec/Makefile |   1 +
>  libavcodec/av1_parser.c | 218 
>  libavcodec/parsers.c|   1 +
>  4 files changed, 221 insertions(+)
>  create mode 100644 libavcodec/av1_parser.c
> 
> diff --git a/configure b/configure
> index ca8b599b63..b46c86ec95 100755
> --- a/configure
> +++ b/configure
> @@ -3020,6 +3020,7 @@ wmv3_crystalhd_decoder_select="crystalhd"
>  
>  # parsers
>  aac_parser_select="adts_header"
> +av1_parser_select="cbs_av1"
>  h264_parser_select="golomb h264dsp h264parse"
>  hevc_parser_select="hevcparse"
>  mpegaudio_parser_select="mpegaudioheader"
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index b2c6995f9a..dc28892e64 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -1006,6 +1006,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
>  OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o
>  OBJS-$(CONFIG_BMP_PARSER)  += bmp_parser.o
>  OBJS-$(CONFIG_CAVSVIDEO_PARSER)+= cavs_parser.o
> diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c
> new file mode 100644
> index 00..b2e19e2119
> --- /dev/null
> +++ b/libavcodec/av1_parser.c
> @@ -0,0 +1,218 @@
> +/*
> + * AV1 parser
> + *
> + * Copyright (C) 2018 James Almer 
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#include "av1_parse.h"
> +#include "cbs.h"
> +#include "cbs_av1.h"
> +#include "parser.h"
> +
> +typedef struct AV1ParseContext {
> +CodedBitstreamContext *cbc;
> +CodedBitstreamFragment temporal_unit;
> +int parsed_extradata;
> +} AV1ParseContext;
> +
> +static int av1_parser_parse(AVCodecParserContext *ctx,
> +AVCodecContext *avctx,
> +const uint8_t **out_data, int *out_size,
> +const uint8_t *data, int size)
> +{
> +AV1ParseContext *s = ctx->priv_data;
> +CodedBitstreamFragment *td = >temporal_unit;
> +CodedBitstreamAV1Context *av1 = s->cbc->priv_data;
> +int ret;
> +
> +*out_data = data;
> +*out_size = size;
> +
> +ctx->key_frame = -1;
> +ctx->pict_type = AV_PICTURE_TYPE_NONE;
> +ctx->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
> +
> +if (avctx->extradata_size && !s->parsed_extradata) {
> +ret = ff_cbs_read(s->cbc, td, avctx->extradata, 
> avctx->extradata_size);
> +if (ret < 0) {
> +av_log(avctx, AV_LOG_ERROR, "Failed to parse extradata.\n");
> +return size;
> +}
> +
> +s->parsed_extradata = 1;
> +
> +ff_cbs_fragment_uninit(s->cbc, td);
> +}
> +
> +ret = ff_cbs_read(s->cbc, td, data, size);
> +if (ret < 0) {
> +av_log(avctx, AV_LOG_ERROR, "Failed to parse temporal unit.\n");
> +return size;
> +}
> +
> +if (!av1->sequence_header) {
> +av_log(avctx, AV_LOG_ERROR, "No sequence header available\n");
> +goto end;
> +}
> +
> +for (int i = 0; i < td->nb_units; i++) {
> +CodedBitstreamUnit *unit = >units[i];
> +AV1RawOBU *obu = unit->content;
> +AV1RawSequenceHeader *seq = 

Re: [FFmpeg-devel] [PATCH] avcodec: add an AV1 parser

2018-09-23 Thread James Almer
On 9/23/2018 9:12 PM, James Almer wrote:
> +subsampling = seq->color_config.subsampling_x << 1 & 
> seq->color_config.subsampling_y;

Changed the logical and into a logical or locally.

> +bitdepth= 8 + seq->color_config.high_bitdepth * 2 + 
> seq->color_config.twelve_bit * 2;
> +switch (bitdepth) {
> +case 8:
> +if (subsampling == 3)  ctx->format = 
> seq->color_config.mono_chrome ? AV_PIX_FMT_GRAY8 :
> + 
> AV_PIX_FMT_YUV420P;
> +else if (subsampling == 2) ctx->format = AV_PIX_FMT_YUV422P;
> +else   ctx->format = AV_PIX_FMT_YUV444P;
> +break;
> +case 10:
> +if (subsampling == 3)  ctx->format = 
> seq->color_config.mono_chrome ? AV_PIX_FMT_GRAY10 :
> + 
> AV_PIX_FMT_YUV420P10;
> +else if (subsampling == 2) ctx->format = AV_PIX_FMT_YUV422P10;
> +else   ctx->format = AV_PIX_FMT_YUV444P10;
> +break;
> +case 12:
> +if (subsampling == 3)  ctx->format = 
> seq->color_config.mono_chrome ? AV_PIX_FMT_GRAY12 :
> + 
> AV_PIX_FMT_YUV420P12;
> +else if (subsampling == 2) ctx->format = AV_PIX_FMT_YUV422P12;
> +else   ctx->format = AV_PIX_FMT_YUV444P12;
> +break;
> +}

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] avcodec: add an AV1 parser

2018-09-23 Thread James Almer
Simple parser to set keyframes, frame type, structure, width, height, and pixel
format, plus stream profile and level.

Signed-off-by: James Almer 
---
Missing Changelog entry and version bump.

This depends on "[PATCH v2 2/3] lavc: Add coded bitstream read/write support
for AV1" which should be committed in the coming days.

The AVCodecParser.split() implementation, added for the sake of completeness,
is very naive and much like the h264 and hevc ones can result in useless OBUs
being "extracted", but since it's no longer used by libavformat to fill global
headers when reading raw containers it shouldn't really matter. It's pretty
much used only by the remove_extradata bsf at this point.

 configure   |   1 +
 libavcodec/Makefile |   1 +
 libavcodec/av1_parser.c | 218 
 libavcodec/parsers.c|   1 +
 4 files changed, 221 insertions(+)
 create mode 100644 libavcodec/av1_parser.c

diff --git a/configure b/configure
index ca8b599b63..b46c86ec95 100755
--- a/configure
+++ b/configure
@@ -3020,6 +3020,7 @@ wmv3_crystalhd_decoder_select="crystalhd"
 
 # parsers
 aac_parser_select="adts_header"
+av1_parser_select="cbs_av1"
 h264_parser_select="golomb h264dsp h264parse"
 hevc_parser_select="hevcparse"
 mpegaudio_parser_select="mpegaudioheader"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index b2c6995f9a..dc28892e64 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1006,6 +1006,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
 OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o
 OBJS-$(CONFIG_BMP_PARSER)  += bmp_parser.o
 OBJS-$(CONFIG_CAVSVIDEO_PARSER)+= cavs_parser.o
diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c
new file mode 100644
index 00..b2e19e2119
--- /dev/null
+++ b/libavcodec/av1_parser.c
@@ -0,0 +1,218 @@
+/*
+ * AV1 parser
+ *
+ * Copyright (C) 2018 James Almer 
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "av1_parse.h"
+#include "cbs.h"
+#include "cbs_av1.h"
+#include "parser.h"
+
+typedef struct AV1ParseContext {
+CodedBitstreamContext *cbc;
+CodedBitstreamFragment temporal_unit;
+int parsed_extradata;
+} AV1ParseContext;
+
+static int av1_parser_parse(AVCodecParserContext *ctx,
+AVCodecContext *avctx,
+const uint8_t **out_data, int *out_size,
+const uint8_t *data, int size)
+{
+AV1ParseContext *s = ctx->priv_data;
+CodedBitstreamFragment *td = >temporal_unit;
+CodedBitstreamAV1Context *av1 = s->cbc->priv_data;
+int ret;
+
+*out_data = data;
+*out_size = size;
+
+ctx->key_frame = -1;
+ctx->pict_type = AV_PICTURE_TYPE_NONE;
+ctx->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
+
+if (avctx->extradata_size && !s->parsed_extradata) {
+ret = ff_cbs_read(s->cbc, td, avctx->extradata, avctx->extradata_size);
+if (ret < 0) {
+av_log(avctx, AV_LOG_ERROR, "Failed to parse extradata.\n");
+return size;
+}
+
+s->parsed_extradata = 1;
+
+ff_cbs_fragment_uninit(s->cbc, td);
+}
+
+ret = ff_cbs_read(s->cbc, td, data, size);
+if (ret < 0) {
+av_log(avctx, AV_LOG_ERROR, "Failed to parse temporal unit.\n");
+return size;
+}
+
+if (!av1->sequence_header) {
+av_log(avctx, AV_LOG_ERROR, "No sequence header available\n");
+goto end;
+}
+
+for (int i = 0; i < td->nb_units; i++) {
+CodedBitstreamUnit *unit = >units[i];
+AV1RawOBU *obu = unit->content;
+AV1RawSequenceHeader *seq = av1->sequence_header;
+AV1RawFrameHeader *frame;
+int frame_type, bitdepth, subsampling;
+
+if (unit->type == AV1_OBU_FRAME)
+frame = >obu.frame.header;
+else if (unit->type == AV1_OBU_FRAME_HEADER)
+frame = >obu.frame_header;
+else
+continue;
+
+