1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * raw ADTS AAC demuxer 3cabdff1aSopenharmony_ci * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at> 4cabdff1aSopenharmony_ci * Copyright (c) 2009 Robert Swain ( rob opendot cl ) 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 24cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 25cabdff1aSopenharmony_ci#include "avformat.h" 26cabdff1aSopenharmony_ci#include "avio_internal.h" 27cabdff1aSopenharmony_ci#include "internal.h" 28cabdff1aSopenharmony_ci#include "id3v1.h" 29cabdff1aSopenharmony_ci#include "id3v2.h" 30cabdff1aSopenharmony_ci#include "apetag.h" 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ci#define ADTS_HEADER_SIZE 7 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_cistatic int adts_aac_probe(const AVProbeData *p) 35cabdff1aSopenharmony_ci{ 36cabdff1aSopenharmony_ci int max_frames = 0, first_frames = 0; 37cabdff1aSopenharmony_ci int fsize, frames; 38cabdff1aSopenharmony_ci const uint8_t *buf0 = p->buf; 39cabdff1aSopenharmony_ci const uint8_t *buf2; 40cabdff1aSopenharmony_ci const uint8_t *buf; 41cabdff1aSopenharmony_ci const uint8_t *end = buf0 + p->buf_size - 7; 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci buf = buf0; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci for (; buf < end; buf = buf2 + 1) { 46cabdff1aSopenharmony_ci buf2 = buf; 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ci for (frames = 0; buf2 < end; frames++) { 49cabdff1aSopenharmony_ci uint32_t header = AV_RB16(buf2); 50cabdff1aSopenharmony_ci if ((header & 0xFFF6) != 0xFFF0) { 51cabdff1aSopenharmony_ci if (buf != buf0) { 52cabdff1aSopenharmony_ci // Found something that isn't an ADTS header, starting 53cabdff1aSopenharmony_ci // from a position other than the start of the buffer. 54cabdff1aSopenharmony_ci // Discard the count we've accumulated so far since it 55cabdff1aSopenharmony_ci // probably was a false positive. 56cabdff1aSopenharmony_ci frames = 0; 57cabdff1aSopenharmony_ci } 58cabdff1aSopenharmony_ci break; 59cabdff1aSopenharmony_ci } 60cabdff1aSopenharmony_ci fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF; 61cabdff1aSopenharmony_ci if (fsize < 7) 62cabdff1aSopenharmony_ci break; 63cabdff1aSopenharmony_ci fsize = FFMIN(fsize, end - buf2); 64cabdff1aSopenharmony_ci buf2 += fsize; 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci max_frames = FFMAX(max_frames, frames); 67cabdff1aSopenharmony_ci if (buf == buf0) 68cabdff1aSopenharmony_ci first_frames = frames; 69cabdff1aSopenharmony_ci } 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_ci if (first_frames >= 3) 72cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 73cabdff1aSopenharmony_ci else if (max_frames > 100) 74cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION; 75cabdff1aSopenharmony_ci else if (max_frames >= 3) 76cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION / 2; 77cabdff1aSopenharmony_ci else if (first_frames >= 1) 78cabdff1aSopenharmony_ci return 1; 79cabdff1aSopenharmony_ci else 80cabdff1aSopenharmony_ci return 0; 81cabdff1aSopenharmony_ci} 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_cistatic int adts_aac_resync(AVFormatContext *s) 84cabdff1aSopenharmony_ci{ 85cabdff1aSopenharmony_ci uint16_t state; 86cabdff1aSopenharmony_ci int64_t start_pos = avio_tell(s->pb); 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci // skip data until an ADTS frame is found 89cabdff1aSopenharmony_ci state = avio_r8(s->pb); 90cabdff1aSopenharmony_ci while (!avio_feof(s->pb) && 91cabdff1aSopenharmony_ci (avio_tell(s->pb) - start_pos) < s->probesize) { 92cabdff1aSopenharmony_ci state = (state << 8) | avio_r8(s->pb); 93cabdff1aSopenharmony_ci if ((state >> 4) != 0xFFF) 94cabdff1aSopenharmony_ci continue; 95cabdff1aSopenharmony_ci avio_seek(s->pb, -2, SEEK_CUR); 96cabdff1aSopenharmony_ci break; 97cabdff1aSopenharmony_ci } 98cabdff1aSopenharmony_ci if (s->pb->eof_reached) 99cabdff1aSopenharmony_ci return AVERROR_EOF; 100cabdff1aSopenharmony_ci if ((state >> 4) != 0xFFF) 101cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci return 0; 104cabdff1aSopenharmony_ci} 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci#ifdef OHOS_OPT_COMPAT 107cabdff1aSopenharmony_ci/** 108cabdff1aSopenharmony_ci * ohos.opt.compat.0001 109cabdff1aSopenharmony_ci * fix duration not accurate in aac. 110cabdff1aSopenharmony_ci * There is one packet for every 1024 samples, 111cabdff1aSopenharmony_ci * get the sample num in each frame and sample rate from adts 112cabdff1aSopenharmony_ci * to calculate duration of each frame, then the summation of 113cabdff1aSopenharmony_ci * frame duration is the file duration. 114cabdff1aSopenharmony_ci */ 115cabdff1aSopenharmony_cistatic int adts_aac_get_frame_length(AVFormatContext *s, int64_t offset) 116cabdff1aSopenharmony_ci{ 117cabdff1aSopenharmony_ci const int adts_header_length_no_crc = 7; 118cabdff1aSopenharmony_ci const int adts_header_length_with_crc = 9; 119cabdff1aSopenharmony_ci uint8_t syncword[2]; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci avio_seek(s->pb, offset, SEEK_SET); 122cabdff1aSopenharmony_ci // read syncword 123cabdff1aSopenharmony_ci if (avio_read(s->pb, &syncword, 2) != 2) { 124cabdff1aSopenharmony_ci return 0; 125cabdff1aSopenharmony_ci } 126cabdff1aSopenharmony_ci if ((syncword[0] != 0xff) || ((syncword[1] & 0xf6) != 0xf0)) { 127cabdff1aSopenharmony_ci return 0; 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci // read protection_absent 131cabdff1aSopenharmony_ci uint8_t protection_absent; 132cabdff1aSopenharmony_ci avio_seek(s->pb, offset + 1, SEEK_SET); 133cabdff1aSopenharmony_ci if (avio_read(s->pb, &protection_absent, 1) < 1) { 134cabdff1aSopenharmony_ci return 0; 135cabdff1aSopenharmony_ci } 136cabdff1aSopenharmony_ci protection_absent &= 0x1; 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci // get frame_size 139cabdff1aSopenharmony_ci uint8_t header[3]; 140cabdff1aSopenharmony_ci avio_seek(s->pb, offset + 3, SEEK_SET); 141cabdff1aSopenharmony_ci if (avio_read(s->pb, &header, 3) < 3) { 142cabdff1aSopenharmony_ci return 0; 143cabdff1aSopenharmony_ci } 144cabdff1aSopenharmony_ci int frame_size = (header[0] & 0x3) << 11 | header[1] << 3 | header[2] >> 5; 145cabdff1aSopenharmony_ci // protection_absent is 0 if there is CRC 146cabdff1aSopenharmony_ci int head_size = protection_absent ? adts_header_length_no_crc : adts_header_length_with_crc; 147cabdff1aSopenharmony_ci if (head_size > frame_size) { 148cabdff1aSopenharmony_ci return 0; 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci // get adts_buffer_fullness 152cabdff1aSopenharmony_ci uint8_t head[2]; 153cabdff1aSopenharmony_ci avio_seek(s->pb, offset + 5, SEEK_SET); 154cabdff1aSopenharmony_ci if (avio_read(s->pb, &head, 2) < 2) { 155cabdff1aSopenharmony_ci return 0; 156cabdff1aSopenharmony_ci } 157cabdff1aSopenharmony_ci uint16_t adts_buffer_fullness = (head[0] & 0x1F) << 6 | (head[1] >> 2); 158cabdff1aSopenharmony_ci if (adts_buffer_fullness != 0x7FF) { // not VBR 159cabdff1aSopenharmony_ci return 0; 160cabdff1aSopenharmony_ci } 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci return frame_size; 163cabdff1aSopenharmony_ci} 164cabdff1aSopenharmony_ci 165cabdff1aSopenharmony_cistatic int adts_aac_get_raw_data_block_num(AVFormatContext *s, int64_t offset) 166cabdff1aSopenharmony_ci{ 167cabdff1aSopenharmony_ci uint8_t raw_data_block_num = 0; 168cabdff1aSopenharmony_ci avio_seek(s->pb, offset + 6, SEEK_SET); 169cabdff1aSopenharmony_ci if (avio_read(s->pb, &raw_data_block_num, 1) < 1) { 170cabdff1aSopenharmony_ci return 0; 171cabdff1aSopenharmony_ci } 172cabdff1aSopenharmony_ci raw_data_block_num &= 0x3; 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci return raw_data_block_num; 175cabdff1aSopenharmony_ci} 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_ci// get sample rate by index 178cabdff1aSopenharmony_cistatic uint32_t get_sample_rate(const uint8_t sr_index) 179cabdff1aSopenharmony_ci{ 180cabdff1aSopenharmony_ci static const uint32_t sample_rates[] = 181cabdff1aSopenharmony_ci { 182cabdff1aSopenharmony_ci 96000, 88200, 64000, 48000, 44100, 32000, 183cabdff1aSopenharmony_ci 24000, 22050, 16000, 12000, 11025, 8000 184cabdff1aSopenharmony_ci }; 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ci if (sr_index < sizeof(sample_rates) / sizeof(sample_rates[0])) { 187cabdff1aSopenharmony_ci return sample_rates[sr_index]; 188cabdff1aSopenharmony_ci } 189cabdff1aSopenharmony_ci 190cabdff1aSopenharmony_ci return 0; 191cabdff1aSopenharmony_ci} 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_cistatic void adts_aac_get_duration(AVFormatContext *s, AVStream *st) 194cabdff1aSopenharmony_ci{ 195cabdff1aSopenharmony_ci avio_seek(s->pb, 0, SEEK_SET); 196cabdff1aSopenharmony_ci uint8_t header[2]; 197cabdff1aSopenharmony_ci avio_seek(s->pb, 2, SEEK_SET); 198cabdff1aSopenharmony_ci if (avio_read(s->pb, &header, 2) < 2) { 199cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "avio_read header error!\n"); 200cabdff1aSopenharmony_ci return; 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci int64_t offset = 0; 203cabdff1aSopenharmony_ci // get profile 204cabdff1aSopenharmony_ci uint8_t profile = (header[0] >> 6) & 0x3; 205cabdff1aSopenharmony_ci st->codecpar->profile = profile; 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci // get sample rate 208cabdff1aSopenharmony_ci uint8_t sr_index = (header[0] >> 2) & 0xf; 209cabdff1aSopenharmony_ci uint32_t sr = get_sample_rate(sr_index); 210cabdff1aSopenharmony_ci if (sr == 0) { 211cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "adts_aac_read_header read sampletare error!\n"); 212cabdff1aSopenharmony_ci return; 213cabdff1aSopenharmony_ci } 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci // get channel 216cabdff1aSopenharmony_ci uint8_t channel = (header[0] & 0x1) << 2 | (header[1] >> 6); 217cabdff1aSopenharmony_ci if(channel == 0) { 218cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "adts_aac_read_header read channel error!\n"); 219cabdff1aSopenharmony_ci return; 220cabdff1aSopenharmony_ci } 221cabdff1aSopenharmony_ci 222cabdff1aSopenharmony_ci st->codecpar->channels = channel; 223cabdff1aSopenharmony_ci st->codecpar->sample_rate = sr; 224cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci int frame_size = 0; 227cabdff1aSopenharmony_ci int raw_data_block_num = 0; 228cabdff1aSopenharmony_ci int64_t frame_duration_us = 0; 229cabdff1aSopenharmony_ci int64_t duration = 0; 230cabdff1aSopenharmony_ci int64_t frame_num = 0; 231cabdff1aSopenharmony_ci int64_t stream_size = avio_size(s->pb); 232cabdff1aSopenharmony_ci if (stream_size > 0) { 233cabdff1aSopenharmony_ci while (offset < stream_size) { 234cabdff1aSopenharmony_ci if ((frame_size = adts_aac_get_frame_length(s, offset)) == 0) { 235cabdff1aSopenharmony_ci break; 236cabdff1aSopenharmony_ci } 237cabdff1aSopenharmony_ci raw_data_block_num = adts_aac_get_raw_data_block_num(s, offset); 238cabdff1aSopenharmony_ci offset += frame_size; 239cabdff1aSopenharmony_ci frame_num += (raw_data_block_num + 1); 240cabdff1aSopenharmony_ci } 241cabdff1aSopenharmony_ci // round up and get the duration 242cabdff1aSopenharmony_ci frame_duration_us = (1024 * 1000000ll + (sr - 1)) / sr; 243cabdff1aSopenharmony_ci duration = frame_num * frame_duration_us; // us 244cabdff1aSopenharmony_ci duration = av_rescale_q(duration, AV_TIME_BASE_Q, st->time_base); 245cabdff1aSopenharmony_ci if (duration != 0) { 246cabdff1aSopenharmony_ci st->duration = duration; 247cabdff1aSopenharmony_ci } 248cabdff1aSopenharmony_ci } 249cabdff1aSopenharmony_ci avio_seek(s->pb, 0, SEEK_SET); 250cabdff1aSopenharmony_ci} 251cabdff1aSopenharmony_ci#endif 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_cistatic int adts_aac_read_header(AVFormatContext *s) 254cabdff1aSopenharmony_ci{ 255cabdff1aSopenharmony_ci AVStream *st; 256cabdff1aSopenharmony_ci int ret; 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_ci st = avformat_new_stream(s, NULL); 259cabdff1aSopenharmony_ci if (!st) 260cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 261cabdff1aSopenharmony_ci 262cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; 263cabdff1aSopenharmony_ci st->codecpar->codec_id = s->iformat->raw_codec_id; 264cabdff1aSopenharmony_ci ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW; 265cabdff1aSopenharmony_ci 266cabdff1aSopenharmony_ci ff_id3v1_read(s); 267cabdff1aSopenharmony_ci if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && 268cabdff1aSopenharmony_ci !av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) { 269cabdff1aSopenharmony_ci int64_t cur = avio_tell(s->pb); 270cabdff1aSopenharmony_ci ff_ape_parse_tag(s); 271cabdff1aSopenharmony_ci avio_seek(s->pb, cur, SEEK_SET); 272cabdff1aSopenharmony_ci } 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci ret = adts_aac_resync(s); 275cabdff1aSopenharmony_ci if (ret < 0) 276cabdff1aSopenharmony_ci return ret; 277cabdff1aSopenharmony_ci 278cabdff1aSopenharmony_ci#ifdef OHOS_OPT_COMPAT 279cabdff1aSopenharmony_ci // ohos.opt.compat.0001 280cabdff1aSopenharmony_ci adts_aac_get_duration(s, st); 281cabdff1aSopenharmony_ci#else 282cabdff1aSopenharmony_ci // LCM of all possible ADTS sample rates 283cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 64, 1, 28224000); 284cabdff1aSopenharmony_ci#endif 285cabdff1aSopenharmony_ci 286cabdff1aSopenharmony_ci return 0; 287cabdff1aSopenharmony_ci} 288cabdff1aSopenharmony_ci 289cabdff1aSopenharmony_cistatic int handle_id3(AVFormatContext *s, AVPacket *pkt) 290cabdff1aSopenharmony_ci{ 291cabdff1aSopenharmony_ci AVDictionary *metadata = NULL; 292cabdff1aSopenharmony_ci FFIOContext pb; 293cabdff1aSopenharmony_ci ID3v2ExtraMeta *id3v2_extra_meta; 294cabdff1aSopenharmony_ci int ret; 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci ret = av_append_packet(s->pb, pkt, ff_id3v2_tag_len(pkt->data) - pkt->size); 297cabdff1aSopenharmony_ci if (ret < 0) { 298cabdff1aSopenharmony_ci return ret; 299cabdff1aSopenharmony_ci } 300cabdff1aSopenharmony_ci 301cabdff1aSopenharmony_ci ffio_init_context(&pb, pkt->data, pkt->size, 0, NULL, NULL, NULL, NULL); 302cabdff1aSopenharmony_ci ff_id3v2_read_dict(&pb.pub, &metadata, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); 303cabdff1aSopenharmony_ci if ((ret = ff_id3v2_parse_priv_dict(&metadata, id3v2_extra_meta)) < 0) 304cabdff1aSopenharmony_ci goto error; 305cabdff1aSopenharmony_ci 306cabdff1aSopenharmony_ci if (metadata) { 307cabdff1aSopenharmony_ci if ((ret = av_dict_copy(&s->metadata, metadata, 0)) < 0) 308cabdff1aSopenharmony_ci goto error; 309cabdff1aSopenharmony_ci s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; 310cabdff1aSopenharmony_ci } 311cabdff1aSopenharmony_ci 312cabdff1aSopenharmony_cierror: 313cabdff1aSopenharmony_ci av_packet_unref(pkt); 314cabdff1aSopenharmony_ci ff_id3v2_free_extra_meta(&id3v2_extra_meta); 315cabdff1aSopenharmony_ci av_dict_free(&metadata); 316cabdff1aSopenharmony_ci 317cabdff1aSopenharmony_ci return ret; 318cabdff1aSopenharmony_ci} 319cabdff1aSopenharmony_ci 320cabdff1aSopenharmony_cistatic int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt) 321cabdff1aSopenharmony_ci{ 322cabdff1aSopenharmony_ci int ret, fsize; 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_ciretry: 325cabdff1aSopenharmony_ci ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE); 326cabdff1aSopenharmony_ci if (ret < 0) 327cabdff1aSopenharmony_ci return ret; 328cabdff1aSopenharmony_ci 329cabdff1aSopenharmony_ci if (ret < ADTS_HEADER_SIZE) { 330cabdff1aSopenharmony_ci return AVERROR(EIO); 331cabdff1aSopenharmony_ci } 332cabdff1aSopenharmony_ci 333cabdff1aSopenharmony_ci if ((AV_RB16(pkt->data) >> 4) != 0xfff) { 334cabdff1aSopenharmony_ci // Parse all the ID3 headers between frames 335cabdff1aSopenharmony_ci int append = ID3v2_HEADER_SIZE - ADTS_HEADER_SIZE; 336cabdff1aSopenharmony_ci 337cabdff1aSopenharmony_ci av_assert2(append > 0); 338cabdff1aSopenharmony_ci ret = av_append_packet(s->pb, pkt, append); 339cabdff1aSopenharmony_ci if (ret != append) { 340cabdff1aSopenharmony_ci return AVERROR(EIO); 341cabdff1aSopenharmony_ci } 342cabdff1aSopenharmony_ci if (!ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) { 343cabdff1aSopenharmony_ci av_packet_unref(pkt); 344cabdff1aSopenharmony_ci ret = adts_aac_resync(s); 345cabdff1aSopenharmony_ci } else 346cabdff1aSopenharmony_ci ret = handle_id3(s, pkt); 347cabdff1aSopenharmony_ci if (ret < 0) 348cabdff1aSopenharmony_ci return ret; 349cabdff1aSopenharmony_ci 350cabdff1aSopenharmony_ci goto retry; 351cabdff1aSopenharmony_ci } 352cabdff1aSopenharmony_ci 353cabdff1aSopenharmony_ci fsize = (AV_RB32(pkt->data + 3) >> 13) & 0x1FFF; 354cabdff1aSopenharmony_ci if (fsize < ADTS_HEADER_SIZE) { 355cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 356cabdff1aSopenharmony_ci } 357cabdff1aSopenharmony_ci 358cabdff1aSopenharmony_ci ret = av_append_packet(s->pb, pkt, fsize - pkt->size); 359cabdff1aSopenharmony_ci 360cabdff1aSopenharmony_ci return ret; 361cabdff1aSopenharmony_ci} 362cabdff1aSopenharmony_ci 363cabdff1aSopenharmony_ciconst AVInputFormat ff_aac_demuxer = { 364cabdff1aSopenharmony_ci .name = "aac", 365cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("raw ADTS AAC (Advanced Audio Coding)"), 366cabdff1aSopenharmony_ci .read_probe = adts_aac_probe, 367cabdff1aSopenharmony_ci .read_header = adts_aac_read_header, 368cabdff1aSopenharmony_ci .read_packet = adts_aac_read_packet, 369cabdff1aSopenharmony_ci .flags = AVFMT_GENERIC_INDEX, 370cabdff1aSopenharmony_ci .extensions = "aac", 371cabdff1aSopenharmony_ci .mime_type = "audio/aac,audio/aacp,audio/x-aac", 372cabdff1aSopenharmony_ci .raw_codec_id = AV_CODEC_ID_AAC, 373cabdff1aSopenharmony_ci}; 374