1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * H.264 MP4 to Annex B byte stream format filter 3cabdff1aSopenharmony_ci * Copyright (c) 2007 Benoit Fouet <benoit.fouet@free.fr> 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include <string.h> 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 25cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 26cabdff1aSopenharmony_ci#include "libavutil/mem.h" 27cabdff1aSopenharmony_ci#ifdef OHOS_DRM 28cabdff1aSopenharmony_ci#include "libavutil/encryption_info.h" 29cabdff1aSopenharmony_ci#endif 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "bsf.h" 32cabdff1aSopenharmony_ci#include "bsf_internal.h" 33cabdff1aSopenharmony_ci#include "bytestream.h" 34cabdff1aSopenharmony_ci#include "defs.h" 35cabdff1aSopenharmony_ci#include "h264.h" 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_citypedef struct H264BSFContext { 38cabdff1aSopenharmony_ci uint8_t *sps; 39cabdff1aSopenharmony_ci uint8_t *pps; 40cabdff1aSopenharmony_ci int sps_size; 41cabdff1aSopenharmony_ci int pps_size; 42cabdff1aSopenharmony_ci uint8_t length_size; 43cabdff1aSopenharmony_ci uint8_t new_idr; 44cabdff1aSopenharmony_ci uint8_t idr_sps_seen; 45cabdff1aSopenharmony_ci uint8_t idr_pps_seen; 46cabdff1aSopenharmony_ci int extradata_parsed; 47cabdff1aSopenharmony_ci} H264BSFContext; 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_cistatic void count_or_copy(uint8_t **out, uint64_t *out_size, 50cabdff1aSopenharmony_ci const uint8_t *in, int in_size, int ps, int copy) 51cabdff1aSopenharmony_ci{ 52cabdff1aSopenharmony_ci#ifdef OHOS_OPT_COMPAT 53cabdff1aSopenharmony_ci uint8_t start_code_size = ps < 0 ? 0 : 4; 54cabdff1aSopenharmony_ci#else 55cabdff1aSopenharmony_ci uint8_t start_code_size = ps < 0 ? 0 : *out_size == 0 || ps ? 4 : 3; 56cabdff1aSopenharmony_ci#endif 57cabdff1aSopenharmony_ci if (copy) { 58cabdff1aSopenharmony_ci memcpy(*out + start_code_size, in, in_size); 59cabdff1aSopenharmony_ci if (start_code_size == 4) { 60cabdff1aSopenharmony_ci AV_WB32(*out, 1); 61cabdff1aSopenharmony_ci } else if (start_code_size) { 62cabdff1aSopenharmony_ci (*out)[0] = 63cabdff1aSopenharmony_ci (*out)[1] = 0; 64cabdff1aSopenharmony_ci (*out)[2] = 1; 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci *out += start_code_size + in_size; 67cabdff1aSopenharmony_ci } 68cabdff1aSopenharmony_ci *out_size += start_code_size + in_size; 69cabdff1aSopenharmony_ci} 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_cistatic int h264_extradata_to_annexb(AVBSFContext *ctx, const int padding) 72cabdff1aSopenharmony_ci{ 73cabdff1aSopenharmony_ci H264BSFContext *s = ctx->priv_data; 74cabdff1aSopenharmony_ci GetByteContext ogb, *gb = &ogb; 75cabdff1aSopenharmony_ci uint16_t unit_size; 76cabdff1aSopenharmony_ci uint32_t total_size = 0; 77cabdff1aSopenharmony_ci uint8_t *out = NULL, unit_nb, sps_done = 0; 78cabdff1aSopenharmony_ci static const uint8_t nalu_header[4] = { 0, 0, 0, 1 }; 79cabdff1aSopenharmony_ci int length_size, pps_offset = 0; 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci bytestream2_init(gb, ctx->par_in->extradata, ctx->par_in->extradata_size); 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci bytestream2_skipu(gb, 4); 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci /* retrieve length coded size */ 86cabdff1aSopenharmony_ci length_size = (bytestream2_get_byteu(gb) & 0x3) + 1; 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci /* retrieve sps and pps unit(s) */ 89cabdff1aSopenharmony_ci unit_nb = bytestream2_get_byteu(gb) & 0x1f; /* number of sps unit(s) */ 90cabdff1aSopenharmony_ci if (!unit_nb) { 91cabdff1aSopenharmony_ci goto pps; 92cabdff1aSopenharmony_ci } 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci while (unit_nb--) { 95cabdff1aSopenharmony_ci int err; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci /* possible overread ok due to padding */ 98cabdff1aSopenharmony_ci unit_size = bytestream2_get_be16u(gb); 99cabdff1aSopenharmony_ci total_size += unit_size + 4; 100cabdff1aSopenharmony_ci av_assert1(total_size <= INT_MAX - padding); 101cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(gb) < unit_size + !sps_done) { 102cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_ERROR, "Global extradata truncated, " 103cabdff1aSopenharmony_ci "corrupted stream or invalid MP4/AVCC bitstream\n"); 104cabdff1aSopenharmony_ci av_free(out); 105cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 106cabdff1aSopenharmony_ci } 107cabdff1aSopenharmony_ci if ((err = av_reallocp(&out, total_size + padding)) < 0) 108cabdff1aSopenharmony_ci return err; 109cabdff1aSopenharmony_ci memcpy(out + total_size - unit_size - 4, nalu_header, 4); 110cabdff1aSopenharmony_ci bytestream2_get_bufferu(gb, out + total_size - unit_size, unit_size); 111cabdff1aSopenharmony_cipps: 112cabdff1aSopenharmony_ci if (!unit_nb && !sps_done++) { 113cabdff1aSopenharmony_ci unit_nb = bytestream2_get_byteu(gb); /* number of pps unit(s) */ 114cabdff1aSopenharmony_ci pps_offset = total_size; 115cabdff1aSopenharmony_ci } 116cabdff1aSopenharmony_ci } 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci if (out) 119cabdff1aSopenharmony_ci memset(out + total_size, 0, padding); 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci if (pps_offset) { 122cabdff1aSopenharmony_ci s->sps = out; 123cabdff1aSopenharmony_ci s->sps_size = pps_offset; 124cabdff1aSopenharmony_ci } else { 125cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_WARNING, 126cabdff1aSopenharmony_ci "Warning: SPS NALU missing or invalid. " 127cabdff1aSopenharmony_ci "The resulting stream may not play.\n"); 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci if (pps_offset < total_size) { 130cabdff1aSopenharmony_ci s->pps = out + pps_offset; 131cabdff1aSopenharmony_ci s->pps_size = total_size - pps_offset; 132cabdff1aSopenharmony_ci } else { 133cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_WARNING, 134cabdff1aSopenharmony_ci "Warning: PPS NALU missing or invalid. " 135cabdff1aSopenharmony_ci "The resulting stream may not play.\n"); 136cabdff1aSopenharmony_ci } 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci av_freep(&ctx->par_out->extradata); 139cabdff1aSopenharmony_ci ctx->par_out->extradata = out; 140cabdff1aSopenharmony_ci ctx->par_out->extradata_size = total_size; 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci return length_size; 143cabdff1aSopenharmony_ci} 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_cistatic int h264_mp4toannexb_init(AVBSFContext *ctx) 146cabdff1aSopenharmony_ci{ 147cabdff1aSopenharmony_ci H264BSFContext *s = ctx->priv_data; 148cabdff1aSopenharmony_ci int extra_size = ctx->par_in->extradata_size; 149cabdff1aSopenharmony_ci int ret; 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci /* retrieve sps and pps NAL units from extradata */ 152cabdff1aSopenharmony_ci if (!extra_size || 153cabdff1aSopenharmony_ci (extra_size >= 3 && AV_RB24(ctx->par_in->extradata) == 1) || 154cabdff1aSopenharmony_ci (extra_size >= 4 && AV_RB32(ctx->par_in->extradata) == 1)) { 155cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_VERBOSE, 156cabdff1aSopenharmony_ci "The input looks like it is Annex B already\n"); 157cabdff1aSopenharmony_ci } else if (extra_size >= 7) { 158cabdff1aSopenharmony_ci ret = h264_extradata_to_annexb(ctx, AV_INPUT_BUFFER_PADDING_SIZE); 159cabdff1aSopenharmony_ci if (ret < 0) 160cabdff1aSopenharmony_ci return ret; 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci s->length_size = ret; 163cabdff1aSopenharmony_ci s->new_idr = 1; 164cabdff1aSopenharmony_ci s->idr_sps_seen = 0; 165cabdff1aSopenharmony_ci s->idr_pps_seen = 0; 166cabdff1aSopenharmony_ci s->extradata_parsed = 1; 167cabdff1aSopenharmony_ci } else { 168cabdff1aSopenharmony_ci av_log(ctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", extra_size); 169cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci 172cabdff1aSopenharmony_ci return 0; 173cabdff1aSopenharmony_ci} 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci#ifdef OHOS_DRM 176cabdff1aSopenharmony_cistatic void h264_mp4toannexb_modify_encryption_info(AVPacket *pkt, uint64_t new_data_size, uint64_t old_data_size, 177cabdff1aSopenharmony_ci int copy) 178cabdff1aSopenharmony_ci{ 179cabdff1aSopenharmony_ci AV_DrmCencInfo *side_data = NULL; 180cabdff1aSopenharmony_ci size_t side_data_size = 0; 181cabdff1aSopenharmony_ci if ((copy == 0) || (new_data_size == old_data_size)) { 182cabdff1aSopenharmony_ci return; 183cabdff1aSopenharmony_ci } 184cabdff1aSopenharmony_ci side_data = (AV_DrmCencInfo *)av_packet_get_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, &side_data_size); 185cabdff1aSopenharmony_ci if ((side_data != NULL) && (side_data_size != 0)) { 186cabdff1aSopenharmony_ci uint64_t total_size = 0; 187cabdff1aSopenharmony_ci for (uint32_t i = 0; i < side_data->sub_sample_num; i++) { 188cabdff1aSopenharmony_ci total_size += 189cabdff1aSopenharmony_ci (uint64_t)(side_data->sub_samples[i].clear_header_len + side_data->sub_samples[i].pay_load_len); 190cabdff1aSopenharmony_ci if (total_size < new_data_size) { 191cabdff1aSopenharmony_ci continue; 192cabdff1aSopenharmony_ci } 193cabdff1aSopenharmony_ci if (new_data_size > old_data_size) { 194cabdff1aSopenharmony_ci side_data->sub_samples[i].clear_header_len += (uint32_t)(new_data_size - old_data_size); 195cabdff1aSopenharmony_ci } else { 196cabdff1aSopenharmony_ci uint32_t diff_size = (uint32_t)(old_data_size - new_data_size); 197cabdff1aSopenharmony_ci if (side_data->sub_samples[i].clear_header_len < diff_size) { 198cabdff1aSopenharmony_ci return; 199cabdff1aSopenharmony_ci } 200cabdff1aSopenharmony_ci side_data->sub_samples[i].clear_header_len -= diff_size; 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci break; 203cabdff1aSopenharmony_ci } 204cabdff1aSopenharmony_ci } 205cabdff1aSopenharmony_ci return; 206cabdff1aSopenharmony_ci} 207cabdff1aSopenharmony_ci#endif 208cabdff1aSopenharmony_ci 209cabdff1aSopenharmony_cistatic int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *opkt) 210cabdff1aSopenharmony_ci{ 211cabdff1aSopenharmony_ci H264BSFContext *s = ctx->priv_data; 212cabdff1aSopenharmony_ci AVPacket *in; 213cabdff1aSopenharmony_ci uint8_t unit_type, new_idr, sps_seen, pps_seen; 214cabdff1aSopenharmony_ci const uint8_t *buf; 215cabdff1aSopenharmony_ci const uint8_t *buf_end; 216cabdff1aSopenharmony_ci uint8_t *out; 217cabdff1aSopenharmony_ci uint64_t out_size; 218cabdff1aSopenharmony_ci int ret; 219cabdff1aSopenharmony_ci#ifdef OHOS_DRM 220cabdff1aSopenharmony_ci uint64_t old_out_size; 221cabdff1aSopenharmony_ci#endif 222cabdff1aSopenharmony_ci 223cabdff1aSopenharmony_ci ret = ff_bsf_get_packet(ctx, &in); 224cabdff1aSopenharmony_ci if (ret < 0) 225cabdff1aSopenharmony_ci return ret; 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci /* nothing to filter */ 228cabdff1aSopenharmony_ci if (!s->extradata_parsed) { 229cabdff1aSopenharmony_ci av_packet_move_ref(opkt, in); 230cabdff1aSopenharmony_ci av_packet_free(&in); 231cabdff1aSopenharmony_ci return 0; 232cabdff1aSopenharmony_ci } 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci buf_end = in->data + in->size; 235cabdff1aSopenharmony_ci 236cabdff1aSopenharmony_ci#define LOG_ONCE(...) \ 237cabdff1aSopenharmony_ci if (j) \ 238cabdff1aSopenharmony_ci av_log(__VA_ARGS__) 239cabdff1aSopenharmony_ci for (int j = 0; j < 2; j++) { 240cabdff1aSopenharmony_ci buf = in->data; 241cabdff1aSopenharmony_ci new_idr = s->new_idr; 242cabdff1aSopenharmony_ci sps_seen = s->idr_sps_seen; 243cabdff1aSopenharmony_ci pps_seen = s->idr_pps_seen; 244cabdff1aSopenharmony_ci out_size = 0; 245cabdff1aSopenharmony_ci#ifdef OHOS_DRM 246cabdff1aSopenharmony_ci old_out_size = out_size; 247cabdff1aSopenharmony_ci#endif 248cabdff1aSopenharmony_ci 249cabdff1aSopenharmony_ci do { 250cabdff1aSopenharmony_ci uint32_t nal_size = 0; 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_ci /* possible overread ok due to padding */ 253cabdff1aSopenharmony_ci for (int i = 0; i < s->length_size; i++) 254cabdff1aSopenharmony_ci nal_size = (nal_size << 8) | buf[i]; 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_ci buf += s->length_size; 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_ci /* This check requires the cast as the right side might 259cabdff1aSopenharmony_ci * otherwise be promoted to an unsigned value. */ 260cabdff1aSopenharmony_ci if ((int64_t)nal_size > buf_end - buf) { 261cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 262cabdff1aSopenharmony_ci goto fail; 263cabdff1aSopenharmony_ci } 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_ci if (!nal_size) 266cabdff1aSopenharmony_ci continue; 267cabdff1aSopenharmony_ci 268cabdff1aSopenharmony_ci unit_type = *buf & 0x1f; 269cabdff1aSopenharmony_ci 270cabdff1aSopenharmony_ci if (unit_type == H264_NAL_SPS) { 271cabdff1aSopenharmony_ci sps_seen = new_idr = 1; 272cabdff1aSopenharmony_ci } else if (unit_type == H264_NAL_PPS) { 273cabdff1aSopenharmony_ci pps_seen = new_idr = 1; 274cabdff1aSopenharmony_ci /* if SPS has not been seen yet, prepend the AVCC one to PPS */ 275cabdff1aSopenharmony_ci if (!sps_seen) { 276cabdff1aSopenharmony_ci if (!s->sps_size) { 277cabdff1aSopenharmony_ci LOG_ONCE(ctx, AV_LOG_WARNING, "SPS not present in the stream, nor in AVCC, stream may be unreadable\n"); 278cabdff1aSopenharmony_ci } else { 279cabdff1aSopenharmony_ci count_or_copy(&out, &out_size, s->sps, s->sps_size, -1, j); 280cabdff1aSopenharmony_ci#ifdef OHOS_DRM 281cabdff1aSopenharmony_ci h264_mp4toannexb_modify_encryption_info(in, out_size, old_out_size, j); 282cabdff1aSopenharmony_ci old_out_size = out_size; 283cabdff1aSopenharmony_ci#endif 284cabdff1aSopenharmony_ci sps_seen = 1; 285cabdff1aSopenharmony_ci } 286cabdff1aSopenharmony_ci } 287cabdff1aSopenharmony_ci } 288cabdff1aSopenharmony_ci 289cabdff1aSopenharmony_ci /* If this is a new IDR picture following an IDR picture, reset the idr flag. 290cabdff1aSopenharmony_ci * Just check first_mb_in_slice to be 0 as this is the simplest solution. 291cabdff1aSopenharmony_ci * This could be checking idr_pic_id instead, but would complexify the parsing. */ 292cabdff1aSopenharmony_ci if (!new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80)) 293cabdff1aSopenharmony_ci new_idr = 1; 294cabdff1aSopenharmony_ci 295cabdff1aSopenharmony_ci /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */ 296cabdff1aSopenharmony_ci if (new_idr && unit_type == H264_NAL_IDR_SLICE && !sps_seen && !pps_seen) { 297cabdff1aSopenharmony_ci if (ctx->par_out->extradata) 298cabdff1aSopenharmony_ci count_or_copy(&out, &out_size, ctx->par_out->extradata, 299cabdff1aSopenharmony_ci ctx->par_out->extradata_size, -1, j); 300cabdff1aSopenharmony_ci#ifdef OHOS_DRM 301cabdff1aSopenharmony_ci h264_mp4toannexb_modify_encryption_info(in, out_size, old_out_size, j); 302cabdff1aSopenharmony_ci old_out_size = out_size; 303cabdff1aSopenharmony_ci#endif 304cabdff1aSopenharmony_ci new_idr = 0; 305cabdff1aSopenharmony_ci /* if only SPS has been seen, also insert PPS */ 306cabdff1aSopenharmony_ci } else if (new_idr && unit_type == H264_NAL_IDR_SLICE && sps_seen && !pps_seen) { 307cabdff1aSopenharmony_ci if (!s->pps_size) { 308cabdff1aSopenharmony_ci LOG_ONCE(ctx, AV_LOG_WARNING, "PPS not present in the stream, nor in AVCC, stream may be unreadable\n"); 309cabdff1aSopenharmony_ci } else { 310cabdff1aSopenharmony_ci count_or_copy(&out, &out_size, s->pps, s->pps_size, -1, j); 311cabdff1aSopenharmony_ci#ifdef OHOS_DRM 312cabdff1aSopenharmony_ci h264_mp4toannexb_modify_encryption_info(in, out_size, old_out_size, j); 313cabdff1aSopenharmony_ci old_out_size = out_size; 314cabdff1aSopenharmony_ci#endif 315cabdff1aSopenharmony_ci } 316cabdff1aSopenharmony_ci } 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_ci count_or_copy(&out, &out_size, buf, nal_size, 319cabdff1aSopenharmony_ci unit_type == H264_NAL_SPS || unit_type == H264_NAL_PPS, j); 320cabdff1aSopenharmony_ci#ifdef OHOS_DRM 321cabdff1aSopenharmony_ci h264_mp4toannexb_modify_encryption_info(in, out_size, 322cabdff1aSopenharmony_ci (uint64_t)(nal_size + old_out_size + s->length_size), j); 323cabdff1aSopenharmony_ci old_out_size = out_size; 324cabdff1aSopenharmony_ci#endif 325cabdff1aSopenharmony_ci if (!new_idr && unit_type == H264_NAL_SLICE) { 326cabdff1aSopenharmony_ci new_idr = 1; 327cabdff1aSopenharmony_ci sps_seen = 0; 328cabdff1aSopenharmony_ci pps_seen = 0; 329cabdff1aSopenharmony_ci } 330cabdff1aSopenharmony_ci 331cabdff1aSopenharmony_ci buf += nal_size; 332cabdff1aSopenharmony_ci } while (buf < buf_end); 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_ci if (!j) { 335cabdff1aSopenharmony_ci if (out_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { 336cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 337cabdff1aSopenharmony_ci goto fail; 338cabdff1aSopenharmony_ci } 339cabdff1aSopenharmony_ci ret = av_new_packet(opkt, out_size); 340cabdff1aSopenharmony_ci if (ret < 0) 341cabdff1aSopenharmony_ci goto fail; 342cabdff1aSopenharmony_ci out = opkt->data; 343cabdff1aSopenharmony_ci } 344cabdff1aSopenharmony_ci } 345cabdff1aSopenharmony_ci#undef LOG_ONCE 346cabdff1aSopenharmony_ci 347cabdff1aSopenharmony_ci av_assert1(out_size == opkt->size); 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ci s->new_idr = new_idr; 350cabdff1aSopenharmony_ci s->idr_sps_seen = sps_seen; 351cabdff1aSopenharmony_ci s->idr_pps_seen = pps_seen; 352cabdff1aSopenharmony_ci 353cabdff1aSopenharmony_ci ret = av_packet_copy_props(opkt, in); 354cabdff1aSopenharmony_ci if (ret < 0) 355cabdff1aSopenharmony_ci goto fail; 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_cifail: 358cabdff1aSopenharmony_ci if (ret < 0) 359cabdff1aSopenharmony_ci av_packet_unref(opkt); 360cabdff1aSopenharmony_ci av_packet_free(&in); 361cabdff1aSopenharmony_ci 362cabdff1aSopenharmony_ci return ret; 363cabdff1aSopenharmony_ci} 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_cistatic void h264_mp4toannexb_flush(AVBSFContext *ctx) 366cabdff1aSopenharmony_ci{ 367cabdff1aSopenharmony_ci H264BSFContext *s = ctx->priv_data; 368cabdff1aSopenharmony_ci 369cabdff1aSopenharmony_ci s->idr_sps_seen = 0; 370cabdff1aSopenharmony_ci s->idr_pps_seen = 0; 371cabdff1aSopenharmony_ci s->new_idr = s->extradata_parsed; 372cabdff1aSopenharmony_ci} 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_cistatic const enum AVCodecID codec_ids[] = { 375cabdff1aSopenharmony_ci AV_CODEC_ID_H264, AV_CODEC_ID_NONE, 376cabdff1aSopenharmony_ci}; 377cabdff1aSopenharmony_ci 378cabdff1aSopenharmony_ciconst FFBitStreamFilter ff_h264_mp4toannexb_bsf = { 379cabdff1aSopenharmony_ci .p.name = "h264_mp4toannexb", 380cabdff1aSopenharmony_ci .p.codec_ids = codec_ids, 381cabdff1aSopenharmony_ci .priv_data_size = sizeof(H264BSFContext), 382cabdff1aSopenharmony_ci .init = h264_mp4toannexb_init, 383cabdff1aSopenharmony_ci .filter = h264_mp4toannexb_filter, 384cabdff1aSopenharmony_ci .flush = h264_mp4toannexb_flush, 385cabdff1aSopenharmony_ci}; 386