int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb) { enum AVCodecID codec_id; unsigned v; int len, tag; int ret; int object_type_id = avio_r8(pb); avio_r8(pb); /* stream type */ avio_rb24(pb); /* buffer size db */ v = avio_rb32(pb); // TODO: fix this with codecpar #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS if (v < INT32_MAX) st->codec->rc_max_rate = v; FF_ENABLE_DEPRECATION_WARNINGS #endif st->codecpar->bit_rate = avio_rb32(pb); /* avg bitrate */ codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id); if (codec_id) st->codecpar->codec_id = codec_id; av_log(fc, AV_LOG_TRACE, "esds object type id 0x%02x\n", object_type_id); len = ff_mp4_read_descr(fc, pb, &tag); if (tag == MP4DecSpecificDescrTag) { av_log(fc, AV_LOG_TRACE, "Specific MPEG-4 header len=%d\n", len); if (!len || (uint64_t)len > (1<<30)) return -1; av_free(st->codecpar->extradata); if ((ret = ff_get_extradata(fc, st->codecpar, pb, len)) < 0) return ret; if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { MPEG4AudioConfig cfg = {0}; avpriv_mpeg4audio_get_config(&cfg, st->codecpar->extradata, st->codecpar->extradata_size * 8, 1); st->codecpar->channels = cfg.channels; if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 st->codecpar->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index]; else if (cfg.ext_sample_rate) st->codecpar->sample_rate = cfg.ext_sample_rate; else st->codecpar->sample_rate = cfg.sample_rate; av_log(fc, AV_LOG_TRACE, "mp4a config channels %d obj %d ext obj %d " "sample rate %d ext sample rate %d\n", st->codecpar->channels, cfg.object_type, cfg.ext_object_type, cfg.sample_rate, cfg.ext_sample_rate); if (!(st->codecpar->codec_id = ff_codec_get_id(mp4_audio_types, cfg.object_type))) st->codecpar->codec_id = AV_CODEC_ID_AAC; } } return 0; }
int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb) { enum AVCodecID codec_id; int len, tag; int ret; int object_type_id = avio_r8(pb); avio_r8(pb); /* stream type */ avio_rb24(pb); /* buffer size db */ avio_rb32(pb); /* max bitrate */ avio_rb32(pb); /* avg bitrate */ if(avcodec_is_open(st->codec)) { av_log(fc, AV_LOG_DEBUG, "codec open in read_dec_config_descr\n"); return -1; } codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id); if (codec_id) st->codec->codec_id= codec_id; av_log(fc, AV_LOG_TRACE, "esds object type id 0x%02x\n", object_type_id); len = ff_mp4_read_descr(fc, pb, &tag); if (tag == MP4DecSpecificDescrTag) { av_log(fc, AV_LOG_TRACE, "Specific MPEG4 header len=%d\n", len); if (!len || (uint64_t)len > (1<<30)) return -1; av_free(st->codec->extradata); if ((ret = ff_get_extradata(st->codec, pb, len)) < 0) return ret; if (st->codec->codec_id == AV_CODEC_ID_AAC) { MPEG4AudioConfig cfg = {0}; avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, st->codec->extradata_size * 8, 1); st->codec->channels = cfg.channels; if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index]; else if (cfg.ext_sample_rate) st->codec->sample_rate = cfg.ext_sample_rate; else st->codec->sample_rate = cfg.sample_rate; av_log(fc, AV_LOG_TRACE, "mp4a config channels %d obj %d ext obj %d " "sample rate %d ext sample rate %d\n", st->codec->channels, cfg.object_type, cfg.ext_object_type, cfg.sample_rate, cfg.ext_sample_rate); if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types, cfg.object_type))) st->codec->codec_id = AV_CODEC_ID_AAC; } } return 0; }
static int avr_read_header(AVFormatContext *s) { uint16_t chan, sign, bps; AVStream *st; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; avio_skip(s->pb, 4); // magic avio_skip(s->pb, 8); // sample_name chan = avio_rb16(s->pb); if (!chan) { st->codecpar->channels = 1; } else if (chan == 0xFFFFu) { st->codecpar->channels = 2; } else { avpriv_request_sample(s, "chan %d", chan); return AVERROR_PATCHWELCOME; } st->codecpar->bits_per_coded_sample = bps = avio_rb16(s->pb); sign = avio_rb16(s->pb); avio_skip(s->pb, 2); // loop avio_skip(s->pb, 2); // midi avio_skip(s->pb, 1); // replay speed st->codecpar->sample_rate = avio_rb24(s->pb); avio_skip(s->pb, 4 * 3); avio_skip(s->pb, 2 * 3); avio_skip(s->pb, 20); avio_skip(s->pb, 64); st->codecpar->codec_id = ff_get_pcm_codec_id(bps, 0, 1, sign); if (st->codecpar->codec_id == AV_CODEC_ID_NONE) { avpriv_request_sample(s, "Bps %d and sign %d", bps, sign); return AVERROR_PATCHWELCOME; } st->codecpar->block_align = bps * st->codecpar->channels / 8; avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); return 0; }
/** * Try to find Xing/Info/VBRI tags and compute duration from info therein */ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) { MP3Context *mp3 = s->priv_data; uint32_t v, spf; unsigned frames = 0; /* Total number of frames in file */ unsigned size = 0; /* Total number of bytes in the stream */ const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; MPADecodeHeader c; int vbrtag_size = 0; int is_cbr; v = avio_rb32(s->pb); if(ff_mpa_check_header(v) < 0) return -1; if (avpriv_mpegaudio_decode_header(&c, v) == 0) vbrtag_size = c.frame_size; if(c.layer != 3) return -1; spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ /* Check for Xing / Info tag */ avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); v = avio_rb32(s->pb); is_cbr = v == MKBETAG('I', 'n', 'f', 'o'); if (v == MKBETAG('X', 'i', 'n', 'g') || is_cbr) { v = avio_rb32(s->pb); if(v & XING_FLAG_FRAMES) frames = avio_rb32(s->pb); if(v & XING_FLAG_SIZE) size = avio_rb32(s->pb); if (v & XING_FLAG_TOC && frames) read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate}, st->time_base)); if(v & 8) avio_skip(s->pb, 4); v = avio_rb32(s->pb); if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) { avio_skip(s->pb, 21-4); v= avio_rb24(s->pb); mp3->start_pad = v>>12; mp3-> end_pad = v&4095; st->skip_samples = mp3->start_pad + 528 + 1; av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); }
int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb) { int len, tag; int object_type_id = avio_r8(pb); avio_r8(pb); /* stream type */ avio_rb24(pb); /* buffer size db */ avio_rb32(pb); /* max bitrate */ avio_rb32(pb); /* avg bitrate */ st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id); av_dlog(fc, "esds object type id 0x%02x\n", object_type_id); len = ff_mp4_read_descr(fc, pb, &tag); if (tag == MP4DecSpecificDescrTag) { av_dlog(fc, "Specific MPEG4 header len=%d\n", len); if((uint64_t)len > (1<<30)) return -1; av_free(st->codec->extradata); st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); avio_read(pb, st->codec->extradata, len); st->codec->extradata_size = len; if (st->codec->codec_id == CODEC_ID_AAC) { MPEG4AudioConfig cfg; ff_mpeg4audio_get_config(&cfg, st->codec->extradata, st->codec->extradata_size); st->codec->channels = cfg.channels; if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index]; else if (cfg.ext_sample_rate) st->codec->sample_rate = cfg.ext_sample_rate; else st->codec->sample_rate = cfg.sample_rate; av_dlog(fc, "mp4a config channels %d obj %d ext obj %d " "sample rate %d ext sample rate %d\n", st->codec->channels, cfg.object_type, cfg.ext_object_type, cfg.sample_rate, cfg.ext_sample_rate); if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types, cfg.object_type))) st->codec->codec_id = CODEC_ID_AAC; } } return 0; }
/** * Try to find Xing/Info/VBRI tags and compute duration from info therein */ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) { MP3Context *mp3 = s->priv_data; uint32_t v, spf; unsigned frames = 0; /* Total number of frames in file */ unsigned size = 0; /* Total number of bytes in the stream */ const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; MPADecodeHeader c; int vbrtag_size = 0; v = avio_rb32(s->pb); if(ff_mpa_check_header(v) < 0) return -1; if (avpriv_mpegaudio_decode_header(&c, v) == 0) vbrtag_size = c.frame_size; if(c.layer != 3) return -1; /* Check for Xing / Info tag */ avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); v = avio_rb32(s->pb); if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { v = avio_rb32(s->pb); if(v & 0x1) frames = avio_rb32(s->pb); if(v & 0x2) size = avio_rb32(s->pb); if(v & 4) avio_skip(s->pb, 100); if(v & 8) avio_skip(s->pb, 4); v = avio_rb32(s->pb); if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) { avio_skip(s->pb, 21-4); v= avio_rb24(s->pb); mp3->start_pad = v>>12; mp3-> end_pad = v&4095; st->skip_samples = mp3->start_pad + 528 + 1; av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); }
static int smush_read_header(AVFormatContext *ctx) { SMUSHContext *smush = ctx->priv_data; AVIOContext *pb = ctx->pb; AVStream *vst, *ast; uint32_t magic, nframes, size, subversion, i; uint32_t width = 0, height = 0, got_audio = 0, read = 0; uint32_t sample_rate, channels, palette[256]; magic = avio_rb32(pb); avio_skip(pb, 4); // skip movie size if (magic == MKBETAG('A', 'N', 'I', 'M')) { if (avio_rb32(pb) != MKBETAG('A', 'H', 'D', 'R')) return AVERROR_INVALIDDATA; size = avio_rb32(pb); if (size < 3 * 256 + 6) return AVERROR_INVALIDDATA; smush->version = 0; subversion = avio_rl16(pb); nframes = avio_rl16(pb); if (!nframes) return AVERROR_INVALIDDATA; avio_skip(pb, 2); // skip pad for (i = 0; i < 256; i++) palette[i] = avio_rb24(pb); avio_skip(pb, size - (3 * 256 + 6)); } else if (magic == MKBETAG('S', 'A', 'N', 'M')) { if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R')) return AVERROR_INVALIDDATA; size = avio_rb32(pb); if (size < 14) return AVERROR_INVALIDDATA; smush->version = 1; subversion = avio_rl16(pb); nframes = avio_rl32(pb); if (!nframes) return AVERROR_INVALIDDATA; avio_skip(pb, 2); // skip pad width = avio_rl16(pb); height = avio_rl16(pb); avio_skip(pb, 2); // skip pad avio_skip(pb, size - 14); if (avio_rb32(pb) != MKBETAG('F', 'L', 'H', 'D')) return AVERROR_INVALIDDATA; size = avio_rb32(pb); while (!got_audio && ((read + 8) < size)) { uint32_t sig, chunk_size; if (avio_feof(pb)) return AVERROR_EOF; sig = avio_rb32(pb); chunk_size = avio_rb32(pb); read += 8; switch (sig) { case MKBETAG('W', 'a', 'v', 'e'): got_audio = 1; sample_rate = avio_rl32(pb); if (!sample_rate) return AVERROR_INVALIDDATA; channels = avio_rl32(pb); if (!channels) return AVERROR_INVALIDDATA; avio_skip(pb, chunk_size - 8); read += chunk_size; break; case MKBETAG('B', 'l', '1', '6'): case MKBETAG('A', 'N', 'N', 'O'): avio_skip(pb, chunk_size); read += chunk_size; break; default: return AVERROR_INVALIDDATA; break; } } avio_skip(pb, size - read); } else { av_log(ctx, AV_LOG_ERROR, "Wrong magic\n"); return AVERROR_INVALIDDATA; } vst = avformat_new_stream(ctx, 0); if (!vst) return AVERROR(ENOMEM); smush->video_stream_index = vst->index; avpriv_set_pts_info(vst, 64, 1, 15); vst->start_time = 0; vst->duration = vst->nb_frames = nframes; vst->avg_frame_rate = av_inv_q(vst->time_base); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_SANM; vst->codec->codec_tag = 0; vst->codec->width = width; vst->codec->height = height; if (!smush->version) { if (ff_alloc_extradata(vst->codec, 1024 + 2)) return AVERROR(ENOMEM); AV_WL16(vst->codec->extradata, subversion); for (i = 0; i < 256; i++) AV_WL32(vst->codec->extradata + 2 + i * 4, palette[i]); } if (got_audio) { ast = avformat_new_stream(ctx, 0); if (!ast) return AVERROR(ENOMEM); smush->audio_stream_index = ast->index; ast->start_time = 0; ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = AV_CODEC_ID_ADPCM_VIMA; ast->codec->codec_tag = 0; ast->codec->sample_rate = sample_rate; ast->codec->channels = channels; avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); } return 0; }
static int tak_read_header(AVFormatContext *s) { TAKDemuxContext *tc = s->priv_data; AVIOContext *pb = s->pb; GetBitContext gb; AVStream *st; uint8_t *buffer = NULL; int ret; st = avformat_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TAK; st->need_parsing = AVSTREAM_PARSE_FULL_RAW; tc->mlast_frame = 0; if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) { avio_seek(pb, -4, SEEK_CUR); return 0; } while (!avio_feof(pb)) { enum TAKMetaDataType type; int size; type = avio_r8(pb) & 0x7f; size = avio_rl24(pb); switch (type) { case TAK_METADATA_STREAMINFO: case TAK_METADATA_LAST_FRAME: case TAK_METADATA_ENCODER: if (size <= 3) return AVERROR_INVALIDDATA; buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE); if (!buffer) return AVERROR(ENOMEM); memset(buffer + size - 3, 0, FF_INPUT_BUFFER_PADDING_SIZE); ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U); if (avio_read(pb, buffer, size - 3) != size - 3) { av_freep(&buffer); return AVERROR(EIO); } if (ffio_get_checksum(s->pb) != avio_rb24(pb)) { av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type); if (s->error_recognition & AV_EF_EXPLODE) { av_freep(&buffer); return AVERROR_INVALIDDATA; } } init_get_bits8(&gb, buffer, size - 3); break; case TAK_METADATA_MD5: { uint8_t md5[16]; int i; if (size != 19) return AVERROR_INVALIDDATA; ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U); avio_read(pb, md5, 16); if (ffio_get_checksum(s->pb) != avio_rb24(pb)) { av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n"); if (s->error_recognition & AV_EF_EXPLODE) return AVERROR_INVALIDDATA; } av_log(s, AV_LOG_VERBOSE, "MD5="); for (i = 0; i < 16; i++) av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]); av_log(s, AV_LOG_VERBOSE, "\n"); break; } case TAK_METADATA_END: { int64_t curpos = avio_tell(pb); if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, curpos, SEEK_SET); } tc->data_end += curpos; return 0; } default: ret = avio_skip(pb, size); if (ret < 0) return ret; } if (type == TAK_METADATA_STREAMINFO) { TAKStreamInfo ti; avpriv_tak_parse_streaminfo(&gb, &ti); if (ti.samples > 0) st->duration = ti.samples; st->codec->bits_per_coded_sample = ti.bps; if (ti.ch_layout) st->codec->channel_layout = ti.ch_layout; st->codec->sample_rate = ti.sample_rate; st->codec->channels = ti.channels; st->start_time = 0; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); st->codec->extradata = buffer; st->codec->extradata_size = size - 3; buffer = NULL; } else if (type == TAK_METADATA_LAST_FRAME) { if (size != 11) return AVERROR_INVALIDDATA; tc->mlast_frame = 1; tc->data_end = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) + get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS); av_freep(&buffer); } else if (type == TAK_METADATA_ENCODER) { av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n", get_bits_long(&gb, TAK_ENCODER_VERSION_BITS)); av_freep(&buffer); } } return AVERROR_EOF; }
/** * @return 0 when a packet was written into /p pkt, and no more data is left; * 1 when a packet was written into /p pkt, and more packets might be left; * <0 when not enough data was provided to return a full packet, or on error. */ static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags) { AVIOContext *pb = &asf->pb; int res, mflags, len_off; RTSPState *rt = s->priv_data; if (!rt->asf_ctx) return -1; if (len > 0) { int off, out_len = 0; if (len < 4) return -1; av_freep(&asf->buf); ffio_init_context(pb, buf, len, 0, NULL, NULL, NULL, NULL); while (avio_tell(pb) + 4 < len) { int start_off = avio_tell(pb); mflags = avio_r8(pb); if (mflags & 0x80) flags |= RTP_FLAG_KEY; len_off = avio_rb24(pb); if (mflags & 0x20) /**< relative timestamp */ avio_skip(pb, 4); if (mflags & 0x10) /**< has duration */ avio_skip(pb, 4); if (mflags & 0x8) /**< has location ID */ avio_skip(pb, 4); off = avio_tell(pb); if (!(mflags & 0x40)) { /** * If 0x40 is not set, the len_off field specifies an offset * of this packet's payload data in the complete (reassembled) * ASF packet. This is used to spread one ASF packet over * multiple RTP packets. */ if (asf->pktbuf && len_off != avio_tell(asf->pktbuf)) { uint8_t *p; avio_close_dyn_buf(asf->pktbuf, &p); asf->pktbuf = NULL; av_free(p); } if (!len_off && !asf->pktbuf && (res = avio_open_dyn_buf(&asf->pktbuf)) < 0) return res; if (!asf->pktbuf) return AVERROR(EIO); avio_write(asf->pktbuf, buf + off, len - off); avio_skip(pb, len - off); if (!(flags & RTP_FLAG_MARKER)) return -1; out_len = avio_close_dyn_buf(asf->pktbuf, &asf->buf); asf->pktbuf = NULL; } else { /** * If 0x40 is set, the len_off field specifies the length of * the next ASF packet that can be read from this payload * data alone. This is commonly the same as the payload size, * but could be less in case of packet splitting (i.e. * multiple ASF packets in one RTP packet). */ int cur_len = start_off + len_off - off; int prev_len = out_len; out_len += cur_len; if (FFMIN(cur_len, len - off) < 0) return -1; if ((res = av_reallocp(&asf->buf, out_len)) < 0) return res; memcpy(asf->buf + prev_len, buf + off, FFMIN(cur_len, len - off)); avio_skip(pb, cur_len); } } init_packetizer(pb, asf->buf, out_len); pb->pos += rt->asf_pb_pos; pb->eof_reached = 0; rt->asf_ctx->pb = pb; } for (;;) { int i; res = ff_read_packet(rt->asf_ctx, pkt); rt->asf_pb_pos = avio_tell(pb); if (res != 0) break; for (i = 0; i < s->nb_streams; i++) { if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) { pkt->stream_index = i; return 1; // FIXME: return 0 if last packet } } av_free_packet(pkt); } return res == 1 ? -1 : res; }
static int read_part_of_packet(AVFormatContext *s, int64_t *pts, int *len, int *strid, int read_packet) { AVIOContext *pb = s->pb; PVAContext *pvactx = s->priv_data; int syncword, streamid, reserved, flags, length, pts_flag; int64_t pva_pts = AV_NOPTS_VALUE, startpos; recover: startpos = avio_tell(pb); syncword = avio_rb16(pb); streamid = avio_r8(pb); avio_r8(pb); /* counter not used */ reserved = avio_r8(pb); flags = avio_r8(pb); length = avio_rb16(pb); pts_flag = flags & 0x10; if (syncword != PVA_MAGIC) { pva_log(s, AV_LOG_ERROR, "invalid syncword\n"); return AVERROR(EIO); } if (streamid != PVA_VIDEO_PAYLOAD && streamid != PVA_AUDIO_PAYLOAD) { pva_log(s, AV_LOG_ERROR, "invalid streamid\n"); return AVERROR(EIO); } if (reserved != 0x55) { pva_log(s, AV_LOG_WARNING, "expected reserved byte to be 0x55\n"); } if (length > PVA_MAX_PAYLOAD_LENGTH) { pva_log(s, AV_LOG_ERROR, "invalid payload length %u\n", length); return AVERROR(EIO); } if (streamid == PVA_VIDEO_PAYLOAD && pts_flag) { pva_pts = avio_rb32(pb); length -= 4; } else if (streamid == PVA_AUDIO_PAYLOAD) { /* PVA Audio Packets either start with a signaled PES packet or * are a continuation of the previous PES packet. New PES packets * always start at the beginning of a PVA Packet, never somewhere in * the middle. */ if (!pvactx->continue_pes) { int pes_signal, pes_header_data_length, pes_packet_length, pes_flags; unsigned char pes_header_data[256]; pes_signal = avio_rb24(pb); avio_r8(pb); pes_packet_length = avio_rb16(pb); pes_flags = avio_rb16(pb); pes_header_data_length = avio_r8(pb); if (pes_signal != 1) { pva_log(s, AV_LOG_WARNING, "expected signaled PES packet, " "trying to recover\n"); avio_skip(pb, length - 9); if (!read_packet) return AVERROR(EIO); goto recover; } avio_read(pb, pes_header_data, pes_header_data_length); length -= 9 + pes_header_data_length; pes_packet_length -= 3 + pes_header_data_length; pvactx->continue_pes = pes_packet_length; if (pes_flags & 0x80 && (pes_header_data[0] & 0xf0) == 0x20) pva_pts = ff_parse_pes_pts(pes_header_data); } pvactx->continue_pes -= length; if (pvactx->continue_pes < 0) { pva_log(s, AV_LOG_WARNING, "audio data corruption\n"); pvactx->continue_pes = 0; } } if (pva_pts != AV_NOPTS_VALUE) av_add_index_entry(s->streams[streamid-1], startpos, pva_pts, 0, 0, AVINDEX_KEYFRAME); *pts = pva_pts; *len = length; *strid = streamid; return 0; }
static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, MPADecodeHeader *c, uint32_t spf) { #define LAST_BITS(k, n) ((k) & ((1 << (n)) - 1)) #define MIDDLE_BITS(k, m, n) LAST_BITS((k) >> (m), ((n) - (m))) uint16_t crc; uint32_t v; char version[10]; uint32_t peak = 0; int32_t r_gain = INT32_MIN, a_gain = INT32_MIN; MP3DecContext *mp3 = s->priv_data; const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; /* Check for Xing / Info tag */ avio_skip(s->pb, xing_offtbl[c->lsf == 1][c->nb_channels == 1]); v = avio_rb32(s->pb); mp3->is_cbr = v == MKBETAG('I', 'n', 'f', 'o'); if (v != MKBETAG('X', 'i', 'n', 'g') && !mp3->is_cbr) return; v = avio_rb32(s->pb); if (v & XING_FLAG_FRAMES) mp3->frames = avio_rb32(s->pb); if (v & XING_FLAG_SIZE) mp3->size = avio_rb32(s->pb); if (v & XING_FLAG_TOC && mp3->frames) read_xing_toc(s, mp3->size, av_rescale_q(mp3->frames, (AVRational){spf, c->sample_rate}, st->time_base)); /* VBR quality */ if (v & XING_FLAC_QSCALE) avio_rb32(s->pb); /* Encoder short version string */ memset(version, 0, sizeof(version)); avio_read(s->pb, version, 9); /* Info Tag revision + VBR method */ avio_r8(s->pb); /* Lowpass filter value */ avio_r8(s->pb); /* ReplayGain peak */ v = avio_rb32(s->pb); peak = av_rescale(v, 100000, 1 << 23); /* Radio ReplayGain */ v = avio_rb16(s->pb); if (MIDDLE_BITS(v, 13, 15) == 1) { r_gain = MIDDLE_BITS(v, 0, 8) * 10000; if (v & (1 << 9)) r_gain *= -1; } /* Audiophile ReplayGain */ v = avio_rb16(s->pb); if (MIDDLE_BITS(v, 13, 15) == 2) { a_gain = MIDDLE_BITS(v, 0, 8) * 10000; if (v & (1 << 9)) a_gain *= -1; } /* Encoding flags + ATH Type */ avio_r8(s->pb); /* if ABR {specified bitrate} else {minimal bitrate} */ avio_r8(s->pb); /* Encoder delays */ avio_rb24(s->pb); /* Misc */ avio_r8(s->pb); /* MP3 gain */ avio_r8(s->pb); /* Preset and surround info */ avio_rb16(s->pb); /* Music length */ avio_rb32(s->pb); /* Music CRC */ avio_rb16(s->pb); /* Info Tag CRC */ crc = ffio_get_checksum(s->pb); v = avio_rb16(s->pb); if (v == crc) { ff_replaygain_export_raw(st, r_gain, peak, a_gain, 0); av_dict_set(&st->metadata, "encoder", version, 0); } }
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) { FLVContext *flv = s->priv_data; int ret, i, type, size, flags; int stream_type=-1; int64_t next, pos; int64_t dts, pts = AV_NOPTS_VALUE; int av_uninit(channels); int av_uninit(sample_rate); AVStream *st = NULL; for(;; avio_skip(s->pb, 4)) { /* pkt size is repeated at end. skip it */ pos = avio_tell(s->pb); type = avio_r8(s->pb); size = avio_rb24(s->pb); dts = avio_rb24(s->pb); dts |= avio_r8(s->pb) << 24; av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts); if (url_feof(s->pb)) return AVERROR_EOF; avio_skip(s->pb, 3); /* stream id, always 0 */ flags = 0; if (flv->validate_next < flv->validate_count) { int64_t validate_pos = flv->validate_index[flv->validate_next].pos; if (pos == validate_pos) { if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <= VALIDATE_INDEX_TS_THRESH) { flv->validate_next++; } else { clear_index_entries(s, validate_pos); flv->validate_count = 0; } } else if (pos > validate_pos) { clear_index_entries(s, validate_pos); flv->validate_count = 0; } } if(size == 0) continue; next= size + avio_tell(s->pb); if (type == FLV_TAG_TYPE_AUDIO) { stream_type=FLV_STREAM_TYPE_AUDIO; flags = avio_r8(s->pb); size--; } else if (type == FLV_TAG_TYPE_VIDEO) { stream_type=FLV_STREAM_TYPE_VIDEO; flags = avio_r8(s->pb); size--; if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) goto skip; } else if (type == FLV_TAG_TYPE_META) { if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff flv_read_metabody(s, next); goto skip; } else if (dts != 0) { // Script-data "special" metadata frames - don't skip stream_type=FLV_STREAM_TYPE_DATA; } else { goto skip; } } else { av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); skip: avio_seek(s->pb, next, SEEK_SET); continue; } /* skip empty data packets */ if (!size) continue; /* now find stream */ for(i=0; i<s->nb_streams; i++) { st = s->streams[i]; if (st->id == stream_type) break; } if(i == s->nb_streams) { av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n"); st = create_stream(s, stream_type, (int[]) { AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA }[stream_type]); } av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard); if( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO))) ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO))) || st->discard >= AVDISCARD_ALL ) { avio_seek(s->pb, next, SEEK_SET); continue; } if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); break; }