1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * AU muxer and demuxer 3cabdff1aSopenharmony_ci * Copyright (c) 2001 Fabrice Bellard 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * first version by Francois Revol <revol@free.fr> 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * This file is part of FFmpeg. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 10cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 11cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 12cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 15cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 16cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17cabdff1aSopenharmony_ci * Lesser General Public License for more details. 18cabdff1aSopenharmony_ci * 19cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 20cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 21cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22cabdff1aSopenharmony_ci */ 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci/* 25cabdff1aSopenharmony_ci * Reference documents: 26cabdff1aSopenharmony_ci * http://www.opengroup.org/public/pubs/external/auformat.html 27cabdff1aSopenharmony_ci * http://www.goice.co.jp/member/mo/formats/au.html 28cabdff1aSopenharmony_ci */ 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci#include "config_components.h" 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ci#include "libavutil/bprint.h" 33cabdff1aSopenharmony_ci#include "avformat.h" 34cabdff1aSopenharmony_ci#include "internal.h" 35cabdff1aSopenharmony_ci#include "avio_internal.h" 36cabdff1aSopenharmony_ci#include "pcm.h" 37cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_ci/* if we don't know the size in advance */ 40cabdff1aSopenharmony_ci#define AU_UNKNOWN_SIZE ((uint32_t)(~0)) 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_cistatic const AVCodecTag codec_au_tags[] = { 43cabdff1aSopenharmony_ci { AV_CODEC_ID_PCM_MULAW, 1 }, 44cabdff1aSopenharmony_ci { AV_CODEC_ID_PCM_S8, 2 }, 45cabdff1aSopenharmony_ci { AV_CODEC_ID_PCM_S16BE, 3 }, 46cabdff1aSopenharmony_ci { AV_CODEC_ID_PCM_S24BE, 4 }, 47cabdff1aSopenharmony_ci { AV_CODEC_ID_PCM_S32BE, 5 }, 48cabdff1aSopenharmony_ci { AV_CODEC_ID_PCM_F32BE, 6 }, 49cabdff1aSopenharmony_ci { AV_CODEC_ID_PCM_F64BE, 7 }, 50cabdff1aSopenharmony_ci { AV_CODEC_ID_ADPCM_G726LE, 23 }, 51cabdff1aSopenharmony_ci { AV_CODEC_ID_ADPCM_G722,24 }, 52cabdff1aSopenharmony_ci { AV_CODEC_ID_ADPCM_G726LE, 25 }, 53cabdff1aSopenharmony_ci { AV_CODEC_ID_ADPCM_G726LE, 26 }, 54cabdff1aSopenharmony_ci { AV_CODEC_ID_PCM_ALAW, 27 }, 55cabdff1aSopenharmony_ci { AV_CODEC_ID_ADPCM_G726LE, MKBETAG('7','2','6','2') }, 56cabdff1aSopenharmony_ci { AV_CODEC_ID_NONE, 0 }, 57cabdff1aSopenharmony_ci}; 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_cistatic const AVCodecTag *const au_codec_tags[] = { codec_au_tags, NULL }; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci#if CONFIG_AU_DEMUXER 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_cistatic int au_probe(const AVProbeData *p) 64cabdff1aSopenharmony_ci{ 65cabdff1aSopenharmony_ci if (p->buf[0] == '.' && p->buf[1] == 's' && 66cabdff1aSopenharmony_ci p->buf[2] == 'n' && p->buf[3] == 'd') 67cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX; 68cabdff1aSopenharmony_ci else 69cabdff1aSopenharmony_ci return 0; 70cabdff1aSopenharmony_ci} 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_cistatic int au_read_annotation(AVFormatContext *s, int size) 73cabdff1aSopenharmony_ci{ 74cabdff1aSopenharmony_ci static const char keys[][7] = { 75cabdff1aSopenharmony_ci "title", 76cabdff1aSopenharmony_ci "artist", 77cabdff1aSopenharmony_ci "album", 78cabdff1aSopenharmony_ci "track", 79cabdff1aSopenharmony_ci "genre", 80cabdff1aSopenharmony_ci }; 81cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 82cabdff1aSopenharmony_ci enum { PARSE_KEY, PARSE_VALUE, PARSE_FINISHED } state = PARSE_KEY; 83cabdff1aSopenharmony_ci char c; 84cabdff1aSopenharmony_ci AVBPrint bprint; 85cabdff1aSopenharmony_ci char * key = NULL; 86cabdff1aSopenharmony_ci char * value = NULL; 87cabdff1aSopenharmony_ci int ret, i; 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci while (size-- > 0) { 92cabdff1aSopenharmony_ci if (avio_feof(pb)) { 93cabdff1aSopenharmony_ci av_bprint_finalize(&bprint, NULL); 94cabdff1aSopenharmony_ci av_freep(&key); 95cabdff1aSopenharmony_ci return AVERROR_EOF; 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci c = avio_r8(pb); 98cabdff1aSopenharmony_ci switch(state) { 99cabdff1aSopenharmony_ci case PARSE_KEY: 100cabdff1aSopenharmony_ci if (c == '\0') { 101cabdff1aSopenharmony_ci state = PARSE_FINISHED; 102cabdff1aSopenharmony_ci } else if (c == '=') { 103cabdff1aSopenharmony_ci ret = av_bprint_finalize(&bprint, &key); 104cabdff1aSopenharmony_ci if (ret < 0) 105cabdff1aSopenharmony_ci return ret; 106cabdff1aSopenharmony_ci av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); 107cabdff1aSopenharmony_ci state = PARSE_VALUE; 108cabdff1aSopenharmony_ci } else { 109cabdff1aSopenharmony_ci av_bprint_chars(&bprint, c, 1); 110cabdff1aSopenharmony_ci } 111cabdff1aSopenharmony_ci break; 112cabdff1aSopenharmony_ci case PARSE_VALUE: 113cabdff1aSopenharmony_ci if (c == '\0' || c == '\n') { 114cabdff1aSopenharmony_ci if (av_bprint_finalize(&bprint, &value) != 0) { 115cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Memory error while parsing AU metadata.\n"); 116cabdff1aSopenharmony_ci } else { 117cabdff1aSopenharmony_ci av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); 118cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(keys); i++) { 119cabdff1aSopenharmony_ci if (av_strcasecmp(keys[i], key) == 0) { 120cabdff1aSopenharmony_ci av_dict_set(&(s->metadata), keys[i], value, AV_DICT_DONT_STRDUP_VAL); 121cabdff1aSopenharmony_ci value = NULL; 122cabdff1aSopenharmony_ci break; 123cabdff1aSopenharmony_ci } 124cabdff1aSopenharmony_ci } 125cabdff1aSopenharmony_ci } 126cabdff1aSopenharmony_ci av_freep(&key); 127cabdff1aSopenharmony_ci av_freep(&value); 128cabdff1aSopenharmony_ci state = (c == '\0') ? PARSE_FINISHED : PARSE_KEY; 129cabdff1aSopenharmony_ci } else { 130cabdff1aSopenharmony_ci av_bprint_chars(&bprint, c, 1); 131cabdff1aSopenharmony_ci } 132cabdff1aSopenharmony_ci break; 133cabdff1aSopenharmony_ci case PARSE_FINISHED: 134cabdff1aSopenharmony_ci break; 135cabdff1aSopenharmony_ci default: 136cabdff1aSopenharmony_ci /* should never happen */ 137cabdff1aSopenharmony_ci av_assert0(0); 138cabdff1aSopenharmony_ci } 139cabdff1aSopenharmony_ci } 140cabdff1aSopenharmony_ci av_bprint_finalize(&bprint, NULL); 141cabdff1aSopenharmony_ci av_freep(&key); 142cabdff1aSopenharmony_ci return 0; 143cabdff1aSopenharmony_ci} 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci#define BLOCK_SIZE 1024 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_cistatic int au_read_header(AVFormatContext *s) 148cabdff1aSopenharmony_ci{ 149cabdff1aSopenharmony_ci int size, data_size = 0; 150cabdff1aSopenharmony_ci unsigned int tag; 151cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 152cabdff1aSopenharmony_ci unsigned int id, channels, rate; 153cabdff1aSopenharmony_ci int bps, ba = 0; 154cabdff1aSopenharmony_ci enum AVCodecID codec; 155cabdff1aSopenharmony_ci AVStream *st; 156cabdff1aSopenharmony_ci int ret; 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci tag = avio_rl32(pb); 159cabdff1aSopenharmony_ci if (tag != MKTAG('.', 's', 'n', 'd')) 160cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 161cabdff1aSopenharmony_ci size = avio_rb32(pb); /* header size */ 162cabdff1aSopenharmony_ci data_size = avio_rb32(pb); /* data size in bytes */ 163cabdff1aSopenharmony_ci 164cabdff1aSopenharmony_ci if (data_size < 0 && data_size != AU_UNKNOWN_SIZE) { 165cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Invalid negative data size '%d' found\n", data_size); 166cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 167cabdff1aSopenharmony_ci } 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci id = avio_rb32(pb); 170cabdff1aSopenharmony_ci rate = avio_rb32(pb); 171cabdff1aSopenharmony_ci channels = avio_rb32(pb); 172cabdff1aSopenharmony_ci 173cabdff1aSopenharmony_ci if (size > 24) { 174cabdff1aSopenharmony_ci /* parse annotation field to get metadata */ 175cabdff1aSopenharmony_ci ret = au_read_annotation(s, size - 24); 176cabdff1aSopenharmony_ci if (ret < 0) 177cabdff1aSopenharmony_ci return ret; 178cabdff1aSopenharmony_ci } 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci codec = ff_codec_get_id(codec_au_tags, id); 181cabdff1aSopenharmony_ci 182cabdff1aSopenharmony_ci if (codec == AV_CODEC_ID_NONE) { 183cabdff1aSopenharmony_ci avpriv_request_sample(s, "unknown or unsupported codec tag: %u", id); 184cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 185cabdff1aSopenharmony_ci } 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci bps = av_get_bits_per_sample(codec); 188cabdff1aSopenharmony_ci if (codec == AV_CODEC_ID_ADPCM_G726LE) { 189cabdff1aSopenharmony_ci if (id == MKBETAG('7','2','6','2')) { 190cabdff1aSopenharmony_ci bps = 2; 191cabdff1aSopenharmony_ci } else { 192cabdff1aSopenharmony_ci const uint8_t bpcss[] = {4, 0, 3, 5}; 193cabdff1aSopenharmony_ci av_assert0(id >= 23 && id < 23 + 4); 194cabdff1aSopenharmony_ci ba = bpcss[id - 23]; 195cabdff1aSopenharmony_ci bps = bpcss[id - 23]; 196cabdff1aSopenharmony_ci } 197cabdff1aSopenharmony_ci } else if (!bps) { 198cabdff1aSopenharmony_ci avpriv_request_sample(s, "Unknown bits per sample"); 199cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 200cabdff1aSopenharmony_ci } 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci if (channels == 0 || channels >= INT_MAX / (BLOCK_SIZE * bps >> 3)) { 203cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Invalid number of channels %u\n", channels); 204cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 205cabdff1aSopenharmony_ci } 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci if (rate == 0 || rate > INT_MAX) { 208cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Invalid sample rate: %u\n", rate); 209cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 210cabdff1aSopenharmony_ci } 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci st = avformat_new_stream(s, NULL); 213cabdff1aSopenharmony_ci if (!st) 214cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 215cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; 216cabdff1aSopenharmony_ci st->codecpar->codec_tag = id; 217cabdff1aSopenharmony_ci st->codecpar->codec_id = codec; 218cabdff1aSopenharmony_ci st->codecpar->ch_layout.nb_channels = channels; 219cabdff1aSopenharmony_ci st->codecpar->sample_rate = rate; 220cabdff1aSopenharmony_ci st->codecpar->bits_per_coded_sample = bps; 221cabdff1aSopenharmony_ci st->codecpar->bit_rate = channels * rate * bps; 222cabdff1aSopenharmony_ci st->codecpar->block_align = ba ? ba : FFMAX(bps * channels / 8, 1); 223cabdff1aSopenharmony_ci if (data_size != AU_UNKNOWN_SIZE) 224cabdff1aSopenharmony_ci st->duration = (((int64_t)data_size)<<3) / (channels * (int64_t)bps); 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci st->start_time = 0; 227cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 64, 1, rate); 228cabdff1aSopenharmony_ci 229cabdff1aSopenharmony_ci return 0; 230cabdff1aSopenharmony_ci} 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ciconst AVInputFormat ff_au_demuxer = { 233cabdff1aSopenharmony_ci .name = "au", 234cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("Sun AU"), 235cabdff1aSopenharmony_ci .read_probe = au_probe, 236cabdff1aSopenharmony_ci .read_header = au_read_header, 237cabdff1aSopenharmony_ci .read_packet = ff_pcm_read_packet, 238cabdff1aSopenharmony_ci .read_seek = ff_pcm_read_seek, 239cabdff1aSopenharmony_ci .codec_tag = au_codec_tags, 240cabdff1aSopenharmony_ci}; 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci#endif /* CONFIG_AU_DEMUXER */ 243cabdff1aSopenharmony_ci 244cabdff1aSopenharmony_ci#if CONFIG_AU_MUXER 245cabdff1aSopenharmony_ci 246cabdff1aSopenharmony_citypedef struct AUContext { 247cabdff1aSopenharmony_ci uint32_t header_size; 248cabdff1aSopenharmony_ci} AUContext; 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci#include "rawenc.h" 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_cistatic int au_get_annotations(AVFormatContext *s, AVBPrint *annotations) 253cabdff1aSopenharmony_ci{ 254cabdff1aSopenharmony_ci static const char keys[][7] = { 255cabdff1aSopenharmony_ci "Title", 256cabdff1aSopenharmony_ci "Artist", 257cabdff1aSopenharmony_ci "Album", 258cabdff1aSopenharmony_ci "Track", 259cabdff1aSopenharmony_ci "Genre", 260cabdff1aSopenharmony_ci }; 261cabdff1aSopenharmony_ci int cnt = 0; 262cabdff1aSopenharmony_ci AVDictionary *m = s->metadata; 263cabdff1aSopenharmony_ci AVDictionaryEntry *t = NULL; 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_ci for (int i = 0; i < FF_ARRAY_ELEMS(keys); i++) { 266cabdff1aSopenharmony_ci t = av_dict_get(m, keys[i], NULL, 0); 267cabdff1aSopenharmony_ci if (t != NULL) { 268cabdff1aSopenharmony_ci if (cnt++) 269cabdff1aSopenharmony_ci av_bprint_chars(annotations, '\n', 1); 270cabdff1aSopenharmony_ci av_bprintf(annotations, "%s=%s", keys[i], t->value); 271cabdff1aSopenharmony_ci } 272cabdff1aSopenharmony_ci } 273cabdff1aSopenharmony_ci /* The specification requires the annotation field to be zero-terminated 274cabdff1aSopenharmony_ci * and its length to be a multiple of eight, so pad with 0's */ 275cabdff1aSopenharmony_ci av_bprint_chars(annotations, '\0', 8); 276cabdff1aSopenharmony_ci return av_bprint_is_complete(annotations) ? 0 : AVERROR(ENOMEM); 277cabdff1aSopenharmony_ci} 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_cistatic int au_write_header(AVFormatContext *s) 280cabdff1aSopenharmony_ci{ 281cabdff1aSopenharmony_ci int ret; 282cabdff1aSopenharmony_ci AUContext *au = s->priv_data; 283cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 284cabdff1aSopenharmony_ci AVCodecParameters *par = s->streams[0]->codecpar; 285cabdff1aSopenharmony_ci AVBPrint annotations; 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci if (s->nb_streams != 1) { 288cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "only one stream is supported\n"); 289cabdff1aSopenharmony_ci return AVERROR(EINVAL); 290cabdff1aSopenharmony_ci } 291cabdff1aSopenharmony_ci 292cabdff1aSopenharmony_ci par->codec_tag = ff_codec_get_tag(codec_au_tags, par->codec_id); 293cabdff1aSopenharmony_ci if (!par->codec_tag) { 294cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "unsupported codec\n"); 295cabdff1aSopenharmony_ci return AVERROR(EINVAL); 296cabdff1aSopenharmony_ci } 297cabdff1aSopenharmony_ci 298cabdff1aSopenharmony_ci av_bprint_init(&annotations, 0, INT_MAX - 24); 299cabdff1aSopenharmony_ci ret = au_get_annotations(s, &annotations); 300cabdff1aSopenharmony_ci if (ret < 0) 301cabdff1aSopenharmony_ci goto fail; 302cabdff1aSopenharmony_ci au->header_size = 24 + annotations.len & ~7; 303cabdff1aSopenharmony_ci 304cabdff1aSopenharmony_ci ffio_wfourcc(pb, ".snd"); /* magic number */ 305cabdff1aSopenharmony_ci avio_wb32(pb, au->header_size); /* header size */ 306cabdff1aSopenharmony_ci avio_wb32(pb, AU_UNKNOWN_SIZE); /* data size */ 307cabdff1aSopenharmony_ci avio_wb32(pb, par->codec_tag); /* codec ID */ 308cabdff1aSopenharmony_ci avio_wb32(pb, par->sample_rate); 309cabdff1aSopenharmony_ci avio_wb32(pb, par->ch_layout.nb_channels); 310cabdff1aSopenharmony_ci avio_write(pb, annotations.str, annotations.len & ~7); 311cabdff1aSopenharmony_ci 312cabdff1aSopenharmony_cifail: 313cabdff1aSopenharmony_ci av_bprint_finalize(&annotations, NULL); 314cabdff1aSopenharmony_ci 315cabdff1aSopenharmony_ci return ret; 316cabdff1aSopenharmony_ci} 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_cistatic int au_write_trailer(AVFormatContext *s) 319cabdff1aSopenharmony_ci{ 320cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 321cabdff1aSopenharmony_ci AUContext *au = s->priv_data; 322cabdff1aSopenharmony_ci int64_t file_size = avio_tell(pb); 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_ci if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && file_size < INT32_MAX) { 325cabdff1aSopenharmony_ci /* update file size */ 326cabdff1aSopenharmony_ci avio_seek(pb, 8, SEEK_SET); 327cabdff1aSopenharmony_ci avio_wb32(pb, (uint32_t)(file_size - au->header_size)); 328cabdff1aSopenharmony_ci avio_seek(pb, file_size, SEEK_SET); 329cabdff1aSopenharmony_ci } 330cabdff1aSopenharmony_ci 331cabdff1aSopenharmony_ci return 0; 332cabdff1aSopenharmony_ci} 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_ciconst AVOutputFormat ff_au_muxer = { 335cabdff1aSopenharmony_ci .name = "au", 336cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("Sun AU"), 337cabdff1aSopenharmony_ci .mime_type = "audio/basic", 338cabdff1aSopenharmony_ci .extensions = "au", 339cabdff1aSopenharmony_ci .priv_data_size = sizeof(AUContext), 340cabdff1aSopenharmony_ci .audio_codec = AV_CODEC_ID_PCM_S16BE, 341cabdff1aSopenharmony_ci .video_codec = AV_CODEC_ID_NONE, 342cabdff1aSopenharmony_ci .write_header = au_write_header, 343cabdff1aSopenharmony_ci .write_packet = ff_raw_write_packet, 344cabdff1aSopenharmony_ci .write_trailer = au_write_trailer, 345cabdff1aSopenharmony_ci .codec_tag = au_codec_tags, 346cabdff1aSopenharmony_ci .flags = AVFMT_NOTIMESTAMPS, 347cabdff1aSopenharmony_ci}; 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ci#endif /* CONFIG_AU_MUXER */ 350