1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * FLV demuxer 3cabdff1aSopenharmony_ci * Copyright (c) 2003 The FFmpeg Project 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This demuxer will generate a 1 byte extradata for VP6F content. 6cabdff1aSopenharmony_ci * It is composed of: 7cabdff1aSopenharmony_ci * - upper 4 bits: difference between encoded width and visible width 8cabdff1aSopenharmony_ci * - lower 4 bits: difference between encoded height and visible height 9cabdff1aSopenharmony_ci * 10cabdff1aSopenharmony_ci * This file is part of FFmpeg. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 13cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 14cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 15cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 18cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 19cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20cabdff1aSopenharmony_ci * Lesser General Public License for more details. 21cabdff1aSopenharmony_ci * 22cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 23cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 24cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 25cabdff1aSopenharmony_ci */ 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 28cabdff1aSopenharmony_ci#include "libavutil/avstring.h" 29cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 30cabdff1aSopenharmony_ci#include "libavutil/dict.h" 31cabdff1aSopenharmony_ci#include "libavutil/opt.h" 32cabdff1aSopenharmony_ci#include "libavutil/internal.h" 33cabdff1aSopenharmony_ci#include "libavutil/intfloat.h" 34cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 35cabdff1aSopenharmony_ci#include "libavutil/mathematics.h" 36cabdff1aSopenharmony_ci#include "avformat.h" 37cabdff1aSopenharmony_ci#include "demux.h" 38cabdff1aSopenharmony_ci#include "internal.h" 39cabdff1aSopenharmony_ci#include "flv.h" 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci#define VALIDATE_INDEX_TS_THRESH 2500 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci#define RESYNC_BUFFER_SIZE (1<<20) 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci#define MAX_DEPTH 16 ///< arbitrary limit to prevent unbounded recursion 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_citypedef struct FLVContext { 48cabdff1aSopenharmony_ci const AVClass *class; ///< Class for private options. 49cabdff1aSopenharmony_ci int trust_metadata; ///< configure streams according onMetaData 50cabdff1aSopenharmony_ci int trust_datasize; ///< trust data size of FLVTag 51cabdff1aSopenharmony_ci int dump_full_metadata; ///< Dump full metadata of the onMetadata 52cabdff1aSopenharmony_ci int wrong_dts; ///< wrong dts due to negative cts 53cabdff1aSopenharmony_ci uint8_t *new_extradata[FLV_STREAM_TYPE_NB]; 54cabdff1aSopenharmony_ci int new_extradata_size[FLV_STREAM_TYPE_NB]; 55cabdff1aSopenharmony_ci int last_sample_rate; 56cabdff1aSopenharmony_ci int last_channels; 57cabdff1aSopenharmony_ci struct { 58cabdff1aSopenharmony_ci int64_t dts; 59cabdff1aSopenharmony_ci int64_t pos; 60cabdff1aSopenharmony_ci } validate_index[2]; 61cabdff1aSopenharmony_ci int validate_next; 62cabdff1aSopenharmony_ci int validate_count; 63cabdff1aSopenharmony_ci int searched_for_end; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci uint8_t resync_buffer[2*RESYNC_BUFFER_SIZE]; 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci int broken_sizes; 68cabdff1aSopenharmony_ci int64_t sum_flv_tag_size; 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci int last_keyframe_stream_index; 71cabdff1aSopenharmony_ci int keyframe_count; 72cabdff1aSopenharmony_ci int64_t video_bit_rate; 73cabdff1aSopenharmony_ci int64_t audio_bit_rate; 74cabdff1aSopenharmony_ci int64_t *keyframe_times; 75cabdff1aSopenharmony_ci int64_t *keyframe_filepositions; 76cabdff1aSopenharmony_ci int missing_streams; 77cabdff1aSopenharmony_ci AVRational framerate; 78cabdff1aSopenharmony_ci int64_t last_ts; 79cabdff1aSopenharmony_ci int64_t time_offset; 80cabdff1aSopenharmony_ci int64_t time_pos; 81cabdff1aSopenharmony_ci} FLVContext; 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci/* AMF date type */ 84cabdff1aSopenharmony_citypedef struct amf_date { 85cabdff1aSopenharmony_ci double milliseconds; 86cabdff1aSopenharmony_ci int16_t timezone; 87cabdff1aSopenharmony_ci} amf_date; 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_cistatic int probe(const AVProbeData *p, int live) 90cabdff1aSopenharmony_ci{ 91cabdff1aSopenharmony_ci const uint8_t *d = p->buf; 92cabdff1aSopenharmony_ci unsigned offset = AV_RB32(d + 5); 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci if (d[0] == 'F' && 95cabdff1aSopenharmony_ci d[1] == 'L' && 96cabdff1aSopenharmony_ci d[2] == 'V' && 97cabdff1aSopenharmony_ci d[3] < 5 && d[5] == 0 && 98cabdff1aSopenharmony_ci offset + 100 < p->buf_size && 99cabdff1aSopenharmony_ci offset > 8) { 100cabdff1aSopenharmony_ci int is_live = !memcmp(d + offset + 40, "NGINX RTMP", 10); 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci if (live == is_live) 103cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX; 104cabdff1aSopenharmony_ci } 105cabdff1aSopenharmony_ci return 0; 106cabdff1aSopenharmony_ci} 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_cistatic int flv_probe(const AVProbeData *p) 109cabdff1aSopenharmony_ci{ 110cabdff1aSopenharmony_ci return probe(p, 0); 111cabdff1aSopenharmony_ci} 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_cistatic int live_flv_probe(const AVProbeData *p) 114cabdff1aSopenharmony_ci{ 115cabdff1aSopenharmony_ci return probe(p, 1); 116cabdff1aSopenharmony_ci} 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_cistatic int kux_probe(const AVProbeData *p) 119cabdff1aSopenharmony_ci{ 120cabdff1aSopenharmony_ci const uint8_t *d = p->buf; 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci if (d[0] == 'K' && 123cabdff1aSopenharmony_ci d[1] == 'D' && 124cabdff1aSopenharmony_ci d[2] == 'K' && 125cabdff1aSopenharmony_ci d[3] == 0 && 126cabdff1aSopenharmony_ci d[4] == 0) { 127cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci return 0; 130cabdff1aSopenharmony_ci} 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_cistatic void add_keyframes_index(AVFormatContext *s) 133cabdff1aSopenharmony_ci{ 134cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 135cabdff1aSopenharmony_ci AVStream *stream = NULL; 136cabdff1aSopenharmony_ci unsigned int i = 0; 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci if (flv->last_keyframe_stream_index < 0) { 139cabdff1aSopenharmony_ci av_log(s, AV_LOG_DEBUG, "keyframe stream hasn't been created\n"); 140cabdff1aSopenharmony_ci return; 141cabdff1aSopenharmony_ci } 142cabdff1aSopenharmony_ci 143cabdff1aSopenharmony_ci av_assert0(flv->last_keyframe_stream_index <= s->nb_streams); 144cabdff1aSopenharmony_ci stream = s->streams[flv->last_keyframe_stream_index]; 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_ci if (ffstream(stream)->nb_index_entries == 0) { 147cabdff1aSopenharmony_ci for (i = 0; i < flv->keyframe_count; i++) { 148cabdff1aSopenharmony_ci av_log(s, AV_LOG_TRACE, "keyframe filepositions = %"PRId64" times = %"PRId64"\n", 149cabdff1aSopenharmony_ci flv->keyframe_filepositions[i], flv->keyframe_times[i] * 1000); 150cabdff1aSopenharmony_ci av_add_index_entry(stream, flv->keyframe_filepositions[i], 151cabdff1aSopenharmony_ci flv->keyframe_times[i] * 1000, 0, 0, AVINDEX_KEYFRAME); 152cabdff1aSopenharmony_ci } 153cabdff1aSopenharmony_ci } else 154cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); 155cabdff1aSopenharmony_ci 156cabdff1aSopenharmony_ci if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { 157cabdff1aSopenharmony_ci av_freep(&flv->keyframe_times); 158cabdff1aSopenharmony_ci av_freep(&flv->keyframe_filepositions); 159cabdff1aSopenharmony_ci flv->keyframe_count = 0; 160cabdff1aSopenharmony_ci } 161cabdff1aSopenharmony_ci} 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_cistatic AVStream *create_stream(AVFormatContext *s, int codec_type) 164cabdff1aSopenharmony_ci{ 165cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 166cabdff1aSopenharmony_ci AVStream *st = avformat_new_stream(s, NULL); 167cabdff1aSopenharmony_ci if (!st) 168cabdff1aSopenharmony_ci return NULL; 169cabdff1aSopenharmony_ci st->codecpar->codec_type = codec_type; 170cabdff1aSopenharmony_ci if (s->nb_streams>=3 ||( s->nb_streams==2 171cabdff1aSopenharmony_ci && s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE 172cabdff1aSopenharmony_ci && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE 173cabdff1aSopenharmony_ci && s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_DATA 174cabdff1aSopenharmony_ci && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_DATA)) 175cabdff1aSopenharmony_ci s->ctx_flags &= ~AVFMTCTX_NOHEADER; 176cabdff1aSopenharmony_ci if (codec_type == AVMEDIA_TYPE_AUDIO) { 177cabdff1aSopenharmony_ci st->codecpar->bit_rate = flv->audio_bit_rate; 178cabdff1aSopenharmony_ci flv->missing_streams &= ~FLV_HEADER_FLAG_HASAUDIO; 179cabdff1aSopenharmony_ci } 180cabdff1aSopenharmony_ci if (codec_type == AVMEDIA_TYPE_VIDEO) { 181cabdff1aSopenharmony_ci st->codecpar->bit_rate = flv->video_bit_rate; 182cabdff1aSopenharmony_ci flv->missing_streams &= ~FLV_HEADER_FLAG_HASVIDEO; 183cabdff1aSopenharmony_ci st->avg_frame_rate = flv->framerate; 184cabdff1aSopenharmony_ci } 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ 188cabdff1aSopenharmony_ci flv->last_keyframe_stream_index = s->nb_streams - 1; 189cabdff1aSopenharmony_ci add_keyframes_index(s); 190cabdff1aSopenharmony_ci return st; 191cabdff1aSopenharmony_ci} 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_cistatic int flv_same_audio_codec(AVCodecParameters *apar, int flags) 194cabdff1aSopenharmony_ci{ 195cabdff1aSopenharmony_ci int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8; 196cabdff1aSopenharmony_ci int flv_codecid = flags & FLV_AUDIO_CODECID_MASK; 197cabdff1aSopenharmony_ci int codec_id; 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_ci if (!apar->codec_id && !apar->codec_tag) 200cabdff1aSopenharmony_ci return 1; 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci if (apar->bits_per_coded_sample != bits_per_coded_sample) 203cabdff1aSopenharmony_ci return 0; 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ci switch (flv_codecid) { 206cabdff1aSopenharmony_ci // no distinction between S16 and S8 PCM codec flags 207cabdff1aSopenharmony_ci case FLV_CODECID_PCM: 208cabdff1aSopenharmony_ci codec_id = bits_per_coded_sample == 8 209cabdff1aSopenharmony_ci ? AV_CODEC_ID_PCM_U8 210cabdff1aSopenharmony_ci#if HAVE_BIGENDIAN 211cabdff1aSopenharmony_ci : AV_CODEC_ID_PCM_S16BE; 212cabdff1aSopenharmony_ci#else 213cabdff1aSopenharmony_ci : AV_CODEC_ID_PCM_S16LE; 214cabdff1aSopenharmony_ci#endif 215cabdff1aSopenharmony_ci return codec_id == apar->codec_id; 216cabdff1aSopenharmony_ci case FLV_CODECID_PCM_LE: 217cabdff1aSopenharmony_ci codec_id = bits_per_coded_sample == 8 218cabdff1aSopenharmony_ci ? AV_CODEC_ID_PCM_U8 219cabdff1aSopenharmony_ci : AV_CODEC_ID_PCM_S16LE; 220cabdff1aSopenharmony_ci return codec_id == apar->codec_id; 221cabdff1aSopenharmony_ci case FLV_CODECID_AAC: 222cabdff1aSopenharmony_ci return apar->codec_id == AV_CODEC_ID_AAC; 223cabdff1aSopenharmony_ci case FLV_CODECID_ADPCM: 224cabdff1aSopenharmony_ci return apar->codec_id == AV_CODEC_ID_ADPCM_SWF; 225cabdff1aSopenharmony_ci case FLV_CODECID_SPEEX: 226cabdff1aSopenharmony_ci return apar->codec_id == AV_CODEC_ID_SPEEX; 227cabdff1aSopenharmony_ci case FLV_CODECID_MP3: 228cabdff1aSopenharmony_ci return apar->codec_id == AV_CODEC_ID_MP3; 229cabdff1aSopenharmony_ci case FLV_CODECID_NELLYMOSER_8KHZ_MONO: 230cabdff1aSopenharmony_ci case FLV_CODECID_NELLYMOSER_16KHZ_MONO: 231cabdff1aSopenharmony_ci case FLV_CODECID_NELLYMOSER: 232cabdff1aSopenharmony_ci return apar->codec_id == AV_CODEC_ID_NELLYMOSER; 233cabdff1aSopenharmony_ci case FLV_CODECID_PCM_MULAW: 234cabdff1aSopenharmony_ci return apar->sample_rate == 8000 && 235cabdff1aSopenharmony_ci apar->codec_id == AV_CODEC_ID_PCM_MULAW; 236cabdff1aSopenharmony_ci case FLV_CODECID_PCM_ALAW: 237cabdff1aSopenharmony_ci return apar->sample_rate == 8000 && 238cabdff1aSopenharmony_ci apar->codec_id == AV_CODEC_ID_PCM_ALAW; 239cabdff1aSopenharmony_ci default: 240cabdff1aSopenharmony_ci return apar->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET); 241cabdff1aSopenharmony_ci } 242cabdff1aSopenharmony_ci} 243cabdff1aSopenharmony_ci 244cabdff1aSopenharmony_cistatic void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, 245cabdff1aSopenharmony_ci AVCodecParameters *apar, int flv_codecid) 246cabdff1aSopenharmony_ci{ 247cabdff1aSopenharmony_ci switch (flv_codecid) { 248cabdff1aSopenharmony_ci // no distinction between S16 and S8 PCM codec flags 249cabdff1aSopenharmony_ci case FLV_CODECID_PCM: 250cabdff1aSopenharmony_ci apar->codec_id = apar->bits_per_coded_sample == 8 251cabdff1aSopenharmony_ci ? AV_CODEC_ID_PCM_U8 252cabdff1aSopenharmony_ci#if HAVE_BIGENDIAN 253cabdff1aSopenharmony_ci : AV_CODEC_ID_PCM_S16BE; 254cabdff1aSopenharmony_ci#else 255cabdff1aSopenharmony_ci : AV_CODEC_ID_PCM_S16LE; 256cabdff1aSopenharmony_ci#endif 257cabdff1aSopenharmony_ci break; 258cabdff1aSopenharmony_ci case FLV_CODECID_PCM_LE: 259cabdff1aSopenharmony_ci apar->codec_id = apar->bits_per_coded_sample == 8 260cabdff1aSopenharmony_ci ? AV_CODEC_ID_PCM_U8 261cabdff1aSopenharmony_ci : AV_CODEC_ID_PCM_S16LE; 262cabdff1aSopenharmony_ci break; 263cabdff1aSopenharmony_ci case FLV_CODECID_AAC: 264cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_AAC; 265cabdff1aSopenharmony_ci break; 266cabdff1aSopenharmony_ci case FLV_CODECID_ADPCM: 267cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_ADPCM_SWF; 268cabdff1aSopenharmony_ci break; 269cabdff1aSopenharmony_ci case FLV_CODECID_SPEEX: 270cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_SPEEX; 271cabdff1aSopenharmony_ci apar->sample_rate = 16000; 272cabdff1aSopenharmony_ci break; 273cabdff1aSopenharmony_ci case FLV_CODECID_MP3: 274cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_MP3; 275cabdff1aSopenharmony_ci ffstream(astream)->need_parsing = AVSTREAM_PARSE_FULL; 276cabdff1aSopenharmony_ci break; 277cabdff1aSopenharmony_ci case FLV_CODECID_NELLYMOSER_8KHZ_MONO: 278cabdff1aSopenharmony_ci // in case metadata does not otherwise declare samplerate 279cabdff1aSopenharmony_ci apar->sample_rate = 8000; 280cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_NELLYMOSER; 281cabdff1aSopenharmony_ci break; 282cabdff1aSopenharmony_ci case FLV_CODECID_NELLYMOSER_16KHZ_MONO: 283cabdff1aSopenharmony_ci apar->sample_rate = 16000; 284cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_NELLYMOSER; 285cabdff1aSopenharmony_ci break; 286cabdff1aSopenharmony_ci case FLV_CODECID_NELLYMOSER: 287cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_NELLYMOSER; 288cabdff1aSopenharmony_ci break; 289cabdff1aSopenharmony_ci case FLV_CODECID_PCM_MULAW: 290cabdff1aSopenharmony_ci apar->sample_rate = 8000; 291cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_PCM_MULAW; 292cabdff1aSopenharmony_ci break; 293cabdff1aSopenharmony_ci case FLV_CODECID_PCM_ALAW: 294cabdff1aSopenharmony_ci apar->sample_rate = 8000; 295cabdff1aSopenharmony_ci apar->codec_id = AV_CODEC_ID_PCM_ALAW; 296cabdff1aSopenharmony_ci break; 297cabdff1aSopenharmony_ci default: 298cabdff1aSopenharmony_ci avpriv_request_sample(s, "Audio codec (%x)", 299cabdff1aSopenharmony_ci flv_codecid >> FLV_AUDIO_CODECID_OFFSET); 300cabdff1aSopenharmony_ci apar->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET; 301cabdff1aSopenharmony_ci } 302cabdff1aSopenharmony_ci} 303cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 304cabdff1aSopenharmony_cistatic int flv_same_video_codec(AVCodecParameters *vpar, uint32_t flv_codecid) 305cabdff1aSopenharmony_ci{ 306cabdff1aSopenharmony_ci if (!vpar->codec_id && !vpar->codec_tag) 307cabdff1aSopenharmony_ci return 1; 308cabdff1aSopenharmony_ci 309cabdff1aSopenharmony_ci switch (flv_codecid) { 310cabdff1aSopenharmony_ci case MKBETAG('h', 'v', 'c', '1'): 311cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_HEVC; 312cabdff1aSopenharmony_ci case FLV_CODECID_H263: 313cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_FLV1; 314cabdff1aSopenharmony_ci case FLV_CODECID_SCREEN: 315cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_FLASHSV; 316cabdff1aSopenharmony_ci case FLV_CODECID_SCREEN2: 317cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_FLASHSV2; 318cabdff1aSopenharmony_ci case FLV_CODECID_VP6: 319cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_VP6F; 320cabdff1aSopenharmony_ci case FLV_CODECID_VP6A: 321cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_VP6A; 322cabdff1aSopenharmony_ci case FLV_CODECID_H264: 323cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_H264; 324cabdff1aSopenharmony_ci case FLV_CODECID_HEVC: 325cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_HEVC; 326cabdff1aSopenharmony_ci default: 327cabdff1aSopenharmony_ci return vpar->codec_tag == flv_codecid; 328cabdff1aSopenharmony_ci } 329cabdff1aSopenharmony_ci} 330cabdff1aSopenharmony_ci#else 331cabdff1aSopenharmony_cistatic int flv_same_video_codec(AVCodecParameters *vpar, int flags) 332cabdff1aSopenharmony_ci{ 333cabdff1aSopenharmony_ci int flv_codecid = flags & FLV_VIDEO_CODECID_MASK; 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci if (!vpar->codec_id && !vpar->codec_tag) 336cabdff1aSopenharmony_ci return 1; 337cabdff1aSopenharmony_ci 338cabdff1aSopenharmony_ci switch (flv_codecid) { 339cabdff1aSopenharmony_ci case FLV_CODECID_H263: 340cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_FLV1; 341cabdff1aSopenharmony_ci case FLV_CODECID_SCREEN: 342cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_FLASHSV; 343cabdff1aSopenharmony_ci case FLV_CODECID_SCREEN2: 344cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_FLASHSV2; 345cabdff1aSopenharmony_ci case FLV_CODECID_VP6: 346cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_VP6F; 347cabdff1aSopenharmony_ci case FLV_CODECID_VP6A: 348cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_VP6A; 349cabdff1aSopenharmony_ci case FLV_CODECID_H264: 350cabdff1aSopenharmony_ci return vpar->codec_id == AV_CODEC_ID_H264; 351cabdff1aSopenharmony_ci default: 352cabdff1aSopenharmony_ci return vpar->codec_tag == flv_codecid; 353cabdff1aSopenharmony_ci } 354cabdff1aSopenharmony_ci} 355cabdff1aSopenharmony_ci#endif 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_cistatic int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, 358cabdff1aSopenharmony_ci int flv_codecid, int read) 359cabdff1aSopenharmony_ci{ 360cabdff1aSopenharmony_ci FFStream *const vstreami = ffstream(vstream); 361cabdff1aSopenharmony_ci int ret = 0; 362cabdff1aSopenharmony_ci AVCodecParameters *par = vstream->codecpar; 363cabdff1aSopenharmony_ci enum AVCodecID old_codec_id = vstream->codecpar->codec_id; 364cabdff1aSopenharmony_ci switch (flv_codecid) { 365cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 366cabdff1aSopenharmony_ci case MKBETAG('h', 'v', 'c', '1'): 367cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_HEVC; 368cabdff1aSopenharmony_ci vstreami->need_parsing = AVSTREAM_PARSE_HEADERS; 369cabdff1aSopenharmony_ci break; 370cabdff1aSopenharmony_ci#endif 371cabdff1aSopenharmony_ci case FLV_CODECID_H263: 372cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_FLV1; 373cabdff1aSopenharmony_ci break; 374cabdff1aSopenharmony_ci case FLV_CODECID_REALH263: 375cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_H263; 376cabdff1aSopenharmony_ci break; // Really mean it this time 377cabdff1aSopenharmony_ci case FLV_CODECID_SCREEN: 378cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_FLASHSV; 379cabdff1aSopenharmony_ci break; 380cabdff1aSopenharmony_ci case FLV_CODECID_SCREEN2: 381cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_FLASHSV2; 382cabdff1aSopenharmony_ci break; 383cabdff1aSopenharmony_ci case FLV_CODECID_VP6: 384cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_VP6F; 385cabdff1aSopenharmony_ci case FLV_CODECID_VP6A: 386cabdff1aSopenharmony_ci if (flv_codecid == FLV_CODECID_VP6A) 387cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_VP6A; 388cabdff1aSopenharmony_ci if (read) { 389cabdff1aSopenharmony_ci if (par->extradata_size != 1) { 390cabdff1aSopenharmony_ci ff_alloc_extradata(par, 1); 391cabdff1aSopenharmony_ci } 392cabdff1aSopenharmony_ci if (par->extradata) 393cabdff1aSopenharmony_ci par->extradata[0] = avio_r8(s->pb); 394cabdff1aSopenharmony_ci else 395cabdff1aSopenharmony_ci avio_skip(s->pb, 1); 396cabdff1aSopenharmony_ci } 397cabdff1aSopenharmony_ci ret = 1; // 1 byte body size adjustment for flv_read_packet() 398cabdff1aSopenharmony_ci break; 399cabdff1aSopenharmony_ci case FLV_CODECID_H264: 400cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_H264; 401cabdff1aSopenharmony_ci vstreami->need_parsing = AVSTREAM_PARSE_HEADERS; 402cabdff1aSopenharmony_ci#ifndef OHOS_H265_DEMUXER 403cabdff1aSopenharmony_ci ret = 3; 404cabdff1aSopenharmony_ci#endif 405cabdff1aSopenharmony_ci break; 406cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 407cabdff1aSopenharmony_ci case FLV_CODECID_HEVC: 408cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_HEVC; 409cabdff1aSopenharmony_ci vstreami->need_parsing = AVSTREAM_PARSE_HEADERS; 410cabdff1aSopenharmony_ci break; 411cabdff1aSopenharmony_ci#endif 412cabdff1aSopenharmony_ci case FLV_CODECID_MPEG4: 413cabdff1aSopenharmony_ci par->codec_id = AV_CODEC_ID_MPEG4; 414cabdff1aSopenharmony_ci#ifndef OHOS_H265_DEMUXER 415cabdff1aSopenharmony_ci ret = 3; 416cabdff1aSopenharmony_ci#endif 417cabdff1aSopenharmony_ci break; 418cabdff1aSopenharmony_ci default: 419cabdff1aSopenharmony_ci avpriv_request_sample(s, "Video codec (%x)", flv_codecid); 420cabdff1aSopenharmony_ci par->codec_tag = flv_codecid; 421cabdff1aSopenharmony_ci } 422cabdff1aSopenharmony_ci 423cabdff1aSopenharmony_ci if (!vstreami->need_context_update && par->codec_id != old_codec_id) { 424cabdff1aSopenharmony_ci avpriv_request_sample(s, "Changing the codec id midstream"); 425cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 426cabdff1aSopenharmony_ci } 427cabdff1aSopenharmony_ci 428cabdff1aSopenharmony_ci return ret; 429cabdff1aSopenharmony_ci} 430cabdff1aSopenharmony_ci 431cabdff1aSopenharmony_cistatic int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) 432cabdff1aSopenharmony_ci{ 433cabdff1aSopenharmony_ci int ret; 434cabdff1aSopenharmony_ci int length = avio_rb16(ioc); 435cabdff1aSopenharmony_ci if (length >= buffsize) { 436cabdff1aSopenharmony_ci avio_skip(ioc, length); 437cabdff1aSopenharmony_ci return -1; 438cabdff1aSopenharmony_ci } 439cabdff1aSopenharmony_ci 440cabdff1aSopenharmony_ci ret = avio_read(ioc, buffer, length); 441cabdff1aSopenharmony_ci if (ret < 0) 442cabdff1aSopenharmony_ci return ret; 443cabdff1aSopenharmony_ci if (ret < length) 444cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 445cabdff1aSopenharmony_ci 446cabdff1aSopenharmony_ci buffer[length] = '\0'; 447cabdff1aSopenharmony_ci 448cabdff1aSopenharmony_ci return length; 449cabdff1aSopenharmony_ci} 450cabdff1aSopenharmony_ci 451cabdff1aSopenharmony_cistatic int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t max_pos) 452cabdff1aSopenharmony_ci{ 453cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 454cabdff1aSopenharmony_ci unsigned int timeslen = 0, fileposlen = 0, i; 455cabdff1aSopenharmony_ci char str_val[256]; 456cabdff1aSopenharmony_ci int64_t *times = NULL; 457cabdff1aSopenharmony_ci int64_t *filepositions = NULL; 458cabdff1aSopenharmony_ci int ret = AVERROR(ENOSYS); 459cabdff1aSopenharmony_ci int64_t initial_pos = avio_tell(ioc); 460cabdff1aSopenharmony_ci 461cabdff1aSopenharmony_ci if (flv->keyframe_count > 0) { 462cabdff1aSopenharmony_ci av_log(s, AV_LOG_DEBUG, "keyframes have been parsed\n"); 463cabdff1aSopenharmony_ci return 0; 464cabdff1aSopenharmony_ci } 465cabdff1aSopenharmony_ci av_assert0(!flv->keyframe_times); 466cabdff1aSopenharmony_ci av_assert0(!flv->keyframe_filepositions); 467cabdff1aSopenharmony_ci 468cabdff1aSopenharmony_ci if (s->flags & AVFMT_FLAG_IGNIDX) 469cabdff1aSopenharmony_ci return 0; 470cabdff1aSopenharmony_ci 471cabdff1aSopenharmony_ci while (avio_tell(ioc) < max_pos - 2 && 472cabdff1aSopenharmony_ci amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { 473cabdff1aSopenharmony_ci int64_t **current_array; 474cabdff1aSopenharmony_ci unsigned int arraylen; 475cabdff1aSopenharmony_ci 476cabdff1aSopenharmony_ci // Expect array object in context 477cabdff1aSopenharmony_ci if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY) 478cabdff1aSopenharmony_ci break; 479cabdff1aSopenharmony_ci 480cabdff1aSopenharmony_ci arraylen = avio_rb32(ioc); 481cabdff1aSopenharmony_ci if (arraylen>>28) 482cabdff1aSopenharmony_ci break; 483cabdff1aSopenharmony_ci 484cabdff1aSopenharmony_ci if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times) { 485cabdff1aSopenharmony_ci current_array = × 486cabdff1aSopenharmony_ci timeslen = arraylen; 487cabdff1aSopenharmony_ci } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && 488cabdff1aSopenharmony_ci !filepositions) { 489cabdff1aSopenharmony_ci current_array = &filepositions; 490cabdff1aSopenharmony_ci fileposlen = arraylen; 491cabdff1aSopenharmony_ci } else 492cabdff1aSopenharmony_ci // unexpected metatag inside keyframes, will not use such 493cabdff1aSopenharmony_ci // metadata for indexing 494cabdff1aSopenharmony_ci break; 495cabdff1aSopenharmony_ci 496cabdff1aSopenharmony_ci if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) { 497cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 498cabdff1aSopenharmony_ci goto finish; 499cabdff1aSopenharmony_ci } 500cabdff1aSopenharmony_ci 501cabdff1aSopenharmony_ci for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) { 502cabdff1aSopenharmony_ci double d; 503cabdff1aSopenharmony_ci if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER) 504cabdff1aSopenharmony_ci goto invalid; 505cabdff1aSopenharmony_ci d = av_int2double(avio_rb64(ioc)); 506cabdff1aSopenharmony_ci if (isnan(d) || d < INT64_MIN || d > INT64_MAX) 507cabdff1aSopenharmony_ci goto invalid; 508cabdff1aSopenharmony_ci if (current_array == × && (d <= INT64_MIN / 1000 || d >= INT64_MAX / 1000)) 509cabdff1aSopenharmony_ci goto invalid; 510cabdff1aSopenharmony_ci if (avio_feof(ioc)) 511cabdff1aSopenharmony_ci goto invalid; 512cabdff1aSopenharmony_ci current_array[0][i] = d; 513cabdff1aSopenharmony_ci } 514cabdff1aSopenharmony_ci if (times && filepositions) { 515cabdff1aSopenharmony_ci // All done, exiting at a position allowing amf_parse_object 516cabdff1aSopenharmony_ci // to finish parsing the object 517cabdff1aSopenharmony_ci ret = 0; 518cabdff1aSopenharmony_ci break; 519cabdff1aSopenharmony_ci } 520cabdff1aSopenharmony_ci } 521cabdff1aSopenharmony_ci 522cabdff1aSopenharmony_ci if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) { 523cabdff1aSopenharmony_ci for (i = 0; i < FFMIN(2,fileposlen); i++) { 524cabdff1aSopenharmony_ci flv->validate_index[i].pos = filepositions[i]; 525cabdff1aSopenharmony_ci flv->validate_index[i].dts = times[i] * 1000; 526cabdff1aSopenharmony_ci flv->validate_count = i + 1; 527cabdff1aSopenharmony_ci } 528cabdff1aSopenharmony_ci flv->keyframe_times = times; 529cabdff1aSopenharmony_ci flv->keyframe_filepositions = filepositions; 530cabdff1aSopenharmony_ci flv->keyframe_count = timeslen; 531cabdff1aSopenharmony_ci times = NULL; 532cabdff1aSopenharmony_ci filepositions = NULL; 533cabdff1aSopenharmony_ci } else { 534cabdff1aSopenharmony_ciinvalid: 535cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n"); 536cabdff1aSopenharmony_ci } 537cabdff1aSopenharmony_ci 538cabdff1aSopenharmony_cifinish: 539cabdff1aSopenharmony_ci av_freep(×); 540cabdff1aSopenharmony_ci av_freep(&filepositions); 541cabdff1aSopenharmony_ci avio_seek(ioc, initial_pos, SEEK_SET); 542cabdff1aSopenharmony_ci return ret; 543cabdff1aSopenharmony_ci} 544cabdff1aSopenharmony_ci 545cabdff1aSopenharmony_cistatic int amf_parse_object(AVFormatContext *s, AVStream *astream, 546cabdff1aSopenharmony_ci AVStream *vstream, const char *key, 547cabdff1aSopenharmony_ci int64_t max_pos, int depth) 548cabdff1aSopenharmony_ci{ 549cabdff1aSopenharmony_ci AVCodecParameters *apar, *vpar; 550cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 551cabdff1aSopenharmony_ci AVIOContext *ioc; 552cabdff1aSopenharmony_ci AMFDataType amf_type; 553cabdff1aSopenharmony_ci char str_val[1024]; 554cabdff1aSopenharmony_ci double num_val; 555cabdff1aSopenharmony_ci amf_date date; 556cabdff1aSopenharmony_ci 557cabdff1aSopenharmony_ci if (depth > MAX_DEPTH) 558cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 559cabdff1aSopenharmony_ci 560cabdff1aSopenharmony_ci num_val = 0; 561cabdff1aSopenharmony_ci ioc = s->pb; 562cabdff1aSopenharmony_ci if (avio_feof(ioc)) 563cabdff1aSopenharmony_ci return AVERROR_EOF; 564cabdff1aSopenharmony_ci amf_type = avio_r8(ioc); 565cabdff1aSopenharmony_ci 566cabdff1aSopenharmony_ci switch (amf_type) { 567cabdff1aSopenharmony_ci case AMF_DATA_TYPE_NUMBER: 568cabdff1aSopenharmony_ci num_val = av_int2double(avio_rb64(ioc)); 569cabdff1aSopenharmony_ci break; 570cabdff1aSopenharmony_ci case AMF_DATA_TYPE_BOOL: 571cabdff1aSopenharmony_ci num_val = avio_r8(ioc); 572cabdff1aSopenharmony_ci break; 573cabdff1aSopenharmony_ci case AMF_DATA_TYPE_STRING: 574cabdff1aSopenharmony_ci if (amf_get_string(ioc, str_val, sizeof(str_val)) < 0) { 575cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "AMF_DATA_TYPE_STRING parsing failed\n"); 576cabdff1aSopenharmony_ci return -1; 577cabdff1aSopenharmony_ci } 578cabdff1aSopenharmony_ci break; 579cabdff1aSopenharmony_ci case AMF_DATA_TYPE_OBJECT: 580cabdff1aSopenharmony_ci if (key && 581cabdff1aSopenharmony_ci (ioc->seekable & AVIO_SEEKABLE_NORMAL) && 582cabdff1aSopenharmony_ci !strcmp(KEYFRAMES_TAG, key) && depth == 1) 583cabdff1aSopenharmony_ci if (parse_keyframes_index(s, ioc, max_pos) < 0) 584cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); 585cabdff1aSopenharmony_ci else 586cabdff1aSopenharmony_ci add_keyframes_index(s); 587cabdff1aSopenharmony_ci while (avio_tell(ioc) < max_pos - 2 && 588cabdff1aSopenharmony_ci amf_get_string(ioc, str_val, sizeof(str_val)) > 0) 589cabdff1aSopenharmony_ci if (amf_parse_object(s, astream, vstream, str_val, max_pos, 590cabdff1aSopenharmony_ci depth + 1) < 0) 591cabdff1aSopenharmony_ci return -1; // if we couldn't skip, bomb out. 592cabdff1aSopenharmony_ci if (avio_r8(ioc) != AMF_END_OF_OBJECT) { 593cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Missing AMF_END_OF_OBJECT in AMF_DATA_TYPE_OBJECT\n"); 594cabdff1aSopenharmony_ci return -1; 595cabdff1aSopenharmony_ci } 596cabdff1aSopenharmony_ci break; 597cabdff1aSopenharmony_ci case AMF_DATA_TYPE_NULL: 598cabdff1aSopenharmony_ci case AMF_DATA_TYPE_UNDEFINED: 599cabdff1aSopenharmony_ci case AMF_DATA_TYPE_UNSUPPORTED: 600cabdff1aSopenharmony_ci break; // these take up no additional space 601cabdff1aSopenharmony_ci case AMF_DATA_TYPE_MIXEDARRAY: 602cabdff1aSopenharmony_ci { 603cabdff1aSopenharmony_ci unsigned v; 604cabdff1aSopenharmony_ci avio_skip(ioc, 4); // skip 32-bit max array index 605cabdff1aSopenharmony_ci while (avio_tell(ioc) < max_pos - 2 && 606cabdff1aSopenharmony_ci amf_get_string(ioc, str_val, sizeof(str_val)) > 0) 607cabdff1aSopenharmony_ci // this is the only case in which we would want a nested 608cabdff1aSopenharmony_ci // parse to not skip over the object 609cabdff1aSopenharmony_ci if (amf_parse_object(s, astream, vstream, str_val, max_pos, 610cabdff1aSopenharmony_ci depth + 1) < 0) 611cabdff1aSopenharmony_ci return -1; 612cabdff1aSopenharmony_ci v = avio_r8(ioc); 613cabdff1aSopenharmony_ci if (v != AMF_END_OF_OBJECT) { 614cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Missing AMF_END_OF_OBJECT in AMF_DATA_TYPE_MIXEDARRAY, found %d\n", v); 615cabdff1aSopenharmony_ci return -1; 616cabdff1aSopenharmony_ci } 617cabdff1aSopenharmony_ci break; 618cabdff1aSopenharmony_ci } 619cabdff1aSopenharmony_ci case AMF_DATA_TYPE_ARRAY: 620cabdff1aSopenharmony_ci { 621cabdff1aSopenharmony_ci unsigned int arraylen, i; 622cabdff1aSopenharmony_ci 623cabdff1aSopenharmony_ci arraylen = avio_rb32(ioc); 624cabdff1aSopenharmony_ci for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) 625cabdff1aSopenharmony_ci if (amf_parse_object(s, NULL, NULL, NULL, max_pos, 626cabdff1aSopenharmony_ci depth + 1) < 0) 627cabdff1aSopenharmony_ci return -1; // if we couldn't skip, bomb out. 628cabdff1aSopenharmony_ci } 629cabdff1aSopenharmony_ci break; 630cabdff1aSopenharmony_ci case AMF_DATA_TYPE_DATE: 631cabdff1aSopenharmony_ci // timestamp (double) and UTC offset (int16) 632cabdff1aSopenharmony_ci date.milliseconds = av_int2double(avio_rb64(ioc)); 633cabdff1aSopenharmony_ci date.timezone = avio_rb16(ioc); 634cabdff1aSopenharmony_ci break; 635cabdff1aSopenharmony_ci default: // unsupported type, we couldn't skip 636cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "unsupported amf type %d\n", amf_type); 637cabdff1aSopenharmony_ci return -1; 638cabdff1aSopenharmony_ci } 639cabdff1aSopenharmony_ci 640cabdff1aSopenharmony_ci if (key) { 641cabdff1aSopenharmony_ci apar = astream ? astream->codecpar : NULL; 642cabdff1aSopenharmony_ci vpar = vstream ? vstream->codecpar : NULL; 643cabdff1aSopenharmony_ci 644cabdff1aSopenharmony_ci // stream info doesn't live any deeper than the first object 645cabdff1aSopenharmony_ci if (depth == 1) { 646cabdff1aSopenharmony_ci if (amf_type == AMF_DATA_TYPE_NUMBER || 647cabdff1aSopenharmony_ci amf_type == AMF_DATA_TYPE_BOOL) { 648cabdff1aSopenharmony_ci if (!strcmp(key, "duration")) 649cabdff1aSopenharmony_ci s->duration = num_val * AV_TIME_BASE; 650cabdff1aSopenharmony_ci else if (!strcmp(key, "videodatarate") && 651cabdff1aSopenharmony_ci 0 <= (int)(num_val * 1024.0)) 652cabdff1aSopenharmony_ci flv->video_bit_rate = num_val * 1024.0; 653cabdff1aSopenharmony_ci else if (!strcmp(key, "audiodatarate") && 654cabdff1aSopenharmony_ci 0 <= (int)(num_val * 1024.0)) 655cabdff1aSopenharmony_ci flv->audio_bit_rate = num_val * 1024.0; 656cabdff1aSopenharmony_ci else if (!strcmp(key, "datastream")) { 657cabdff1aSopenharmony_ci AVStream *st = create_stream(s, AVMEDIA_TYPE_SUBTITLE); 658cabdff1aSopenharmony_ci if (!st) 659cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 660cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_TEXT; 661cabdff1aSopenharmony_ci } else if (!strcmp(key, "framerate")) { 662cabdff1aSopenharmony_ci flv->framerate = av_d2q(num_val, 1000); 663cabdff1aSopenharmony_ci if (vstream) 664cabdff1aSopenharmony_ci vstream->avg_frame_rate = flv->framerate; 665cabdff1aSopenharmony_ci } else if (flv->trust_metadata) { 666cabdff1aSopenharmony_ci if (!strcmp(key, "videocodecid") && vpar) { 667cabdff1aSopenharmony_ci int ret = flv_set_video_codec(s, vstream, num_val, 0); 668cabdff1aSopenharmony_ci if (ret < 0) 669cabdff1aSopenharmony_ci return ret; 670cabdff1aSopenharmony_ci } else if (!strcmp(key, "audiocodecid") && apar) { 671cabdff1aSopenharmony_ci int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET; 672cabdff1aSopenharmony_ci flv_set_audio_codec(s, astream, apar, id); 673cabdff1aSopenharmony_ci } else if (!strcmp(key, "audiosamplerate") && apar) { 674cabdff1aSopenharmony_ci apar->sample_rate = num_val; 675cabdff1aSopenharmony_ci } else if (!strcmp(key, "audiosamplesize") && apar) { 676cabdff1aSopenharmony_ci apar->bits_per_coded_sample = num_val; 677cabdff1aSopenharmony_ci } else if (!strcmp(key, "stereo") && apar) { 678cabdff1aSopenharmony_ci av_channel_layout_default(&apar->ch_layout, num_val + 1); 679cabdff1aSopenharmony_ci } else if (!strcmp(key, "width") && vpar) { 680cabdff1aSopenharmony_ci vpar->width = num_val; 681cabdff1aSopenharmony_ci } else if (!strcmp(key, "height") && vpar) { 682cabdff1aSopenharmony_ci vpar->height = num_val; 683cabdff1aSopenharmony_ci } 684cabdff1aSopenharmony_ci } 685cabdff1aSopenharmony_ci } 686cabdff1aSopenharmony_ci if (amf_type == AMF_DATA_TYPE_STRING) { 687cabdff1aSopenharmony_ci if (!strcmp(key, "encoder")) { 688cabdff1aSopenharmony_ci int version = -1; 689cabdff1aSopenharmony_ci if (1 == sscanf(str_val, "Open Broadcaster Software v0.%d", &version)) { 690cabdff1aSopenharmony_ci if (version > 0 && version <= 655) 691cabdff1aSopenharmony_ci flv->broken_sizes = 1; 692cabdff1aSopenharmony_ci } 693cabdff1aSopenharmony_ci } else if (!strcmp(key, "metadatacreator")) { 694cabdff1aSopenharmony_ci if ( !strcmp (str_val, "MEGA") 695cabdff1aSopenharmony_ci || !strncmp(str_val, "FlixEngine", 10)) 696cabdff1aSopenharmony_ci flv->broken_sizes = 1; 697cabdff1aSopenharmony_ci } 698cabdff1aSopenharmony_ci } 699cabdff1aSopenharmony_ci } 700cabdff1aSopenharmony_ci 701cabdff1aSopenharmony_ci if (amf_type == AMF_DATA_TYPE_OBJECT && s->nb_streams == 1 && 702cabdff1aSopenharmony_ci ((!apar && !strcmp(key, "audiocodecid")) || 703cabdff1aSopenharmony_ci (!vpar && !strcmp(key, "videocodecid")))) 704cabdff1aSopenharmony_ci s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object 705cabdff1aSopenharmony_ci 706cabdff1aSopenharmony_ci if ((!strcmp(key, "duration") || 707cabdff1aSopenharmony_ci !strcmp(key, "filesize") || 708cabdff1aSopenharmony_ci !strcmp(key, "width") || 709cabdff1aSopenharmony_ci !strcmp(key, "height") || 710cabdff1aSopenharmony_ci !strcmp(key, "videodatarate") || 711cabdff1aSopenharmony_ci !strcmp(key, "framerate") || 712cabdff1aSopenharmony_ci !strcmp(key, "videocodecid") || 713cabdff1aSopenharmony_ci !strcmp(key, "audiodatarate") || 714cabdff1aSopenharmony_ci !strcmp(key, "audiosamplerate") || 715cabdff1aSopenharmony_ci !strcmp(key, "audiosamplesize") || 716cabdff1aSopenharmony_ci !strcmp(key, "stereo") || 717cabdff1aSopenharmony_ci !strcmp(key, "audiocodecid") || 718cabdff1aSopenharmony_ci !strcmp(key, "datastream")) && !flv->dump_full_metadata) 719cabdff1aSopenharmony_ci return 0; 720cabdff1aSopenharmony_ci 721cabdff1aSopenharmony_ci s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; 722cabdff1aSopenharmony_ci if (amf_type == AMF_DATA_TYPE_BOOL) { 723cabdff1aSopenharmony_ci av_strlcpy(str_val, num_val > 0 ? "true" : "false", 724cabdff1aSopenharmony_ci sizeof(str_val)); 725cabdff1aSopenharmony_ci av_dict_set(&s->metadata, key, str_val, 0); 726cabdff1aSopenharmony_ci } else if (amf_type == AMF_DATA_TYPE_NUMBER) { 727cabdff1aSopenharmony_ci snprintf(str_val, sizeof(str_val), "%.f", num_val); 728cabdff1aSopenharmony_ci av_dict_set(&s->metadata, key, str_val, 0); 729cabdff1aSopenharmony_ci } else if (amf_type == AMF_DATA_TYPE_STRING) { 730cabdff1aSopenharmony_ci av_dict_set(&s->metadata, key, str_val, 0); 731cabdff1aSopenharmony_ci } else if ( amf_type == AMF_DATA_TYPE_DATE 732cabdff1aSopenharmony_ci && isfinite(date.milliseconds) 733cabdff1aSopenharmony_ci && date.milliseconds > INT64_MIN/1000 734cabdff1aSopenharmony_ci && date.milliseconds < INT64_MAX/1000 735cabdff1aSopenharmony_ci ) { 736cabdff1aSopenharmony_ci // timezone is ignored, since there is no easy way to offset the UTC 737cabdff1aSopenharmony_ci // timestamp into the specified timezone 738cabdff1aSopenharmony_ci avpriv_dict_set_timestamp(&s->metadata, key, 1000 * (int64_t)date.milliseconds); 739cabdff1aSopenharmony_ci } 740cabdff1aSopenharmony_ci } 741cabdff1aSopenharmony_ci 742cabdff1aSopenharmony_ci return 0; 743cabdff1aSopenharmony_ci} 744cabdff1aSopenharmony_ci 745cabdff1aSopenharmony_ci#define TYPE_ONTEXTDATA 1 746cabdff1aSopenharmony_ci#define TYPE_ONCAPTION 2 747cabdff1aSopenharmony_ci#define TYPE_ONCAPTIONINFO 3 748cabdff1aSopenharmony_ci#define TYPE_UNKNOWN 9 749cabdff1aSopenharmony_ci 750cabdff1aSopenharmony_cistatic int flv_read_metabody(AVFormatContext *s, int64_t next_pos) 751cabdff1aSopenharmony_ci{ 752cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 753cabdff1aSopenharmony_ci AMFDataType type; 754cabdff1aSopenharmony_ci AVStream *stream, *astream, *vstream; 755cabdff1aSopenharmony_ci AVStream av_unused *dstream; 756cabdff1aSopenharmony_ci AVIOContext *ioc; 757cabdff1aSopenharmony_ci int i; 758cabdff1aSopenharmony_ci char buffer[32]; 759cabdff1aSopenharmony_ci 760cabdff1aSopenharmony_ci astream = NULL; 761cabdff1aSopenharmony_ci vstream = NULL; 762cabdff1aSopenharmony_ci dstream = NULL; 763cabdff1aSopenharmony_ci ioc = s->pb; 764cabdff1aSopenharmony_ci 765cabdff1aSopenharmony_ci // first object needs to be "onMetaData" string 766cabdff1aSopenharmony_ci type = avio_r8(ioc); 767cabdff1aSopenharmony_ci if (type != AMF_DATA_TYPE_STRING || 768cabdff1aSopenharmony_ci amf_get_string(ioc, buffer, sizeof(buffer)) < 0) 769cabdff1aSopenharmony_ci return TYPE_UNKNOWN; 770cabdff1aSopenharmony_ci 771cabdff1aSopenharmony_ci if (!strcmp(buffer, "onTextData")) 772cabdff1aSopenharmony_ci return TYPE_ONTEXTDATA; 773cabdff1aSopenharmony_ci 774cabdff1aSopenharmony_ci if (!strcmp(buffer, "onCaption")) 775cabdff1aSopenharmony_ci return TYPE_ONCAPTION; 776cabdff1aSopenharmony_ci 777cabdff1aSopenharmony_ci if (!strcmp(buffer, "onCaptionInfo")) 778cabdff1aSopenharmony_ci return TYPE_ONCAPTIONINFO; 779cabdff1aSopenharmony_ci 780cabdff1aSopenharmony_ci if (strcmp(buffer, "onMetaData") && strcmp(buffer, "onCuePoint") && strcmp(buffer, "|RtmpSampleAccess")) { 781cabdff1aSopenharmony_ci av_log(s, AV_LOG_DEBUG, "Unknown type %s\n", buffer); 782cabdff1aSopenharmony_ci return TYPE_UNKNOWN; 783cabdff1aSopenharmony_ci } 784cabdff1aSopenharmony_ci 785cabdff1aSopenharmony_ci // find the streams now so that amf_parse_object doesn't need to do 786cabdff1aSopenharmony_ci // the lookup every time it is called. 787cabdff1aSopenharmony_ci for (i = 0; i < s->nb_streams; i++) { 788cabdff1aSopenharmony_ci stream = s->streams[i]; 789cabdff1aSopenharmony_ci if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { 790cabdff1aSopenharmony_ci vstream = stream; 791cabdff1aSopenharmony_ci flv->last_keyframe_stream_index = i; 792cabdff1aSopenharmony_ci } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { 793cabdff1aSopenharmony_ci astream = stream; 794cabdff1aSopenharmony_ci if (flv->last_keyframe_stream_index == -1) 795cabdff1aSopenharmony_ci flv->last_keyframe_stream_index = i; 796cabdff1aSopenharmony_ci } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) 797cabdff1aSopenharmony_ci dstream = stream; 798cabdff1aSopenharmony_ci } 799cabdff1aSopenharmony_ci 800cabdff1aSopenharmony_ci // parse the second object (we want a mixed array) 801cabdff1aSopenharmony_ci if (amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0) 802cabdff1aSopenharmony_ci return -1; 803cabdff1aSopenharmony_ci 804cabdff1aSopenharmony_ci return 0; 805cabdff1aSopenharmony_ci} 806cabdff1aSopenharmony_ci 807cabdff1aSopenharmony_cistatic int flv_read_header(AVFormatContext *s) 808cabdff1aSopenharmony_ci{ 809cabdff1aSopenharmony_ci int flags; 810cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 811cabdff1aSopenharmony_ci int offset; 812cabdff1aSopenharmony_ci int pre_tag_size = 0; 813cabdff1aSopenharmony_ci 814cabdff1aSopenharmony_ci /* Actual FLV data at 0xe40000 in KUX file */ 815cabdff1aSopenharmony_ci if(!strcmp(s->iformat->name, "kux")) 816cabdff1aSopenharmony_ci avio_skip(s->pb, 0xe40000); 817cabdff1aSopenharmony_ci 818cabdff1aSopenharmony_ci avio_skip(s->pb, 4); 819cabdff1aSopenharmony_ci flags = avio_r8(s->pb); 820cabdff1aSopenharmony_ci 821cabdff1aSopenharmony_ci flv->missing_streams = flags & (FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO); 822cabdff1aSopenharmony_ci 823cabdff1aSopenharmony_ci s->ctx_flags |= AVFMTCTX_NOHEADER; 824cabdff1aSopenharmony_ci 825cabdff1aSopenharmony_ci offset = avio_rb32(s->pb); 826cabdff1aSopenharmony_ci avio_seek(s->pb, offset, SEEK_SET); 827cabdff1aSopenharmony_ci 828cabdff1aSopenharmony_ci /* Annex E. The FLV File Format 829cabdff1aSopenharmony_ci * E.3 TheFLVFileBody 830cabdff1aSopenharmony_ci * Field Type Comment 831cabdff1aSopenharmony_ci * PreviousTagSize0 UI32 Always 0 832cabdff1aSopenharmony_ci * */ 833cabdff1aSopenharmony_ci pre_tag_size = avio_rb32(s->pb); 834cabdff1aSopenharmony_ci if (pre_tag_size) { 835cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, "Read FLV header error, input file is not a standard flv format, first PreviousTagSize0 always is 0\n"); 836cabdff1aSopenharmony_ci } 837cabdff1aSopenharmony_ci 838cabdff1aSopenharmony_ci s->start_time = 0; 839cabdff1aSopenharmony_ci flv->sum_flv_tag_size = 0; 840cabdff1aSopenharmony_ci flv->last_keyframe_stream_index = -1; 841cabdff1aSopenharmony_ci 842cabdff1aSopenharmony_ci return 0; 843cabdff1aSopenharmony_ci} 844cabdff1aSopenharmony_ci 845cabdff1aSopenharmony_cistatic int flv_read_close(AVFormatContext *s) 846cabdff1aSopenharmony_ci{ 847cabdff1aSopenharmony_ci int i; 848cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 849cabdff1aSopenharmony_ci for (i=0; i<FLV_STREAM_TYPE_NB; i++) 850cabdff1aSopenharmony_ci av_freep(&flv->new_extradata[i]); 851cabdff1aSopenharmony_ci av_freep(&flv->keyframe_times); 852cabdff1aSopenharmony_ci av_freep(&flv->keyframe_filepositions); 853cabdff1aSopenharmony_ci return 0; 854cabdff1aSopenharmony_ci} 855cabdff1aSopenharmony_ci 856cabdff1aSopenharmony_cistatic int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) 857cabdff1aSopenharmony_ci{ 858cabdff1aSopenharmony_ci int ret; 859cabdff1aSopenharmony_ci if (!size) 860cabdff1aSopenharmony_ci return 0; 861cabdff1aSopenharmony_ci 862cabdff1aSopenharmony_ci if ((ret = ff_get_extradata(s, st->codecpar, s->pb, size)) < 0) 863cabdff1aSopenharmony_ci return ret; 864cabdff1aSopenharmony_ci ffstream(st)->need_context_update = 1; 865cabdff1aSopenharmony_ci return 0; 866cabdff1aSopenharmony_ci} 867cabdff1aSopenharmony_ci 868cabdff1aSopenharmony_cistatic int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream, 869cabdff1aSopenharmony_ci int size) 870cabdff1aSopenharmony_ci{ 871cabdff1aSopenharmony_ci if (!size) 872cabdff1aSopenharmony_ci return 0; 873cabdff1aSopenharmony_ci 874cabdff1aSopenharmony_ci av_free(flv->new_extradata[stream]); 875cabdff1aSopenharmony_ci flv->new_extradata[stream] = av_mallocz(size + 876cabdff1aSopenharmony_ci AV_INPUT_BUFFER_PADDING_SIZE); 877cabdff1aSopenharmony_ci if (!flv->new_extradata[stream]) 878cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 879cabdff1aSopenharmony_ci flv->new_extradata_size[stream] = size; 880cabdff1aSopenharmony_ci avio_read(pb, flv->new_extradata[stream], size); 881cabdff1aSopenharmony_ci return 0; 882cabdff1aSopenharmony_ci} 883cabdff1aSopenharmony_ci 884cabdff1aSopenharmony_cistatic void clear_index_entries(AVFormatContext *s, int64_t pos) 885cabdff1aSopenharmony_ci{ 886cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, 887cabdff1aSopenharmony_ci "Found invalid index entries, clearing the index.\n"); 888cabdff1aSopenharmony_ci for (unsigned i = 0; i < s->nb_streams; i++) { 889cabdff1aSopenharmony_ci FFStream *const sti = ffstream(s->streams[i]); 890cabdff1aSopenharmony_ci int out = 0; 891cabdff1aSopenharmony_ci /* Remove all index entries that point to >= pos */ 892cabdff1aSopenharmony_ci for (int j = 0; j < sti->nb_index_entries; j++) 893cabdff1aSopenharmony_ci if (sti->index_entries[j].pos < pos) 894cabdff1aSopenharmony_ci sti->index_entries[out++] = sti->index_entries[j]; 895cabdff1aSopenharmony_ci sti->nb_index_entries = out; 896cabdff1aSopenharmony_ci } 897cabdff1aSopenharmony_ci} 898cabdff1aSopenharmony_ci 899cabdff1aSopenharmony_cistatic int amf_skip_tag(AVIOContext *pb, AMFDataType type, int depth) 900cabdff1aSopenharmony_ci{ 901cabdff1aSopenharmony_ci int nb = -1, ret, parse_name = 1; 902cabdff1aSopenharmony_ci 903cabdff1aSopenharmony_ci if (depth > MAX_DEPTH) 904cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 905cabdff1aSopenharmony_ci 906cabdff1aSopenharmony_ci if (avio_feof(pb)) 907cabdff1aSopenharmony_ci return AVERROR_EOF; 908cabdff1aSopenharmony_ci 909cabdff1aSopenharmony_ci switch (type) { 910cabdff1aSopenharmony_ci case AMF_DATA_TYPE_NUMBER: 911cabdff1aSopenharmony_ci avio_skip(pb, 8); 912cabdff1aSopenharmony_ci break; 913cabdff1aSopenharmony_ci case AMF_DATA_TYPE_BOOL: 914cabdff1aSopenharmony_ci avio_skip(pb, 1); 915cabdff1aSopenharmony_ci break; 916cabdff1aSopenharmony_ci case AMF_DATA_TYPE_STRING: 917cabdff1aSopenharmony_ci avio_skip(pb, avio_rb16(pb)); 918cabdff1aSopenharmony_ci break; 919cabdff1aSopenharmony_ci case AMF_DATA_TYPE_ARRAY: 920cabdff1aSopenharmony_ci parse_name = 0; 921cabdff1aSopenharmony_ci case AMF_DATA_TYPE_MIXEDARRAY: 922cabdff1aSopenharmony_ci nb = avio_rb32(pb); 923cabdff1aSopenharmony_ci if (nb < 0) 924cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 925cabdff1aSopenharmony_ci case AMF_DATA_TYPE_OBJECT: 926cabdff1aSopenharmony_ci while(!pb->eof_reached && (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY)) { 927cabdff1aSopenharmony_ci if (parse_name) { 928cabdff1aSopenharmony_ci int size = avio_rb16(pb); 929cabdff1aSopenharmony_ci if (!size) { 930cabdff1aSopenharmony_ci avio_skip(pb, 1); 931cabdff1aSopenharmony_ci break; 932cabdff1aSopenharmony_ci } 933cabdff1aSopenharmony_ci avio_skip(pb, size); 934cabdff1aSopenharmony_ci } 935cabdff1aSopenharmony_ci if ((ret = amf_skip_tag(pb, avio_r8(pb), depth + 1)) < 0) 936cabdff1aSopenharmony_ci return ret; 937cabdff1aSopenharmony_ci } 938cabdff1aSopenharmony_ci break; 939cabdff1aSopenharmony_ci case AMF_DATA_TYPE_NULL: 940cabdff1aSopenharmony_ci case AMF_DATA_TYPE_OBJECT_END: 941cabdff1aSopenharmony_ci break; 942cabdff1aSopenharmony_ci default: 943cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 944cabdff1aSopenharmony_ci } 945cabdff1aSopenharmony_ci return 0; 946cabdff1aSopenharmony_ci} 947cabdff1aSopenharmony_ci 948cabdff1aSopenharmony_cistatic int flv_data_packet(AVFormatContext *s, AVPacket *pkt, 949cabdff1aSopenharmony_ci int64_t dts, int64_t next) 950cabdff1aSopenharmony_ci{ 951cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 952cabdff1aSopenharmony_ci AVStream *st = NULL; 953cabdff1aSopenharmony_ci char buf[20]; 954cabdff1aSopenharmony_ci int ret = AVERROR_INVALIDDATA; 955cabdff1aSopenharmony_ci int i, length = -1; 956cabdff1aSopenharmony_ci int array = 0; 957cabdff1aSopenharmony_ci 958cabdff1aSopenharmony_ci switch (avio_r8(pb)) { 959cabdff1aSopenharmony_ci case AMF_DATA_TYPE_ARRAY: 960cabdff1aSopenharmony_ci array = 1; 961cabdff1aSopenharmony_ci case AMF_DATA_TYPE_MIXEDARRAY: 962cabdff1aSopenharmony_ci avio_seek(pb, 4, SEEK_CUR); 963cabdff1aSopenharmony_ci case AMF_DATA_TYPE_OBJECT: 964cabdff1aSopenharmony_ci break; 965cabdff1aSopenharmony_ci default: 966cabdff1aSopenharmony_ci goto skip; 967cabdff1aSopenharmony_ci } 968cabdff1aSopenharmony_ci 969cabdff1aSopenharmony_ci while (array || (ret = amf_get_string(pb, buf, sizeof(buf))) > 0) { 970cabdff1aSopenharmony_ci AMFDataType type = avio_r8(pb); 971cabdff1aSopenharmony_ci if (type == AMF_DATA_TYPE_STRING && (array || !strcmp(buf, "text"))) { 972cabdff1aSopenharmony_ci length = avio_rb16(pb); 973cabdff1aSopenharmony_ci ret = av_get_packet(pb, pkt, length); 974cabdff1aSopenharmony_ci if (ret < 0) 975cabdff1aSopenharmony_ci goto skip; 976cabdff1aSopenharmony_ci else 977cabdff1aSopenharmony_ci break; 978cabdff1aSopenharmony_ci } else { 979cabdff1aSopenharmony_ci if ((ret = amf_skip_tag(pb, type, 0)) < 0) 980cabdff1aSopenharmony_ci goto skip; 981cabdff1aSopenharmony_ci } 982cabdff1aSopenharmony_ci } 983cabdff1aSopenharmony_ci 984cabdff1aSopenharmony_ci if (length < 0) { 985cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 986cabdff1aSopenharmony_ci goto skip; 987cabdff1aSopenharmony_ci } 988cabdff1aSopenharmony_ci 989cabdff1aSopenharmony_ci for (i = 0; i < s->nb_streams; i++) { 990cabdff1aSopenharmony_ci st = s->streams[i]; 991cabdff1aSopenharmony_ci if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) 992cabdff1aSopenharmony_ci break; 993cabdff1aSopenharmony_ci } 994cabdff1aSopenharmony_ci 995cabdff1aSopenharmony_ci if (i == s->nb_streams) { 996cabdff1aSopenharmony_ci st = create_stream(s, AVMEDIA_TYPE_SUBTITLE); 997cabdff1aSopenharmony_ci if (!st) 998cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 999cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_TEXT; 1000cabdff1aSopenharmony_ci } 1001cabdff1aSopenharmony_ci 1002cabdff1aSopenharmony_ci pkt->dts = dts; 1003cabdff1aSopenharmony_ci pkt->pts = dts; 1004cabdff1aSopenharmony_ci pkt->size = ret; 1005cabdff1aSopenharmony_ci 1006cabdff1aSopenharmony_ci pkt->stream_index = st->index; 1007cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 1008cabdff1aSopenharmony_ci 1009cabdff1aSopenharmony_ciskip: 1010cabdff1aSopenharmony_ci avio_seek(s->pb, next + 4, SEEK_SET); 1011cabdff1aSopenharmony_ci 1012cabdff1aSopenharmony_ci return ret; 1013cabdff1aSopenharmony_ci} 1014cabdff1aSopenharmony_ci 1015cabdff1aSopenharmony_cistatic int resync(AVFormatContext *s) 1016cabdff1aSopenharmony_ci{ 1017cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 1018cabdff1aSopenharmony_ci int64_t i; 1019cabdff1aSopenharmony_ci int64_t pos = avio_tell(s->pb); 1020cabdff1aSopenharmony_ci 1021cabdff1aSopenharmony_ci for (i=0; !avio_feof(s->pb); i++) { 1022cabdff1aSopenharmony_ci int j = i & (RESYNC_BUFFER_SIZE-1); 1023cabdff1aSopenharmony_ci int j1 = j + RESYNC_BUFFER_SIZE; 1024cabdff1aSopenharmony_ci flv->resync_buffer[j ] = 1025cabdff1aSopenharmony_ci flv->resync_buffer[j1] = avio_r8(s->pb); 1026cabdff1aSopenharmony_ci 1027cabdff1aSopenharmony_ci if (i >= 8 && pos) { 1028cabdff1aSopenharmony_ci uint8_t *d = flv->resync_buffer + j1 - 8; 1029cabdff1aSopenharmony_ci if (d[0] == 'F' && 1030cabdff1aSopenharmony_ci d[1] == 'L' && 1031cabdff1aSopenharmony_ci d[2] == 'V' && 1032cabdff1aSopenharmony_ci d[3] < 5 && d[5] == 0) { 1033cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, "Concatenated FLV detected, might fail to demux, decode and seek %"PRId64"\n", flv->last_ts); 1034cabdff1aSopenharmony_ci flv->time_offset = flv->last_ts + 1; 1035cabdff1aSopenharmony_ci flv->time_pos = avio_tell(s->pb); 1036cabdff1aSopenharmony_ci } 1037cabdff1aSopenharmony_ci } 1038cabdff1aSopenharmony_ci 1039cabdff1aSopenharmony_ci if (i > 22) { 1040cabdff1aSopenharmony_ci unsigned lsize2 = AV_RB32(flv->resync_buffer + j1 - 4); 1041cabdff1aSopenharmony_ci if (lsize2 >= 11 && lsize2 + 8LL < FFMIN(i, RESYNC_BUFFER_SIZE)) { 1042cabdff1aSopenharmony_ci unsigned size2 = AV_RB24(flv->resync_buffer + j1 - lsize2 + 1 - 4); 1043cabdff1aSopenharmony_ci unsigned lsize1 = AV_RB32(flv->resync_buffer + j1 - lsize2 - 8); 1044cabdff1aSopenharmony_ci if (lsize1 >= 11 && lsize1 + 8LL + lsize2 < FFMIN(i, RESYNC_BUFFER_SIZE)) { 1045cabdff1aSopenharmony_ci unsigned size1 = AV_RB24(flv->resync_buffer + j1 - lsize1 + 1 - lsize2 - 8); 1046cabdff1aSopenharmony_ci if (size1 == lsize1 - 11 && size2 == lsize2 - 11) { 1047cabdff1aSopenharmony_ci avio_seek(s->pb, pos + i - lsize1 - lsize2 - 8, SEEK_SET); 1048cabdff1aSopenharmony_ci return 1; 1049cabdff1aSopenharmony_ci } 1050cabdff1aSopenharmony_ci } 1051cabdff1aSopenharmony_ci } 1052cabdff1aSopenharmony_ci } 1053cabdff1aSopenharmony_ci } 1054cabdff1aSopenharmony_ci return AVERROR_EOF; 1055cabdff1aSopenharmony_ci} 1056cabdff1aSopenharmony_ci 1057cabdff1aSopenharmony_cistatic int flv_read_packet(AVFormatContext *s, AVPacket *pkt) 1058cabdff1aSopenharmony_ci{ 1059cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 1060cabdff1aSopenharmony_ci int ret, i, size, flags; 1061cabdff1aSopenharmony_ci enum FlvTagType type; 1062cabdff1aSopenharmony_ci int stream_type=-1; 1063cabdff1aSopenharmony_ci int64_t next, pos, meta_pos; 1064cabdff1aSopenharmony_ci int64_t dts, pts = AV_NOPTS_VALUE; 1065cabdff1aSopenharmony_ci int av_uninit(channels); 1066cabdff1aSopenharmony_ci int av_uninit(sample_rate); 1067cabdff1aSopenharmony_ci AVStream *st = NULL; 1068cabdff1aSopenharmony_ci int last = -1; 1069cabdff1aSopenharmony_ci int orig_size; 1070cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 1071cabdff1aSopenharmony_ci uint32_t video_codec_id = 0; 1072cabdff1aSopenharmony_ci int enhanced_flv = 0; 1073cabdff1aSopenharmony_ci#endif 1074cabdff1aSopenharmony_ci 1075cabdff1aSopenharmony_ciretry: 1076cabdff1aSopenharmony_ci /* pkt size is repeated at end. skip it */ 1077cabdff1aSopenharmony_ci pos = avio_tell(s->pb); 1078cabdff1aSopenharmony_ci type = (avio_r8(s->pb) & 0x1F); 1079cabdff1aSopenharmony_ci orig_size = 1080cabdff1aSopenharmony_ci size = avio_rb24(s->pb); 1081cabdff1aSopenharmony_ci flv->sum_flv_tag_size += size + 11LL; 1082cabdff1aSopenharmony_ci dts = avio_rb24(s->pb); 1083cabdff1aSopenharmony_ci dts |= (unsigned)avio_r8(s->pb) << 24; 1084cabdff1aSopenharmony_ci av_log(s, AV_LOG_TRACE, "type:%d, size:%d, last:%d, dts:%"PRId64" pos:%"PRId64"\n", type, size, last, dts, avio_tell(s->pb)); 1085cabdff1aSopenharmony_ci if (avio_feof(s->pb)) 1086cabdff1aSopenharmony_ci return AVERROR_EOF; 1087cabdff1aSopenharmony_ci avio_skip(s->pb, 3); /* stream id, always 0 */ 1088cabdff1aSopenharmony_ci flags = 0; 1089cabdff1aSopenharmony_ci 1090cabdff1aSopenharmony_ci if (flv->validate_next < flv->validate_count) { 1091cabdff1aSopenharmony_ci int64_t validate_pos = flv->validate_index[flv->validate_next].pos; 1092cabdff1aSopenharmony_ci if (pos == validate_pos) { 1093cabdff1aSopenharmony_ci if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <= 1094cabdff1aSopenharmony_ci VALIDATE_INDEX_TS_THRESH) { 1095cabdff1aSopenharmony_ci flv->validate_next++; 1096cabdff1aSopenharmony_ci } else { 1097cabdff1aSopenharmony_ci clear_index_entries(s, validate_pos); 1098cabdff1aSopenharmony_ci flv->validate_count = 0; 1099cabdff1aSopenharmony_ci } 1100cabdff1aSopenharmony_ci } else if (pos > validate_pos) { 1101cabdff1aSopenharmony_ci clear_index_entries(s, validate_pos); 1102cabdff1aSopenharmony_ci flv->validate_count = 0; 1103cabdff1aSopenharmony_ci } 1104cabdff1aSopenharmony_ci } 1105cabdff1aSopenharmony_ci 1106cabdff1aSopenharmony_ci if (size == 0) { 1107cabdff1aSopenharmony_ci ret = FFERROR_REDO; 1108cabdff1aSopenharmony_ci goto leave; 1109cabdff1aSopenharmony_ci } 1110cabdff1aSopenharmony_ci 1111cabdff1aSopenharmony_ci next = size + avio_tell(s->pb); 1112cabdff1aSopenharmony_ci 1113cabdff1aSopenharmony_ci if (type == FLV_TAG_TYPE_AUDIO) { 1114cabdff1aSopenharmony_ci stream_type = FLV_STREAM_TYPE_AUDIO; 1115cabdff1aSopenharmony_ci flags = avio_r8(s->pb); 1116cabdff1aSopenharmony_ci size--; 1117cabdff1aSopenharmony_ci } else if (type == FLV_TAG_TYPE_VIDEO) { 1118cabdff1aSopenharmony_ci stream_type = FLV_STREAM_TYPE_VIDEO; 1119cabdff1aSopenharmony_ci flags = avio_r8(s->pb); 1120cabdff1aSopenharmony_ci size--; 1121cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 1122cabdff1aSopenharmony_ci video_codec_id = flags & FLV_VIDEO_CODECID_MASK; 1123cabdff1aSopenharmony_ci enhanced_flv = (flags >> 7) & 1; 1124cabdff1aSopenharmony_ci if (enhanced_flv) { 1125cabdff1aSopenharmony_ci video_codec_id = avio_rb32(s->pb); 1126cabdff1aSopenharmony_ci size -= 4; 1127cabdff1aSopenharmony_ci } 1128cabdff1aSopenharmony_ci#endif 1129cabdff1aSopenharmony_ci if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) 1130cabdff1aSopenharmony_ci goto skip; 1131cabdff1aSopenharmony_ci } else if (type == FLV_TAG_TYPE_META) { 1132cabdff1aSopenharmony_ci stream_type=FLV_STREAM_TYPE_SUBTITLE; 1133cabdff1aSopenharmony_ci if (size > 13 + 1 + 4) { // Header-type metadata stuff 1134cabdff1aSopenharmony_ci int type; 1135cabdff1aSopenharmony_ci meta_pos = avio_tell(s->pb); 1136cabdff1aSopenharmony_ci type = flv_read_metabody(s, next); 1137cabdff1aSopenharmony_ci if (type == 0 && dts == 0 || type < 0) { 1138cabdff1aSopenharmony_ci if (type < 0 && flv->validate_count && 1139cabdff1aSopenharmony_ci flv->validate_index[0].pos > next && 1140cabdff1aSopenharmony_ci flv->validate_index[0].pos - 4 < next) { 1141cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, "Adjusting next position due to index mismatch\n"); 1142cabdff1aSopenharmony_ci next = flv->validate_index[0].pos - 4; 1143cabdff1aSopenharmony_ci } 1144cabdff1aSopenharmony_ci goto skip; 1145cabdff1aSopenharmony_ci } else if (type == TYPE_ONTEXTDATA) { 1146cabdff1aSopenharmony_ci avpriv_request_sample(s, "OnTextData packet"); 1147cabdff1aSopenharmony_ci return flv_data_packet(s, pkt, dts, next); 1148cabdff1aSopenharmony_ci } else if (type == TYPE_ONCAPTION) { 1149cabdff1aSopenharmony_ci return flv_data_packet(s, pkt, dts, next); 1150cabdff1aSopenharmony_ci } else if (type == TYPE_UNKNOWN) { 1151cabdff1aSopenharmony_ci stream_type = FLV_STREAM_TYPE_DATA; 1152cabdff1aSopenharmony_ci } 1153cabdff1aSopenharmony_ci avio_seek(s->pb, meta_pos, SEEK_SET); 1154cabdff1aSopenharmony_ci } 1155cabdff1aSopenharmony_ci } else { 1156cabdff1aSopenharmony_ci av_log(s, AV_LOG_DEBUG, 1157cabdff1aSopenharmony_ci "Skipping flv packet: type %d, size %d, flags %d.\n", 1158cabdff1aSopenharmony_ci type, size, flags); 1159cabdff1aSopenharmony_ciskip: 1160cabdff1aSopenharmony_ci if (avio_seek(s->pb, next, SEEK_SET) != next) { 1161cabdff1aSopenharmony_ci // This can happen if flv_read_metabody above read past 1162cabdff1aSopenharmony_ci // next, on a non-seekable input, and the preceding data has 1163cabdff1aSopenharmony_ci // been flushed out from the IO buffer. 1164cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Unable to seek to the next packet\n"); 1165cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1166cabdff1aSopenharmony_ci } 1167cabdff1aSopenharmony_ci ret = FFERROR_REDO; 1168cabdff1aSopenharmony_ci goto leave; 1169cabdff1aSopenharmony_ci } 1170cabdff1aSopenharmony_ci 1171cabdff1aSopenharmony_ci /* skip empty data packets */ 1172cabdff1aSopenharmony_ci if (!size) { 1173cabdff1aSopenharmony_ci ret = FFERROR_REDO; 1174cabdff1aSopenharmony_ci goto leave; 1175cabdff1aSopenharmony_ci } 1176cabdff1aSopenharmony_ci 1177cabdff1aSopenharmony_ci /* now find stream */ 1178cabdff1aSopenharmony_ci for (i = 0; i < s->nb_streams; i++) { 1179cabdff1aSopenharmony_ci st = s->streams[i]; 1180cabdff1aSopenharmony_ci if (stream_type == FLV_STREAM_TYPE_AUDIO) { 1181cabdff1aSopenharmony_ci if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && 1182cabdff1aSopenharmony_ci (s->audio_codec_id || flv_same_audio_codec(st->codecpar, flags))) 1183cabdff1aSopenharmony_ci break; 1184cabdff1aSopenharmony_ci } else if (stream_type == FLV_STREAM_TYPE_VIDEO) { 1185cabdff1aSopenharmony_ci if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && 1186cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 1187cabdff1aSopenharmony_ci (s->video_codec_id || flv_same_video_codec(st->codecpar, video_codec_id)) 1188cabdff1aSopenharmony_ci#else 1189cabdff1aSopenharmony_ci (s->video_codec_id || flv_same_video_codec(st->codecpar, flags)) 1190cabdff1aSopenharmony_ci#endif 1191cabdff1aSopenharmony_ci ) 1192cabdff1aSopenharmony_ci break; 1193cabdff1aSopenharmony_ci } else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) { 1194cabdff1aSopenharmony_ci if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) 1195cabdff1aSopenharmony_ci break; 1196cabdff1aSopenharmony_ci } else if (stream_type == FLV_STREAM_TYPE_DATA) { 1197cabdff1aSopenharmony_ci if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) 1198cabdff1aSopenharmony_ci break; 1199cabdff1aSopenharmony_ci } 1200cabdff1aSopenharmony_ci } 1201cabdff1aSopenharmony_ci if (i == s->nb_streams) { 1202cabdff1aSopenharmony_ci static const enum AVMediaType stream_types[] = {AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_SUBTITLE, AVMEDIA_TYPE_DATA}; 1203cabdff1aSopenharmony_ci st = create_stream(s, stream_types[stream_type]); 1204cabdff1aSopenharmony_ci if (!st) 1205cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1206cabdff1aSopenharmony_ci } 1207cabdff1aSopenharmony_ci av_log(s, AV_LOG_TRACE, "%d %X %d \n", stream_type, flags, st->discard); 1208cabdff1aSopenharmony_ci 1209cabdff1aSopenharmony_ci if (flv->time_pos <= pos) { 1210cabdff1aSopenharmony_ci dts += flv->time_offset; 1211cabdff1aSopenharmony_ci } 1212cabdff1aSopenharmony_ci 1213cabdff1aSopenharmony_ci if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && 1214cabdff1aSopenharmony_ci ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || 1215cabdff1aSopenharmony_ci stream_type == FLV_STREAM_TYPE_AUDIO)) 1216cabdff1aSopenharmony_ci av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); 1217cabdff1aSopenharmony_ci 1218cabdff1aSopenharmony_ci if ((st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)) || 1219cabdff1aSopenharmony_ci (st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && stream_type == FLV_STREAM_TYPE_VIDEO)) || 1220cabdff1aSopenharmony_ci st->discard >= AVDISCARD_ALL) { 1221cabdff1aSopenharmony_ci avio_seek(s->pb, next, SEEK_SET); 1222cabdff1aSopenharmony_ci ret = FFERROR_REDO; 1223cabdff1aSopenharmony_ci goto leave; 1224cabdff1aSopenharmony_ci } 1225cabdff1aSopenharmony_ci 1226cabdff1aSopenharmony_ci // if not streamed and no duration from metadata then seek to end to find 1227cabdff1aSopenharmony_ci // the duration from the timestamps 1228cabdff1aSopenharmony_ci if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && 1229cabdff1aSopenharmony_ci (!s->duration || s->duration == AV_NOPTS_VALUE) && 1230cabdff1aSopenharmony_ci !flv->searched_for_end) { 1231cabdff1aSopenharmony_ci int size; 1232cabdff1aSopenharmony_ci const int64_t pos = avio_tell(s->pb); 1233cabdff1aSopenharmony_ci // Read the last 4 bytes of the file, this should be the size of the 1234cabdff1aSopenharmony_ci // previous FLV tag. Use the timestamp of its payload as duration. 1235cabdff1aSopenharmony_ci int64_t fsize = avio_size(s->pb); 1236cabdff1aSopenharmony_ciretry_duration: 1237cabdff1aSopenharmony_ci avio_seek(s->pb, fsize - 4, SEEK_SET); 1238cabdff1aSopenharmony_ci size = avio_rb32(s->pb); 1239cabdff1aSopenharmony_ci if (size > 0 && size < fsize) { 1240cabdff1aSopenharmony_ci // Seek to the start of the last FLV tag at position (fsize - 4 - size) 1241cabdff1aSopenharmony_ci // but skip the byte indicating the type. 1242cabdff1aSopenharmony_ci avio_seek(s->pb, fsize - 3 - size, SEEK_SET); 1243cabdff1aSopenharmony_ci if (size == avio_rb24(s->pb) + 11) { 1244cabdff1aSopenharmony_ci uint32_t ts = avio_rb24(s->pb); 1245cabdff1aSopenharmony_ci ts |= (unsigned)avio_r8(s->pb) << 24; 1246cabdff1aSopenharmony_ci if (ts) 1247cabdff1aSopenharmony_ci s->duration = ts * (int64_t)AV_TIME_BASE / 1000; 1248cabdff1aSopenharmony_ci else if (fsize >= 8 && fsize - 8 >= size) { 1249cabdff1aSopenharmony_ci fsize -= size+4; 1250cabdff1aSopenharmony_ci goto retry_duration; 1251cabdff1aSopenharmony_ci } 1252cabdff1aSopenharmony_ci } 1253cabdff1aSopenharmony_ci } 1254cabdff1aSopenharmony_ci 1255cabdff1aSopenharmony_ci avio_seek(s->pb, pos, SEEK_SET); 1256cabdff1aSopenharmony_ci flv->searched_for_end = 1; 1257cabdff1aSopenharmony_ci } 1258cabdff1aSopenharmony_ci 1259cabdff1aSopenharmony_ci if (stream_type == FLV_STREAM_TYPE_AUDIO) { 1260cabdff1aSopenharmony_ci int bits_per_coded_sample; 1261cabdff1aSopenharmony_ci channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1; 1262cabdff1aSopenharmony_ci sample_rate = 44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> 1263cabdff1aSopenharmony_ci FLV_AUDIO_SAMPLERATE_OFFSET) >> 3; 1264cabdff1aSopenharmony_ci bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8; 1265cabdff1aSopenharmony_ci if (!av_channel_layout_check(&st->codecpar->ch_layout) || 1266cabdff1aSopenharmony_ci !st->codecpar->sample_rate || 1267cabdff1aSopenharmony_ci !st->codecpar->bits_per_coded_sample) { 1268cabdff1aSopenharmony_ci av_channel_layout_default(&st->codecpar->ch_layout, channels); 1269cabdff1aSopenharmony_ci st->codecpar->sample_rate = sample_rate; 1270cabdff1aSopenharmony_ci st->codecpar->bits_per_coded_sample = bits_per_coded_sample; 1271cabdff1aSopenharmony_ci } 1272cabdff1aSopenharmony_ci if (!st->codecpar->codec_id) { 1273cabdff1aSopenharmony_ci flv_set_audio_codec(s, st, st->codecpar, 1274cabdff1aSopenharmony_ci flags & FLV_AUDIO_CODECID_MASK); 1275cabdff1aSopenharmony_ci flv->last_sample_rate = 1276cabdff1aSopenharmony_ci sample_rate = st->codecpar->sample_rate; 1277cabdff1aSopenharmony_ci flv->last_channels = 1278cabdff1aSopenharmony_ci channels = st->codecpar->ch_layout.nb_channels; 1279cabdff1aSopenharmony_ci } else { 1280cabdff1aSopenharmony_ci AVCodecParameters *par = avcodec_parameters_alloc(); 1281cabdff1aSopenharmony_ci if (!par) { 1282cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 1283cabdff1aSopenharmony_ci goto leave; 1284cabdff1aSopenharmony_ci } 1285cabdff1aSopenharmony_ci par->sample_rate = sample_rate; 1286cabdff1aSopenharmony_ci par->bits_per_coded_sample = bits_per_coded_sample; 1287cabdff1aSopenharmony_ci flv_set_audio_codec(s, st, par, flags & FLV_AUDIO_CODECID_MASK); 1288cabdff1aSopenharmony_ci sample_rate = par->sample_rate; 1289cabdff1aSopenharmony_ci avcodec_parameters_free(&par); 1290cabdff1aSopenharmony_ci } 1291cabdff1aSopenharmony_ci } else if (stream_type == FLV_STREAM_TYPE_VIDEO) { 1292cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 1293cabdff1aSopenharmony_ci int ret = flv_set_video_codec(s, st, video_codec_id, 1); 1294cabdff1aSopenharmony_ci#else 1295cabdff1aSopenharmony_ci int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1); 1296cabdff1aSopenharmony_ci#endif 1297cabdff1aSopenharmony_ci if (ret < 0) 1298cabdff1aSopenharmony_ci return ret; 1299cabdff1aSopenharmony_ci size -= ret; 1300cabdff1aSopenharmony_ci } else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) { 1301cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_TEXT; 1302cabdff1aSopenharmony_ci } else if (stream_type == FLV_STREAM_TYPE_DATA) { 1303cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_NONE; // Opaque AMF data 1304cabdff1aSopenharmony_ci } 1305cabdff1aSopenharmony_ci 1306cabdff1aSopenharmony_ci if (st->codecpar->codec_id == AV_CODEC_ID_AAC || 1307cabdff1aSopenharmony_ci st->codecpar->codec_id == AV_CODEC_ID_H264 || 1308cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 1309cabdff1aSopenharmony_ci st->codecpar->codec_id == AV_CODEC_ID_MPEG4 || 1310cabdff1aSopenharmony_ci st->codecpar->codec_id == AV_CODEC_ID_HEVC) { 1311cabdff1aSopenharmony_ci int type = 0; 1312cabdff1aSopenharmony_ci if (enhanced_flv && stream_type == FLV_STREAM_TYPE_VIDEO) { 1313cabdff1aSopenharmony_ci type = flags & 0x0F; 1314cabdff1aSopenharmony_ci } else { 1315cabdff1aSopenharmony_ci type = avio_r8(s->pb); 1316cabdff1aSopenharmony_ci size--; 1317cabdff1aSopenharmony_ci } 1318cabdff1aSopenharmony_ci#else 1319cabdff1aSopenharmony_ci st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { 1320cabdff1aSopenharmony_ci int type = avio_r8(s->pb); 1321cabdff1aSopenharmony_ci size--; 1322cabdff1aSopenharmony_ci#endif 1323cabdff1aSopenharmony_ci if (size < 0) { 1324cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 1325cabdff1aSopenharmony_ci goto leave; 1326cabdff1aSopenharmony_ci } 1327cabdff1aSopenharmony_ci 1328cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 1329cabdff1aSopenharmony_ci if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4 || 1330cabdff1aSopenharmony_ci (enhanced_flv && st->codecpar->codec_id == AV_CODEC_ID_HEVC && type == PacketTypeCodedFrames) || 1331cabdff1aSopenharmony_ci video_codec_id == FLV_CODECID_HEVC) { 1332cabdff1aSopenharmony_ci#else 1333cabdff1aSopenharmony_ci if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { 1334cabdff1aSopenharmony_ci#endif 1335cabdff1aSopenharmony_ci // sign extension 1336cabdff1aSopenharmony_ci int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000; 1337cabdff1aSopenharmony_ci pts = av_sat_add64(dts, cts); 1338cabdff1aSopenharmony_ci if (cts < 0) { // dts might be wrong 1339cabdff1aSopenharmony_ci if (!flv->wrong_dts) 1340cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, 1341cabdff1aSopenharmony_ci "Negative cts, previous timestamps might be wrong.\n"); 1342cabdff1aSopenharmony_ci flv->wrong_dts = 1; 1343cabdff1aSopenharmony_ci } else if (FFABS(dts - pts) > 1000*60*15) { 1344cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, 1345cabdff1aSopenharmony_ci "invalid timestamps %"PRId64" %"PRId64"\n", dts, pts); 1346cabdff1aSopenharmony_ci dts = pts = AV_NOPTS_VALUE; 1347cabdff1aSopenharmony_ci } 1348cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 1349cabdff1aSopenharmony_ci size -= 3; 1350cabdff1aSopenharmony_ci#endif 1351cabdff1aSopenharmony_ci } 1352cabdff1aSopenharmony_ci if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC || 1353cabdff1aSopenharmony_ci#ifdef OHOS_H265_DEMUXER 1354cabdff1aSopenharmony_ci st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) { 1355cabdff1aSopenharmony_ci#else 1356cabdff1aSopenharmony_ci st->codecpar->codec_id == AV_CODEC_ID_H264)) { 1357cabdff1aSopenharmony_ci#endif 1358cabdff1aSopenharmony_ci AVDictionaryEntry *t; 1359cabdff1aSopenharmony_ci 1360cabdff1aSopenharmony_ci if (st->codecpar->extradata) { 1361cabdff1aSopenharmony_ci if ((ret = flv_queue_extradata(flv, s->pb, stream_type, size)) < 0) 1362cabdff1aSopenharmony_ci return ret; 1363cabdff1aSopenharmony_ci ret = FFERROR_REDO; 1364cabdff1aSopenharmony_ci goto leave; 1365cabdff1aSopenharmony_ci } 1366cabdff1aSopenharmony_ci if ((ret = flv_get_extradata(s, st, size)) < 0) 1367cabdff1aSopenharmony_ci return ret; 1368cabdff1aSopenharmony_ci 1369cabdff1aSopenharmony_ci /* Workaround for buggy Omnia A/XE encoder */ 1370cabdff1aSopenharmony_ci t = av_dict_get(s->metadata, "Encoder", NULL, 0); 1371cabdff1aSopenharmony_ci if (st->codecpar->codec_id == AV_CODEC_ID_AAC && t && !strcmp(t->value, "Omnia A/XE")) 1372cabdff1aSopenharmony_ci st->codecpar->extradata_size = 2; 1373cabdff1aSopenharmony_ci 1374cabdff1aSopenharmony_ci ret = FFERROR_REDO; 1375cabdff1aSopenharmony_ci goto leave; 1376cabdff1aSopenharmony_ci } 1377cabdff1aSopenharmony_ci } 1378cabdff1aSopenharmony_ci 1379cabdff1aSopenharmony_ci /* skip empty data packets */ 1380cabdff1aSopenharmony_ci if (!size) { 1381cabdff1aSopenharmony_ci ret = FFERROR_REDO; 1382cabdff1aSopenharmony_ci goto leave; 1383cabdff1aSopenharmony_ci } 1384cabdff1aSopenharmony_ci 1385cabdff1aSopenharmony_ci ret = av_get_packet(s->pb, pkt, size); 1386cabdff1aSopenharmony_ci if (ret < 0) 1387cabdff1aSopenharmony_ci return ret; 1388cabdff1aSopenharmony_ci pkt->dts = dts; 1389cabdff1aSopenharmony_ci pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts; 1390cabdff1aSopenharmony_ci pkt->stream_index = st->index; 1391cabdff1aSopenharmony_ci pkt->pos = pos; 1392cabdff1aSopenharmony_ci if (flv->new_extradata[stream_type]) { 1393cabdff1aSopenharmony_ci int ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, 1394cabdff1aSopenharmony_ci flv->new_extradata[stream_type], 1395cabdff1aSopenharmony_ci flv->new_extradata_size[stream_type]); 1396cabdff1aSopenharmony_ci if (ret >= 0) { 1397cabdff1aSopenharmony_ci flv->new_extradata[stream_type] = NULL; 1398cabdff1aSopenharmony_ci flv->new_extradata_size[stream_type] = 0; 1399cabdff1aSopenharmony_ci } 1400cabdff1aSopenharmony_ci } 1401cabdff1aSopenharmony_ci if (stream_type == FLV_STREAM_TYPE_AUDIO && 1402cabdff1aSopenharmony_ci (sample_rate != flv->last_sample_rate || 1403cabdff1aSopenharmony_ci channels != flv->last_channels)) { 1404cabdff1aSopenharmony_ci flv->last_sample_rate = sample_rate; 1405cabdff1aSopenharmony_ci flv->last_channels = channels; 1406cabdff1aSopenharmony_ci ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0); 1407cabdff1aSopenharmony_ci } 1408cabdff1aSopenharmony_ci 1409cabdff1aSopenharmony_ci if (stream_type == FLV_STREAM_TYPE_AUDIO || 1410cabdff1aSopenharmony_ci (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || 1411cabdff1aSopenharmony_ci stream_type == FLV_STREAM_TYPE_SUBTITLE || 1412cabdff1aSopenharmony_ci stream_type == FLV_STREAM_TYPE_DATA) 1413cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 1414cabdff1aSopenharmony_ci 1415cabdff1aSopenharmony_cileave: 1416cabdff1aSopenharmony_ci last = avio_rb32(s->pb); 1417cabdff1aSopenharmony_ci if (!flv->trust_datasize) { 1418cabdff1aSopenharmony_ci if (last != orig_size + 11 && last != orig_size + 10 && 1419cabdff1aSopenharmony_ci !avio_feof(s->pb) && 1420cabdff1aSopenharmony_ci (last != orig_size || !last) && last != flv->sum_flv_tag_size && 1421cabdff1aSopenharmony_ci !flv->broken_sizes) { 1422cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "Packet mismatch %d %d %"PRId64"\n", last, orig_size + 11, flv->sum_flv_tag_size); 1423cabdff1aSopenharmony_ci avio_seek(s->pb, pos + 1, SEEK_SET); 1424cabdff1aSopenharmony_ci ret = resync(s); 1425cabdff1aSopenharmony_ci av_packet_unref(pkt); 1426cabdff1aSopenharmony_ci if (ret >= 0) { 1427cabdff1aSopenharmony_ci goto retry; 1428cabdff1aSopenharmony_ci } 1429cabdff1aSopenharmony_ci } 1430cabdff1aSopenharmony_ci } 1431cabdff1aSopenharmony_ci 1432cabdff1aSopenharmony_ci if (ret >= 0) 1433cabdff1aSopenharmony_ci flv->last_ts = pkt->dts; 1434cabdff1aSopenharmony_ci 1435cabdff1aSopenharmony_ci return ret; 1436cabdff1aSopenharmony_ci} 1437cabdff1aSopenharmony_ci 1438cabdff1aSopenharmony_cistatic int flv_read_seek(AVFormatContext *s, int stream_index, 1439cabdff1aSopenharmony_ci int64_t ts, int flags) 1440cabdff1aSopenharmony_ci{ 1441cabdff1aSopenharmony_ci FLVContext *flv = s->priv_data; 1442cabdff1aSopenharmony_ci flv->validate_count = 0; 1443cabdff1aSopenharmony_ci return avio_seek_time(s->pb, stream_index, ts, flags); 1444cabdff1aSopenharmony_ci} 1445cabdff1aSopenharmony_ci 1446cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(FLVContext, x) 1447cabdff1aSopenharmony_ci#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM 1448cabdff1aSopenharmony_cistatic const AVOption options[] = { 1449cabdff1aSopenharmony_ci { "flv_metadata", "Allocate streams according to the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD }, 1450cabdff1aSopenharmony_ci { "flv_full_metadata", "Dump full metadata of the onMetadata", OFFSET(dump_full_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD }, 1451cabdff1aSopenharmony_ci { "flv_ignore_prevtag", "Ignore the Size of previous tag", OFFSET(trust_datasize), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD }, 1452cabdff1aSopenharmony_ci { "missing_streams", "", OFFSET(missing_streams), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xFF, VD | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY }, 1453cabdff1aSopenharmony_ci { NULL } 1454cabdff1aSopenharmony_ci}; 1455cabdff1aSopenharmony_ci 1456cabdff1aSopenharmony_cistatic const AVClass flv_kux_class = { 1457cabdff1aSopenharmony_ci .class_name = "(live) flv/kux demuxer", 1458cabdff1aSopenharmony_ci .item_name = av_default_item_name, 1459cabdff1aSopenharmony_ci .option = options, 1460cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 1461cabdff1aSopenharmony_ci}; 1462cabdff1aSopenharmony_ci 1463cabdff1aSopenharmony_ciconst AVInputFormat ff_flv_demuxer = { 1464cabdff1aSopenharmony_ci .name = "flv", 1465cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"), 1466cabdff1aSopenharmony_ci .priv_data_size = sizeof(FLVContext), 1467cabdff1aSopenharmony_ci .read_probe = flv_probe, 1468cabdff1aSopenharmony_ci .read_header = flv_read_header, 1469cabdff1aSopenharmony_ci .read_packet = flv_read_packet, 1470cabdff1aSopenharmony_ci .read_seek = flv_read_seek, 1471cabdff1aSopenharmony_ci .read_close = flv_read_close, 1472cabdff1aSopenharmony_ci .extensions = "flv", 1473cabdff1aSopenharmony_ci .priv_class = &flv_kux_class, 1474cabdff1aSopenharmony_ci}; 1475cabdff1aSopenharmony_ci 1476cabdff1aSopenharmony_ciconst AVInputFormat ff_live_flv_demuxer = { 1477cabdff1aSopenharmony_ci .name = "live_flv", 1478cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("live RTMP FLV (Flash Video)"), 1479cabdff1aSopenharmony_ci .priv_data_size = sizeof(FLVContext), 1480cabdff1aSopenharmony_ci .read_probe = live_flv_probe, 1481cabdff1aSopenharmony_ci .read_header = flv_read_header, 1482cabdff1aSopenharmony_ci .read_packet = flv_read_packet, 1483cabdff1aSopenharmony_ci .read_seek = flv_read_seek, 1484cabdff1aSopenharmony_ci .read_close = flv_read_close, 1485cabdff1aSopenharmony_ci .extensions = "flv", 1486cabdff1aSopenharmony_ci .priv_class = &flv_kux_class, 1487cabdff1aSopenharmony_ci .flags = AVFMT_TS_DISCONT 1488cabdff1aSopenharmony_ci}; 1489cabdff1aSopenharmony_ci 1490cabdff1aSopenharmony_ciconst AVInputFormat ff_kux_demuxer = { 1491cabdff1aSopenharmony_ci .name = "kux", 1492cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("KUX (YouKu)"), 1493cabdff1aSopenharmony_ci .priv_data_size = sizeof(FLVContext), 1494cabdff1aSopenharmony_ci .read_probe = kux_probe, 1495cabdff1aSopenharmony_ci .read_header = flv_read_header, 1496cabdff1aSopenharmony_ci .read_packet = flv_read_packet, 1497cabdff1aSopenharmony_ci .read_seek = flv_read_seek, 1498cabdff1aSopenharmony_ci .read_close = flv_read_close, 1499cabdff1aSopenharmony_ci .extensions = "kux", 1500cabdff1aSopenharmony_ci .priv_class = &flv_kux_class, 1501cabdff1aSopenharmony_ci}; 1502