1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#include <stdint.h> 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include "libavutil/log.h" 22cabdff1aSopenharmony_ci#include "libavutil/opt.h" 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include "av1.h" 25cabdff1aSopenharmony_ci#include "av1_parse.h" 26cabdff1aSopenharmony_ci#include "bsf.h" 27cabdff1aSopenharmony_ci#include "bsf_internal.h" 28cabdff1aSopenharmony_ci#include "bytestream.h" 29cabdff1aSopenharmony_ci#include "h2645_parse.h" 30cabdff1aSopenharmony_ci#include "h264.h" 31cabdff1aSopenharmony_ci#include "hevc.h" 32cabdff1aSopenharmony_ci#include "startcode.h" 33cabdff1aSopenharmony_ci#include "vc1_common.h" 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_citypedef struct ExtractExtradataContext { 36cabdff1aSopenharmony_ci const AVClass *class; 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci int (*extract)(AVBSFContext *ctx, AVPacket *pkt, 39cabdff1aSopenharmony_ci uint8_t **data, int *size); 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci /* AV1 specific fields */ 42cabdff1aSopenharmony_ci AV1Packet av1_pkt; 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci /* H264/HEVC specific fields */ 45cabdff1aSopenharmony_ci H2645Packet h2645_pkt; 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_ci /* AVOptions */ 48cabdff1aSopenharmony_ci int remove; 49cabdff1aSopenharmony_ci} ExtractExtradataContext; 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_cistatic int val_in_array(const int *arr, int len, int val) 52cabdff1aSopenharmony_ci{ 53cabdff1aSopenharmony_ci int i; 54cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 55cabdff1aSopenharmony_ci if (arr[i] == val) 56cabdff1aSopenharmony_ci return 1; 57cabdff1aSopenharmony_ci return 0; 58cabdff1aSopenharmony_ci} 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_cistatic int extract_extradata_av1(AVBSFContext *ctx, AVPacket *pkt, 61cabdff1aSopenharmony_ci uint8_t **data, int *size) 62cabdff1aSopenharmony_ci{ 63cabdff1aSopenharmony_ci static const int extradata_obu_types[] = { 64cabdff1aSopenharmony_ci AV1_OBU_SEQUENCE_HEADER, AV1_OBU_METADATA, 65cabdff1aSopenharmony_ci }; 66cabdff1aSopenharmony_ci ExtractExtradataContext *s = ctx->priv_data; 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_ci int extradata_size = 0, filtered_size = 0; 69cabdff1aSopenharmony_ci int nb_extradata_obu_types = FF_ARRAY_ELEMS(extradata_obu_types); 70cabdff1aSopenharmony_ci int i, has_seq = 0, ret = 0; 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci ret = ff_av1_packet_split(&s->av1_pkt, pkt->data, pkt->size, ctx); 73cabdff1aSopenharmony_ci if (ret < 0) 74cabdff1aSopenharmony_ci return ret; 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci for (i = 0; i < s->av1_pkt.nb_obus; i++) { 77cabdff1aSopenharmony_ci AV1OBU *obu = &s->av1_pkt.obus[i]; 78cabdff1aSopenharmony_ci if (val_in_array(extradata_obu_types, nb_extradata_obu_types, obu->type)) { 79cabdff1aSopenharmony_ci extradata_size += obu->raw_size; 80cabdff1aSopenharmony_ci if (obu->type == AV1_OBU_SEQUENCE_HEADER) 81cabdff1aSopenharmony_ci has_seq = 1; 82cabdff1aSopenharmony_ci } else if (s->remove) { 83cabdff1aSopenharmony_ci filtered_size += obu->raw_size; 84cabdff1aSopenharmony_ci } 85cabdff1aSopenharmony_ci } 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_ci if (extradata_size && has_seq) { 88cabdff1aSopenharmony_ci AVBufferRef *filtered_buf = NULL; 89cabdff1aSopenharmony_ci PutByteContext pb_filtered_data, pb_extradata; 90cabdff1aSopenharmony_ci uint8_t *extradata; 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci if (s->remove) { 93cabdff1aSopenharmony_ci filtered_buf = av_buffer_alloc(filtered_size + AV_INPUT_BUFFER_PADDING_SIZE); 94cabdff1aSopenharmony_ci if (!filtered_buf) { 95cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci memset(filtered_buf->data + filtered_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); 98cabdff1aSopenharmony_ci } 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ci extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 101cabdff1aSopenharmony_ci if (!extradata) { 102cabdff1aSopenharmony_ci av_buffer_unref(&filtered_buf); 103cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 104cabdff1aSopenharmony_ci } 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci *data = extradata; 107cabdff1aSopenharmony_ci *size = extradata_size; 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci bytestream2_init_writer(&pb_extradata, extradata, extradata_size); 110cabdff1aSopenharmony_ci if (s->remove) 111cabdff1aSopenharmony_ci bytestream2_init_writer(&pb_filtered_data, filtered_buf->data, filtered_size); 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ci for (i = 0; i < s->av1_pkt.nb_obus; i++) { 114cabdff1aSopenharmony_ci AV1OBU *obu = &s->av1_pkt.obus[i]; 115cabdff1aSopenharmony_ci if (val_in_array(extradata_obu_types, nb_extradata_obu_types, 116cabdff1aSopenharmony_ci obu->type)) { 117cabdff1aSopenharmony_ci bytestream2_put_bufferu(&pb_extradata, obu->raw_data, obu->raw_size); 118cabdff1aSopenharmony_ci } else if (s->remove) { 119cabdff1aSopenharmony_ci bytestream2_put_bufferu(&pb_filtered_data, obu->raw_data, obu->raw_size); 120cabdff1aSopenharmony_ci } 121cabdff1aSopenharmony_ci } 122cabdff1aSopenharmony_ci 123cabdff1aSopenharmony_ci if (s->remove) { 124cabdff1aSopenharmony_ci av_buffer_unref(&pkt->buf); 125cabdff1aSopenharmony_ci pkt->buf = filtered_buf; 126cabdff1aSopenharmony_ci pkt->data = filtered_buf->data; 127cabdff1aSopenharmony_ci pkt->size = filtered_size; 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci } 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_ci return 0; 132cabdff1aSopenharmony_ci} 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_cistatic int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt, 135cabdff1aSopenharmony_ci uint8_t **data, int *size) 136cabdff1aSopenharmony_ci{ 137cabdff1aSopenharmony_ci static const int extradata_nal_types_hevc[] = { 138cabdff1aSopenharmony_ci HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS, 139cabdff1aSopenharmony_ci }; 140cabdff1aSopenharmony_ci static const int extradata_nal_types_h264[] = { 141cabdff1aSopenharmony_ci H264_NAL_SPS, H264_NAL_PPS, 142cabdff1aSopenharmony_ci }; 143cabdff1aSopenharmony_ci 144cabdff1aSopenharmony_ci ExtractExtradataContext *s = ctx->priv_data; 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_ci int extradata_size = 0, filtered_size = 0; 147cabdff1aSopenharmony_ci const int *extradata_nal_types; 148cabdff1aSopenharmony_ci int nb_extradata_nal_types; 149cabdff1aSopenharmony_ci int i, has_sps = 0, has_vps = 0, ret = 0; 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) { 152cabdff1aSopenharmony_ci extradata_nal_types = extradata_nal_types_hevc; 153cabdff1aSopenharmony_ci nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_hevc); 154cabdff1aSopenharmony_ci } else { 155cabdff1aSopenharmony_ci extradata_nal_types = extradata_nal_types_h264; 156cabdff1aSopenharmony_ci nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_h264); 157cabdff1aSopenharmony_ci } 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci ret = ff_h2645_packet_split(&s->h2645_pkt, pkt->data, pkt->size, 160cabdff1aSopenharmony_ci ctx, 0, 0, ctx->par_in->codec_id, 1, 0); 161cabdff1aSopenharmony_ci if (ret < 0) 162cabdff1aSopenharmony_ci return ret; 163cabdff1aSopenharmony_ci 164cabdff1aSopenharmony_ci for (i = 0; i < s->h2645_pkt.nb_nals; i++) { 165cabdff1aSopenharmony_ci H2645NAL *nal = &s->h2645_pkt.nals[i]; 166cabdff1aSopenharmony_ci if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type)) { 167cabdff1aSopenharmony_ci extradata_size += nal->raw_size + 3; 168cabdff1aSopenharmony_ci if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) { 169cabdff1aSopenharmony_ci if (nal->type == HEVC_NAL_SPS) has_sps = 1; 170cabdff1aSopenharmony_ci if (nal->type == HEVC_NAL_VPS) has_vps = 1; 171cabdff1aSopenharmony_ci } else { 172cabdff1aSopenharmony_ci if (nal->type == H264_NAL_SPS) has_sps = 1; 173cabdff1aSopenharmony_ci } 174cabdff1aSopenharmony_ci } else if (s->remove) { 175cabdff1aSopenharmony_ci filtered_size += nal->raw_size + 3; 176cabdff1aSopenharmony_ci } 177cabdff1aSopenharmony_ci } 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_ci if (extradata_size && 180cabdff1aSopenharmony_ci ((ctx->par_in->codec_id == AV_CODEC_ID_HEVC && has_sps && has_vps) || 181cabdff1aSopenharmony_ci (ctx->par_in->codec_id == AV_CODEC_ID_H264 && has_sps))) { 182cabdff1aSopenharmony_ci AVBufferRef *filtered_buf = NULL; 183cabdff1aSopenharmony_ci PutByteContext pb_filtered_data, pb_extradata; 184cabdff1aSopenharmony_ci uint8_t *extradata; 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ci if (s->remove) { 187cabdff1aSopenharmony_ci filtered_buf = av_buffer_alloc(filtered_size + AV_INPUT_BUFFER_PADDING_SIZE); 188cabdff1aSopenharmony_ci if (!filtered_buf) { 189cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 190cabdff1aSopenharmony_ci } 191cabdff1aSopenharmony_ci memset(filtered_buf->data + filtered_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); 192cabdff1aSopenharmony_ci } 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 195cabdff1aSopenharmony_ci if (!extradata) { 196cabdff1aSopenharmony_ci av_buffer_unref(&filtered_buf); 197cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 198cabdff1aSopenharmony_ci } 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci *data = extradata; 201cabdff1aSopenharmony_ci *size = extradata_size; 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci bytestream2_init_writer(&pb_extradata, extradata, extradata_size); 204cabdff1aSopenharmony_ci if (s->remove) 205cabdff1aSopenharmony_ci bytestream2_init_writer(&pb_filtered_data, filtered_buf->data, filtered_size); 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci for (i = 0; i < s->h2645_pkt.nb_nals; i++) { 208cabdff1aSopenharmony_ci H2645NAL *nal = &s->h2645_pkt.nals[i]; 209cabdff1aSopenharmony_ci if (val_in_array(extradata_nal_types, nb_extradata_nal_types, 210cabdff1aSopenharmony_ci nal->type)) { 211cabdff1aSopenharmony_ci bytestream2_put_be24u(&pb_extradata, 1); //startcode 212cabdff1aSopenharmony_ci bytestream2_put_bufferu(&pb_extradata, nal->raw_data, nal->raw_size); 213cabdff1aSopenharmony_ci } else if (s->remove) { 214cabdff1aSopenharmony_ci bytestream2_put_be24u(&pb_filtered_data, 1); // startcode 215cabdff1aSopenharmony_ci bytestream2_put_bufferu(&pb_filtered_data, nal->raw_data, nal->raw_size); 216cabdff1aSopenharmony_ci } 217cabdff1aSopenharmony_ci } 218cabdff1aSopenharmony_ci 219cabdff1aSopenharmony_ci if (s->remove) { 220cabdff1aSopenharmony_ci av_buffer_unref(&pkt->buf); 221cabdff1aSopenharmony_ci pkt->buf = filtered_buf; 222cabdff1aSopenharmony_ci pkt->data = filtered_buf->data; 223cabdff1aSopenharmony_ci pkt->size = filtered_size; 224cabdff1aSopenharmony_ci } 225cabdff1aSopenharmony_ci } 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci return 0; 228cabdff1aSopenharmony_ci} 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_cistatic int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, 231cabdff1aSopenharmony_ci uint8_t **data, int *size) 232cabdff1aSopenharmony_ci{ 233cabdff1aSopenharmony_ci ExtractExtradataContext *s = ctx->priv_data; 234cabdff1aSopenharmony_ci const uint8_t *ptr = pkt->data, *end = pkt->data + pkt->size; 235cabdff1aSopenharmony_ci uint32_t state = UINT32_MAX; 236cabdff1aSopenharmony_ci int has_extradata = 0, extradata_size = 0; 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ci while (ptr < end) { 239cabdff1aSopenharmony_ci ptr = avpriv_find_start_code(ptr, end, &state); 240cabdff1aSopenharmony_ci if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) { 241cabdff1aSopenharmony_ci has_extradata = 1; 242cabdff1aSopenharmony_ci } else if (has_extradata && IS_MARKER(state)) { 243cabdff1aSopenharmony_ci extradata_size = ptr - 4 - pkt->data; 244cabdff1aSopenharmony_ci break; 245cabdff1aSopenharmony_ci } 246cabdff1aSopenharmony_ci } 247cabdff1aSopenharmony_ci 248cabdff1aSopenharmony_ci if (extradata_size) { 249cabdff1aSopenharmony_ci *data = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 250cabdff1aSopenharmony_ci if (!*data) 251cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_ci memcpy(*data, pkt->data, extradata_size); 254cabdff1aSopenharmony_ci *size = extradata_size; 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_ci if (s->remove) { 257cabdff1aSopenharmony_ci pkt->data += extradata_size; 258cabdff1aSopenharmony_ci pkt->size -= extradata_size; 259cabdff1aSopenharmony_ci } 260cabdff1aSopenharmony_ci } 261cabdff1aSopenharmony_ci 262cabdff1aSopenharmony_ci return 0; 263cabdff1aSopenharmony_ci} 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_cistatic int extract_extradata_mpeg12(AVBSFContext *ctx, AVPacket *pkt, 266cabdff1aSopenharmony_ci uint8_t **data, int *size) 267cabdff1aSopenharmony_ci{ 268cabdff1aSopenharmony_ci ExtractExtradataContext *s = ctx->priv_data; 269cabdff1aSopenharmony_ci uint32_t state = UINT32_MAX; 270cabdff1aSopenharmony_ci int i, found = 0; 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci for (i = 0; i < pkt->size; i++) { 273cabdff1aSopenharmony_ci state = (state << 8) | pkt->data[i]; 274cabdff1aSopenharmony_ci if (state == 0x1B3) 275cabdff1aSopenharmony_ci found = 1; 276cabdff1aSopenharmony_ci else if (found && state != 0x1B5 && state < 0x200 && state >= 0x100) { 277cabdff1aSopenharmony_ci *size = i - 3; 278cabdff1aSopenharmony_ci *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); 279cabdff1aSopenharmony_ci if (!*data) 280cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 281cabdff1aSopenharmony_ci 282cabdff1aSopenharmony_ci memcpy(*data, pkt->data, *size); 283cabdff1aSopenharmony_ci 284cabdff1aSopenharmony_ci if (s->remove) { 285cabdff1aSopenharmony_ci pkt->data += *size; 286cabdff1aSopenharmony_ci pkt->size -= *size; 287cabdff1aSopenharmony_ci } 288cabdff1aSopenharmony_ci break; 289cabdff1aSopenharmony_ci } 290cabdff1aSopenharmony_ci } 291cabdff1aSopenharmony_ci return 0; 292cabdff1aSopenharmony_ci} 293cabdff1aSopenharmony_ci 294cabdff1aSopenharmony_cistatic int extract_extradata_mpeg4(AVBSFContext *ctx, AVPacket *pkt, 295cabdff1aSopenharmony_ci uint8_t **data, int *size) 296cabdff1aSopenharmony_ci{ 297cabdff1aSopenharmony_ci ExtractExtradataContext *s = ctx->priv_data; 298cabdff1aSopenharmony_ci const uint8_t *ptr = pkt->data, *end = pkt->data + pkt->size; 299cabdff1aSopenharmony_ci uint32_t state = UINT32_MAX; 300cabdff1aSopenharmony_ci 301cabdff1aSopenharmony_ci while (ptr < end) { 302cabdff1aSopenharmony_ci ptr = avpriv_find_start_code(ptr, end, &state); 303cabdff1aSopenharmony_ci if (state == 0x1B3 || state == 0x1B6) { 304cabdff1aSopenharmony_ci if (ptr - pkt->data > 4) { 305cabdff1aSopenharmony_ci *size = ptr - 4 - pkt->data; 306cabdff1aSopenharmony_ci *data = av_malloc(*size + AV_INPUT_BUFFER_PADDING_SIZE); 307cabdff1aSopenharmony_ci if (!*data) 308cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci memcpy(*data, pkt->data, *size); 311cabdff1aSopenharmony_ci 312cabdff1aSopenharmony_ci if (s->remove) { 313cabdff1aSopenharmony_ci pkt->data += *size; 314cabdff1aSopenharmony_ci pkt->size -= *size; 315cabdff1aSopenharmony_ci } 316cabdff1aSopenharmony_ci } 317cabdff1aSopenharmony_ci break; 318cabdff1aSopenharmony_ci } 319cabdff1aSopenharmony_ci } 320cabdff1aSopenharmony_ci return 0; 321cabdff1aSopenharmony_ci} 322cabdff1aSopenharmony_ci 323cabdff1aSopenharmony_cistatic const struct { 324cabdff1aSopenharmony_ci enum AVCodecID id; 325cabdff1aSopenharmony_ci int (*extract)(AVBSFContext *ctx, AVPacket *pkt, 326cabdff1aSopenharmony_ci uint8_t **data, int *size); 327cabdff1aSopenharmony_ci} extract_tab[] = { 328cabdff1aSopenharmony_ci { AV_CODEC_ID_AV1, extract_extradata_av1 }, 329cabdff1aSopenharmony_ci { AV_CODEC_ID_AVS2, extract_extradata_mpeg4 }, 330cabdff1aSopenharmony_ci { AV_CODEC_ID_AVS3, extract_extradata_mpeg4 }, 331cabdff1aSopenharmony_ci { AV_CODEC_ID_CAVS, extract_extradata_mpeg4 }, 332cabdff1aSopenharmony_ci { AV_CODEC_ID_H264, extract_extradata_h2645 }, 333cabdff1aSopenharmony_ci { AV_CODEC_ID_HEVC, extract_extradata_h2645 }, 334cabdff1aSopenharmony_ci { AV_CODEC_ID_MPEG1VIDEO, extract_extradata_mpeg12 }, 335cabdff1aSopenharmony_ci { AV_CODEC_ID_MPEG2VIDEO, extract_extradata_mpeg12 }, 336cabdff1aSopenharmony_ci { AV_CODEC_ID_MPEG4, extract_extradata_mpeg4 }, 337cabdff1aSopenharmony_ci { AV_CODEC_ID_VC1, extract_extradata_vc1 }, 338cabdff1aSopenharmony_ci}; 339cabdff1aSopenharmony_ci 340cabdff1aSopenharmony_cistatic int extract_extradata_init(AVBSFContext *ctx) 341cabdff1aSopenharmony_ci{ 342cabdff1aSopenharmony_ci ExtractExtradataContext *s = ctx->priv_data; 343cabdff1aSopenharmony_ci int i; 344cabdff1aSopenharmony_ci 345cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(extract_tab); i++) { 346cabdff1aSopenharmony_ci if (extract_tab[i].id == ctx->par_in->codec_id) { 347cabdff1aSopenharmony_ci s->extract = extract_tab[i].extract; 348cabdff1aSopenharmony_ci break; 349cabdff1aSopenharmony_ci } 350cabdff1aSopenharmony_ci } 351cabdff1aSopenharmony_ci if (!s->extract) 352cabdff1aSopenharmony_ci return AVERROR_BUG; 353cabdff1aSopenharmony_ci 354cabdff1aSopenharmony_ci return 0; 355cabdff1aSopenharmony_ci} 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_cistatic int extract_extradata_filter(AVBSFContext *ctx, AVPacket *pkt) 358cabdff1aSopenharmony_ci{ 359cabdff1aSopenharmony_ci ExtractExtradataContext *s = ctx->priv_data; 360cabdff1aSopenharmony_ci uint8_t *extradata = NULL; 361cabdff1aSopenharmony_ci int extradata_size; 362cabdff1aSopenharmony_ci int ret = 0; 363cabdff1aSopenharmony_ci 364cabdff1aSopenharmony_ci ret = ff_bsf_get_packet_ref(ctx, pkt); 365cabdff1aSopenharmony_ci if (ret < 0) 366cabdff1aSopenharmony_ci return ret; 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ci ret = s->extract(ctx, pkt, &extradata, &extradata_size); 369cabdff1aSopenharmony_ci if (ret < 0) 370cabdff1aSopenharmony_ci goto fail; 371cabdff1aSopenharmony_ci 372cabdff1aSopenharmony_ci if (extradata) { 373cabdff1aSopenharmony_ci memset(extradata + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); 374cabdff1aSopenharmony_ci ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, 375cabdff1aSopenharmony_ci extradata, extradata_size); 376cabdff1aSopenharmony_ci if (ret < 0) { 377cabdff1aSopenharmony_ci av_freep(&extradata); 378cabdff1aSopenharmony_ci goto fail; 379cabdff1aSopenharmony_ci } 380cabdff1aSopenharmony_ci } 381cabdff1aSopenharmony_ci 382cabdff1aSopenharmony_ci return 0; 383cabdff1aSopenharmony_ci 384cabdff1aSopenharmony_cifail: 385cabdff1aSopenharmony_ci av_packet_unref(pkt); 386cabdff1aSopenharmony_ci return ret; 387cabdff1aSopenharmony_ci} 388cabdff1aSopenharmony_ci 389cabdff1aSopenharmony_cistatic void extract_extradata_close(AVBSFContext *ctx) 390cabdff1aSopenharmony_ci{ 391cabdff1aSopenharmony_ci ExtractExtradataContext *s = ctx->priv_data; 392cabdff1aSopenharmony_ci ff_av1_packet_uninit(&s->av1_pkt); 393cabdff1aSopenharmony_ci ff_h2645_packet_uninit(&s->h2645_pkt); 394cabdff1aSopenharmony_ci} 395cabdff1aSopenharmony_ci 396cabdff1aSopenharmony_cistatic const enum AVCodecID codec_ids[] = { 397cabdff1aSopenharmony_ci AV_CODEC_ID_AV1, 398cabdff1aSopenharmony_ci AV_CODEC_ID_AVS2, 399cabdff1aSopenharmony_ci AV_CODEC_ID_AVS3, 400cabdff1aSopenharmony_ci AV_CODEC_ID_CAVS, 401cabdff1aSopenharmony_ci AV_CODEC_ID_H264, 402cabdff1aSopenharmony_ci AV_CODEC_ID_HEVC, 403cabdff1aSopenharmony_ci AV_CODEC_ID_MPEG1VIDEO, 404cabdff1aSopenharmony_ci AV_CODEC_ID_MPEG2VIDEO, 405cabdff1aSopenharmony_ci AV_CODEC_ID_MPEG4, 406cabdff1aSopenharmony_ci AV_CODEC_ID_VC1, 407cabdff1aSopenharmony_ci AV_CODEC_ID_NONE, 408cabdff1aSopenharmony_ci}; 409cabdff1aSopenharmony_ci 410cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(ExtractExtradataContext, x) 411cabdff1aSopenharmony_ci#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) 412cabdff1aSopenharmony_cistatic const AVOption options[] = { 413cabdff1aSopenharmony_ci { "remove", "remove the extradata from the bitstream", OFFSET(remove), AV_OPT_TYPE_INT, 414cabdff1aSopenharmony_ci { .i64 = 0 }, 0, 1, FLAGS }, 415cabdff1aSopenharmony_ci { NULL }, 416cabdff1aSopenharmony_ci}; 417cabdff1aSopenharmony_ci 418cabdff1aSopenharmony_cistatic const AVClass extract_extradata_class = { 419cabdff1aSopenharmony_ci .class_name = "extract_extradata", 420cabdff1aSopenharmony_ci .item_name = av_default_item_name, 421cabdff1aSopenharmony_ci .option = options, 422cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 423cabdff1aSopenharmony_ci}; 424cabdff1aSopenharmony_ci 425cabdff1aSopenharmony_ciconst FFBitStreamFilter ff_extract_extradata_bsf = { 426cabdff1aSopenharmony_ci .p.name = "extract_extradata", 427cabdff1aSopenharmony_ci .p.codec_ids = codec_ids, 428cabdff1aSopenharmony_ci .p.priv_class = &extract_extradata_class, 429cabdff1aSopenharmony_ci .priv_data_size = sizeof(ExtractExtradataContext), 430cabdff1aSopenharmony_ci .init = extract_extradata_init, 431cabdff1aSopenharmony_ci .filter = extract_extradata_filter, 432cabdff1aSopenharmony_ci .close = extract_extradata_close, 433cabdff1aSopenharmony_ci}; 434