+static int extract_extradata_av1(AVBSFContext *ctx, AVPacket *pkt,
+ uint8_t **data, int *size)
+{
+ static const int extradata_obu_types[] = {
+ AV1_OBU_SEQUENCE_HEADER, AV1_OBU_METADATA,
+ };
+ ExtractExtradataContext *s = ctx->priv_data;
+
+ int extradata_size = 0, filtered_size = 0;
+ int nb_extradata_obu_types = FF_ARRAY_ELEMS(extradata_obu_types);
+ int i, has_seq = 0, ret = 0;
+
+ ret = ff_av1_packet_split(&s->av1_pkt, pkt->data, pkt->size, ctx);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < s->av1_pkt.nb_obus; i++) {
+ AV1OBU *obu = &s->av1_pkt.obus[i];
+ if (val_in_array(extradata_obu_types, nb_extradata_obu_types, obu->type)) {
+ extradata_size += obu->raw_size;
+ if (obu->type == AV1_OBU_SEQUENCE_HEADER)
+ has_seq = 1;
+ } else if (s->remove) {
+ filtered_size += obu->raw_size;
+ }
+ }
+
+ if (extradata_size && has_seq) {
+ AVBufferRef *filtered_buf = NULL;
+ PutByteContext pb_filtered_data, pb_extradata;
+ uint8_t *extradata;
+
+ if (s->remove) {
+ filtered_buf = av_buffer_alloc(filtered_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!filtered_buf) {
+ return AVERROR(ENOMEM);
+ }
+ memset(filtered_buf->data + filtered_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ }
+
+ extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!extradata) {
+ av_buffer_unref(&filtered_buf);
+ return AVERROR(ENOMEM);
+ }
+
+ *data = extradata;
+ *size = extradata_size;
+
+ bytestream2_init_writer(&pb_extradata, extradata, extradata_size);
+ if (s->remove)
+ bytestream2_init_writer(&pb_filtered_data, filtered_buf->data, filtered_size);
+
+ for (i = 0; i < s->av1_pkt.nb_obus; i++) {
+ AV1OBU *obu = &s->av1_pkt.obus[i];
+ if (val_in_array(extradata_obu_types, nb_extradata_obu_types,
+ obu->type)) {
+ bytestream2_put_bufferu(&pb_extradata, obu->raw_data, obu->raw_size);
+ } else if (s->remove) {
+ bytestream2_put_bufferu(&pb_filtered_data, obu->raw_data, obu->raw_size);
+ }
+ }
+
+ if (s->remove) {
+ av_buffer_unref(&pkt->buf);
+ pkt->buf = filtered_buf;
+ pkt->data = filtered_buf->data;
+ pkt->size = filtered_size;
+ }
+ }
+
+ return 0;
+}
+