static int fsb_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; unsigned format, version, c; int64_t offset; AVCodecContext *codec; AVStream *st = avformat_new_stream(s, NULL); avio_skip(pb, 3); // "FSB" version = avio_r8(pb) - '0'; if (version != 4 && version != 3) { avpriv_request_sample(s, "version %d", version); return AVERROR_PATCHWELCOME; } avio_skip(pb, 4); if (!st) return AVERROR(ENOMEM); codec = st->codec; codec->codec_type = AVMEDIA_TYPE_AUDIO; codec->codec_tag = 0; if (version == 3) { offset = avio_rl32(pb) + 0x18; avio_skip(pb, 44); st->duration = avio_rl32(pb); avio_skip(pb, 12); format = avio_rl32(pb); codec->sample_rate = avio_rl32(pb); if (codec->sample_rate <= 0) return AVERROR_INVALIDDATA; avio_skip(pb, 6); codec->channels = avio_rl16(pb); if (!codec->channels) return AVERROR_INVALIDDATA; if (format & 0x00000100) { codec->codec_id = AV_CODEC_ID_PCM_S16LE; codec->block_align = 4096 * codec->channels; } else if (format & 0x00400000) { codec->bits_per_coded_sample = 4; codec->codec_id = AV_CODEC_ID_ADPCM_IMA_WAV; codec->block_align = 36 * codec->channels; } else if (format & 0x00800000) { codec->codec_id = AV_CODEC_ID_ADPCM_PSX; codec->block_align = 16 * codec->channels; } else if (format & 0x02000000) { codec->codec_id = AV_CODEC_ID_ADPCM_THP; codec->block_align = 8 * codec->channels; if (codec->channels > INT_MAX / 32) return AVERROR_INVALIDDATA; ff_alloc_extradata(codec, 32 * codec->channels); if (!codec->extradata) return AVERROR(ENOMEM); avio_seek(pb, 0x68, SEEK_SET); for (c = 0; c < codec->channels; c++) { avio_read(pb, codec->extradata + 32 * c, 32); avio_skip(pb, 14); } } else { avpriv_request_sample(s, "format 0x%X", format); return AVERROR_PATCHWELCOME; } } else if (version == 4) { offset = avio_rl32(pb) + 0x30; avio_skip(pb, 80); st->duration = avio_rl32(pb); format = avio_rb32(pb); switch(format) { case 0x40001001: case 0x00001005: case 0x40001081: case 0x40200001: codec->codec_id = AV_CODEC_ID_XMA2; break; case 0x40000802: codec->codec_id = AV_CODEC_ID_ADPCM_THP; break; default: avpriv_request_sample(s, "format 0x%X", format); return AVERROR_PATCHWELCOME; } codec->sample_rate = avio_rl32(pb); if (codec->sample_rate <= 0) return AVERROR_INVALIDDATA; avio_skip(pb, 6); codec->channels = avio_rl16(pb); if (!codec->channels) return AVERROR_INVALIDDATA; switch (codec->codec_id) { case AV_CODEC_ID_XMA2: ff_alloc_extradata(codec, 34); if (!codec->extradata) return AVERROR(ENOMEM); memset(codec->extradata, 0, 34); codec->block_align = 2048; break; case AV_CODEC_ID_ADPCM_THP: if (codec->channels > INT_MAX / 32) return AVERROR_INVALIDDATA; ff_alloc_extradata(codec, 32 * codec->channels); if (!codec->extradata) return AVERROR(ENOMEM); avio_seek(pb, 0x80, SEEK_SET); for (c = 0; c < codec->channels; c++) { avio_read(pb, codec->extradata + 32 * c, 32); avio_skip(pb, 14); } codec->block_align = 8 * codec->channels; break; } } else { av_assert0(0); } avio_skip(pb, offset - avio_tell(pb)); s->internal->data_offset = avio_tell(pb); avpriv_set_pts_info(st, 64, 1, codec->sample_rate); return 0; }
static int smjpeg_read_header(AVFormatContext *s) { SMJPEGContext *sc = s->priv_data; AVStream *ast = NULL, *vst = NULL; AVIOContext *pb = s->pb; uint32_t version, htype, hlength, duration; char *comment; avio_skip(pb, 8); // magic version = avio_rb32(pb); if (version) av_log_ask_for_sample(s, "unknown version %d\n", version); duration = avio_rb32(pb); // in msec while (!pb->eof_reached) { htype = avio_rl32(pb); switch (htype) { case SMJPEG_TXT: hlength = avio_rb32(pb); if (!hlength || hlength > 512) return AVERROR_INVALIDDATA; comment = av_malloc(hlength + 1); if (!comment) return AVERROR(ENOMEM); if (avio_read(pb, comment, hlength) != hlength) { av_freep(&comment); av_log(s, AV_LOG_ERROR, "error when reading comment\n"); return AVERROR_INVALIDDATA; } comment[hlength] = 0; av_dict_set(&s->metadata, "comment", comment, AV_DICT_DONT_STRDUP_VAL); break; case SMJPEG_SND: if (ast) { av_log_ask_for_sample(s, "multiple audio streams not supported\n"); return AVERROR_INVALIDDATA; } hlength = avio_rb32(pb); if (hlength < 8) return AVERROR_INVALIDDATA; ast = avformat_new_stream(s, 0); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->sample_rate = avio_rb16(pb); ast->codec->bits_per_coded_sample = avio_r8(pb); ast->codec->channels = avio_r8(pb); ast->codec->codec_tag = avio_rl32(pb); ast->codec->codec_id = ff_codec_get_id(ff_codec_smjpeg_audio_tags, ast->codec->codec_tag); ast->duration = duration; sc->audio_stream_index = ast->index; avpriv_set_pts_info(ast, 32, 1, 1000); avio_skip(pb, hlength - 8); break; case SMJPEG_VID: if (vst) { av_log_ask_for_sample(s, "multiple video streams not supported\n"); return AVERROR_INVALIDDATA; } hlength = avio_rb32(pb); if (hlength < 12) return AVERROR_INVALIDDATA; avio_skip(pb, 4); // number of frames vst = avformat_new_stream(s, 0); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->width = avio_rb16(pb); vst->codec->height = avio_rb16(pb); vst->codec->codec_tag = avio_rl32(pb); vst->codec->codec_id = ff_codec_get_id(ff_codec_smjpeg_video_tags, vst->codec->codec_tag); vst->duration = duration; sc->video_stream_index = vst->index; avpriv_set_pts_info(vst, 32, 1, 1000); avio_skip(pb, hlength - 12); break; case SMJPEG_HEND: return 0; default: av_log(s, AV_LOG_ERROR, "unknown header %x\n", htype); return AVERROR_INVALIDDATA; } } return AVERROR_EOF; }
static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, AVStream *st, RMStream *ast, int read_all) { char buf[256]; uint32_t version; int ret; /* ra type header */ version = avio_rb16(pb); /* version */ if (version == 3) { unsigned bytes_per_minute; int header_size = avio_rb16(pb); int64_t startpos = avio_tell(pb); avio_skip(pb, 8); bytes_per_minute = avio_rb16(pb); avio_skip(pb, 4); rm_read_metadata(s, pb, 0); if ((startpos + header_size) >= avio_tell(pb) + 2) { // fourcc (should always be "lpcJ") avio_r8(pb); get_str8(pb, buf, sizeof(buf)); } // Skip extra header crap (this should never happen) if ((startpos + header_size) > avio_tell(pb)) avio_skip(pb, header_size + startpos - avio_tell(pb)); if (bytes_per_minute) st->codec->bit_rate = 8LL * bytes_per_minute / 60; st->codec->sample_rate = 8000; st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_RA_144; ast->deint_id = DEINT_ID_INT0; } else { int flavor, sub_packet_h, coded_framesize, sub_packet_size; int codecdata_length; unsigned bytes_per_minute; /* old version (4) */ avio_skip(pb, 2); /* unused */ avio_rb32(pb); /* .ra4 */ avio_rb32(pb); /* data size */ avio_rb16(pb); /* version2 */ avio_rb32(pb); /* header size */ flavor= avio_rb16(pb); /* add codec info / flavor */ ast->coded_framesize = coded_framesize = avio_rb32(pb); /* coded frame size */ avio_rb32(pb); /* ??? */ bytes_per_minute = avio_rb32(pb); if (version == 4) { if (bytes_per_minute) st->codec->bit_rate = 8LL * bytes_per_minute / 60; } avio_rb32(pb); /* ??? */ ast->sub_packet_h = sub_packet_h = avio_rb16(pb); /* 1 */ st->codec->block_align= avio_rb16(pb); /* frame size */ ast->sub_packet_size = sub_packet_size = avio_rb16(pb); /* sub packet size */ avio_rb16(pb); /* ??? */ if (version == 5) { avio_rb16(pb); avio_rb16(pb); avio_rb16(pb); } st->codec->sample_rate = avio_rb16(pb); avio_rb32(pb); st->codec->channels = avio_rb16(pb); if (version == 5) { ast->deint_id = avio_rl32(pb); avio_read(pb, buf, 4); buf[4] = 0; } else { AV_WL32(buf, 0); get_str8(pb, buf, sizeof(buf)); /* desc */ ast->deint_id = AV_RL32(buf); get_str8(pb, buf, sizeof(buf)); /* desc */ } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = AV_RL32(buf); st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags, st->codec->codec_tag); switch (st->codec->codec_id) { case AV_CODEC_ID_AC3: st->need_parsing = AVSTREAM_PARSE_FULL; break; case AV_CODEC_ID_RA_288: st->codec->extradata_size= 0; ast->audio_framesize = st->codec->block_align; st->codec->block_align = coded_framesize; break; case AV_CODEC_ID_COOK: st->need_parsing = AVSTREAM_PARSE_HEADERS; case AV_CODEC_ID_ATRAC3: case AV_CODEC_ID_SIPR: if (read_all) { codecdata_length = 0; } else { avio_rb16(pb); avio_r8(pb); if (version == 5) avio_r8(pb); codecdata_length = avio_rb32(pb); if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); return -1; } } ast->audio_framesize = st->codec->block_align; if (st->codec->codec_id == AV_CODEC_ID_SIPR) { if (flavor > 3) { av_log(s, AV_LOG_ERROR, "bad SIPR file flavor %d\n", flavor); return -1; } st->codec->block_align = ff_sipr_subpk_size[flavor]; } else { if(sub_packet_size <= 0){ av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n"); return -1; } st->codec->block_align = ast->sub_packet_size; } if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0) return ret; break; case AV_CODEC_ID_AAC: avio_rb16(pb); avio_r8(pb); if (version == 5) avio_r8(pb); codecdata_length = avio_rb32(pb); if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); return -1; } if (codecdata_length >= 1) { avio_r8(pb); if ((ret = rm_read_extradata(pb, st->codec, codecdata_length - 1)) < 0) return ret; } break; } switch (ast->deint_id) { case DEINT_ID_INT4: if (ast->coded_framesize > ast->audio_framesize || sub_packet_h <= 1 || ast->coded_framesize * sub_packet_h > (2 + (sub_packet_h & 1)) * ast->audio_framesize) return AVERROR_INVALIDDATA; if (ast->coded_framesize * sub_packet_h != 2*ast->audio_framesize) { avpriv_request_sample(s, "mismatching interleaver parameters"); return AVERROR_INVALIDDATA; } break; case DEINT_ID_GENR: if (ast->sub_packet_size <= 0 || ast->sub_packet_size > ast->audio_framesize) return AVERROR_INVALIDDATA; if (ast->audio_framesize % ast->sub_packet_size) return AVERROR_INVALIDDATA; break; case DEINT_ID_SIPR: case DEINT_ID_INT0: case DEINT_ID_VBRS: case DEINT_ID_VBRF: break; default: av_log(s, AV_LOG_ERROR ,"Unknown interleaver %"PRIX32"\n", ast->deint_id); return AVERROR_INVALIDDATA; } if (ast->deint_id == DEINT_ID_INT4 || ast->deint_id == DEINT_ID_GENR || ast->deint_id == DEINT_ID_SIPR) { if (st->codec->block_align <= 0 || ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX || ast->audio_framesize * sub_packet_h < st->codec->block_align) return AVERROR_INVALIDDATA; if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0) return AVERROR(ENOMEM); } if (read_all) { avio_r8(pb); avio_r8(pb); avio_r8(pb); rm_read_metadata(s, pb, 0); } } return 0; }
static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, uint8_t block_type, AVFormatContext *s) { uint8_t * vidbuf_start = NULL; int vidbuf_nbytes = 0; int code; int bytes_copied = 0; int position, duration, npixels; unsigned int vidbuf_capacity; int ret = 0; AVStream *st; if (vid->video_index < 0) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); vid->video_index = st->index; if (vid->audio_index < 0) { av_log_ask_for_sample(s, "No audio packet before first video " "packet. Using default video time base.\n"); } avpriv_set_pts_info(st, 64, 185, vid->sample_rate); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_BETHSOFTVID; st->codec->width = vid->width; st->codec->height = vid->height; } st = s->streams[vid->video_index]; npixels = st->codec->width * st->codec->height; vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); // save the file position for the packet, include block type position = avio_tell(pb) - 1; vidbuf_start[vidbuf_nbytes++] = block_type; // get the current packet duration duration = vid->bethsoft_global_delay + avio_rl16(pb); // set the y offset if it exists (decoder header data should be in data section) if(block_type == VIDEO_YOFF_P_FRAME){ if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) { ret = AVERROR(EIO); goto fail; } vidbuf_nbytes += 2; } do{ vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); code = avio_r8(pb); vidbuf_start[vidbuf_nbytes++] = code; if(code >= 0x80){ // rle sequence if(block_type == VIDEO_I_FRAME) vidbuf_start[vidbuf_nbytes++] = avio_r8(pb); } else if(code){ // plain sequence if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) { ret = AVERROR(EIO); goto fail; } vidbuf_nbytes += code; } bytes_copied += code & 0x7F; if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied // may contain a 0 byte even if read all pixels if(avio_r8(pb)) avio_seek(pb, -1, SEEK_CUR); break; } if (bytes_copied > npixels) { ret = AVERROR_INVALIDDATA; goto fail; } } while(code); // copy data into packet if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0) goto fail; memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); av_free(vidbuf_start); pkt->pos = position; pkt->stream_index = vid->video_index; pkt->duration = duration; if (block_type == VIDEO_I_FRAME) pkt->flags |= AV_PKT_FLAG_KEY; /* if there is a new palette available, add it to packet side data */ if (vid->palette) { uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, BVID_PALETTE_SIZE); memcpy(pdata, vid->palette, BVID_PALETTE_SIZE); av_freep(&vid->palette); } vid->nframes--; // used to check if all the frames were read return 0; fail: av_free(vidbuf_start); return ret; }
/** * @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 void get_str8(AVIOContext *pb, char *buf, int buf_size) { get_strl(pb, buf, buf_size, avio_r8(pb)); }
static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; enum IEC61937DataType data_type; enum CodecID codec_id; uint32_t state = 0; int pkt_size_bits, offset, ret; while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) { state = (state << 8) | avio_r8(pb); if (url_feof(pb)) return AVERROR_EOF; } data_type = (IEC61937DataType)avio_rl16(pb); pkt_size_bits = avio_rl16(pb); if (pkt_size_bits % 16) av_log_ask_for_sample(s, "Packet does not end to a 16-bit boundary."); ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3); if (ret) return ret; pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE; if (avio_read(pb, pkt->data, pkt->size) < pkt->size) { av_free_packet(pkt); return AVERROR_EOF; } ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); ret = spdif_get_offset_and_codec(s, data_type, (const char *)pkt->data, &offset, &codec_id); if (ret) { av_free_packet(pkt); return ret; } /* skip over the padding to the beginning of the next frame */ avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE); if (!s->nb_streams) { /* first packet, create a stream */ AVStream *st = avformat_new_stream(s, NULL); if (!st) { av_free_packet(pkt); return AVERROR(ENOMEM); } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = codec_id; } else if (codec_id != s->streams[0]->codec->codec_id) { av_log_missing_feature(s, "codec change in IEC 61937", 0); return AVERROR_PATCHWELCOME; } if (!s->bit_rate && s->streams[0]->codec->sample_rate) /* stream bitrate matches 16-bit stereo PCM bitrate for currently supported codecs */ s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate; return 0; }
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 int nuv_header(AVFormatContext *s) { NUVContext *ctx = s->priv_data; AVIOContext *pb = s->pb; char id_string[12]; double aspect, fps; int is_mythtv, width, height, v_packs, a_packs; int stream_nr = 0; AVStream *vst = NULL, *ast = NULL; avio_read(pb, id_string, 12); is_mythtv = !memcmp(id_string, "MythTVVideo", 12); avio_skip(pb, 5); // version string avio_skip(pb, 3); // padding width = avio_rl32(pb); height = avio_rl32(pb); avio_rl32(pb); // unused, "desiredwidth" avio_rl32(pb); // unused, "desiredheight" avio_r8(pb); // 'P' == progressive, 'I' == interlaced avio_skip(pb, 3); // padding aspect = av_int2double(avio_rl64(pb)); if (aspect > 0.9999 && aspect < 1.0001) aspect = 4.0 / 3.0; fps = av_int2double(avio_rl64(pb)); // number of packets per stream type, -1 means unknown, e.g. streaming v_packs = avio_rl32(pb); a_packs = avio_rl32(pb); avio_rl32(pb); // text avio_rl32(pb); // keyframe distance (?) if (v_packs) { ctx->v_id = stream_nr++; vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = CODEC_ID_NUV; vst->codec->width = width; vst->codec->height = height; vst->codec->bits_per_coded_sample = 10; vst->sample_aspect_ratio = av_d2q(aspect * height / width, 10000); vst->r_frame_rate = av_d2q(fps, 60000); avpriv_set_pts_info(vst, 32, 1, 1000); } else ctx->v_id = -1; if (a_packs) { ctx->a_id = stream_nr++; ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = CODEC_ID_PCM_S16LE; ast->codec->channels = 2; ast->codec->sample_rate = 44100; ast->codec->bit_rate = 2 * 2 * 44100 * 8; ast->codec->block_align = 2 * 2; ast->codec->bits_per_coded_sample = 16; avpriv_set_pts_info(ast, 32, 1, 1000); } else ctx->a_id = -1; get_codec_data(pb, vst, ast, is_mythtv); ctx->rtjpg_video = vst && vst->codec->codec_id == CODEC_ID_NUV; return 0; }
static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof) { AVIOContext *pb = s->pb; char abss[24]; int hour, min, sec, i, ret, config; int dsd_layout[6]; ID3v2ExtraMeta *id3v2_extra_meta; while (avio_tell(pb) + 12 <= eof) { uint32_t tag = avio_rl32(pb); uint64_t size = avio_rb64(pb); uint64_t orig_pos = avio_tell(pb); switch(tag) { case MKTAG('A','B','S','S'): if (size < 8) return AVERROR_INVALIDDATA; hour = avio_rb16(pb); min = avio_r8(pb); sec = avio_r8(pb); snprintf(abss, sizeof(abss), "%02dh:%02dm:%02ds:%d", hour, min, sec, avio_rb32(pb)); av_dict_set(&st->metadata, "absolute_start_time", abss, 0); break; case MKTAG('C','H','N','L'): if (size < 2) return AVERROR_INVALIDDATA; st->codec->channels = avio_rb16(pb); if (size < 2 + st->codec->channels * 4) return AVERROR_INVALIDDATA; st->codec->channel_layout = 0; if (st->codec->channels > FF_ARRAY_ELEMS(dsd_layout)) { avpriv_request_sample(s, "channel layout"); break; } for (i = 0; i < st->codec->channels; i++) dsd_layout[i] = avio_rl32(pb); for (i = 0; i < FF_ARRAY_ELEMS(dsd_channel_layout); i++) { const DSDLayoutDesc * d = &dsd_channel_layout[i]; if (av_get_channel_layout_nb_channels(d->layout) == st->codec->channels && !memcmp(d->dsd_layout, dsd_layout, st->codec->channels * sizeof(uint32_t))) { st->codec->channel_layout = d->layout; break; } } break; case MKTAG('C','M','P','R'): if (size < 4) return AVERROR_INVALIDDATA; tag = avio_rl32(pb); st->codec->codec_id = ff_codec_get_id(dsd_codec_tags, tag); if (!st->codec->codec_id) { av_log(s, AV_LOG_ERROR, "'%c%c%c%c' compression is not supported\n", tag&0xFF, (tag>>8)&0xFF, (tag>>16)&0xFF, (tag>>24)&0xFF); return AVERROR_PATCHWELCOME; } break; case MKTAG('F','S',' ',' '): if (size < 4) return AVERROR_INVALIDDATA; st->codec->sample_rate = avio_rb32(pb) / 8; break; case MKTAG('I','D','3',' '): id3v2_extra_meta = NULL; ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size); if (id3v2_extra_meta) { if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) { ff_id3v2_free_extra_meta(&id3v2_extra_meta); return ret; } ff_id3v2_free_extra_meta(&id3v2_extra_meta); } if (size < avio_tell(pb) - orig_pos) { av_log(s, AV_LOG_ERROR, "id3 exceeds chunk size\n"); return AVERROR_INVALIDDATA; } break; case MKTAG('L','S','C','O'): if (size < 2) return AVERROR_INVALIDDATA; config = avio_rb16(pb); if (config != 0xFFFF) { if (config < FF_ARRAY_ELEMS(dsd_loudspeaker_config)) st->codec->channel_layout = dsd_loudspeaker_config[config]; if (!st->codec->channel_layout) avpriv_request_sample(s, "loudspeaker configuration %d", config); } break; } avio_skip(pb, size - (avio_tell(pb) - orig_pos) + (size & 1)); }
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 ape_read_header(AVFormatContext * s) { AVIOContext *pb = s->pb; APEContext *ape = s->priv_data; AVStream *st; uint32_t tag; int i; int total_blocks, final_size = 0; int64_t pts, file_size; /* Skip any leading junk such as id3v2 tags */ ape->junklength = avio_tell(pb); tag = avio_rl32(pb); if (tag != MKTAG('M', 'A', 'C', ' ')) return AVERROR_INVALIDDATA; ape->fileversion = avio_rl16(pb); if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) { av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10); return AVERROR_PATCHWELCOME; } if (ape->fileversion >= 3980) { ape->padding1 = avio_rl16(pb); ape->descriptorlength = avio_rl32(pb); ape->headerlength = avio_rl32(pb); ape->seektablelength = avio_rl32(pb); ape->wavheaderlength = avio_rl32(pb); ape->audiodatalength = avio_rl32(pb); ape->audiodatalength_high = avio_rl32(pb); ape->wavtaillength = avio_rl32(pb); avio_read(pb, ape->md5, 16); /* Skip any unknown bytes at the end of the descriptor. This is for future compatibility */ if (ape->descriptorlength > 52) avio_skip(pb, ape->descriptorlength - 52); /* Read header data */ ape->compressiontype = avio_rl16(pb); ape->formatflags = avio_rl16(pb); ape->blocksperframe = avio_rl32(pb); ape->finalframeblocks = avio_rl32(pb); ape->totalframes = avio_rl32(pb); ape->bps = avio_rl16(pb); ape->channels = avio_rl16(pb); ape->samplerate = avio_rl32(pb); } else { ape->descriptorlength = 0; ape->headerlength = 32; ape->compressiontype = avio_rl16(pb); ape->formatflags = avio_rl16(pb); ape->channels = avio_rl16(pb); ape->samplerate = avio_rl32(pb); ape->wavheaderlength = avio_rl32(pb); ape->wavtaillength = avio_rl32(pb); ape->totalframes = avio_rl32(pb); ape->finalframeblocks = avio_rl32(pb); if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) { avio_skip(pb, 4); /* Skip the peak level */ ape->headerlength += 4; } if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) { ape->seektablelength = avio_rl32(pb); ape->headerlength += 4; ape->seektablelength *= sizeof(int32_t); } else ape->seektablelength = ape->totalframes * sizeof(int32_t); if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT) ape->bps = 8; else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT) ape->bps = 24; else ape->bps = 16; if (ape->fileversion >= 3950) ape->blocksperframe = 73728 * 4; else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800 && ape->compressiontype >= 4000)) ape->blocksperframe = 73728; else ape->blocksperframe = 9216; /* Skip any stored wav header */ if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER)) avio_skip(pb, ape->wavheaderlength); } if(!ape->totalframes){ av_log(s, AV_LOG_ERROR, "No frames in the file!\n"); return AVERROR(EINVAL); } if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){ av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n", ape->totalframes); return AVERROR_INVALIDDATA; } if (ape->seektablelength / sizeof(*ape->seektable) < ape->totalframes) { av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %"SIZE_SPECIFIER" vs. %"PRIu32"\n", ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); return AVERROR_INVALIDDATA; } ape->frames = av_malloc_array(ape->totalframes, sizeof(APEFrame)); if(!ape->frames) return AVERROR(ENOMEM); ape->firstframe = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength; if (ape->fileversion < 3810) ape->firstframe += ape->totalframes; ape->currentframe = 0; ape->totalsamples = ape->finalframeblocks; if (ape->totalframes > 1) ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1); if (ape->seektablelength > 0) { ape->seektable = av_mallocz(ape->seektablelength); if (!ape->seektable) return AVERROR(ENOMEM); for (i = 0; i < ape->seektablelength / sizeof(uint32_t) && !pb->eof_reached; i++) ape->seektable[i] = avio_rl32(pb); if (ape->fileversion < 3810) { ape->bittable = av_mallocz(ape->totalframes); if (!ape->bittable) return AVERROR(ENOMEM); for (i = 0; i < ape->totalframes && !pb->eof_reached; i++) ape->bittable[i] = avio_r8(pb); } if (pb->eof_reached) av_log(s, AV_LOG_WARNING, "File truncated\n"); } ape->frames[0].pos = ape->firstframe; ape->frames[0].nblocks = ape->blocksperframe; ape->frames[0].skip = 0; for (i = 1; i < ape->totalframes; i++) { ape->frames[i].pos = ape->seektable[i] + ape->junklength; ape->frames[i].nblocks = ape->blocksperframe; ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; } ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; /* calculate final packet size from total file size, if available */ file_size = avio_size(pb); if (file_size > 0) { final_size = file_size - ape->frames[ape->totalframes - 1].pos - ape->wavtaillength; final_size -= final_size & 3; } if (file_size <= 0 || final_size <= 0) final_size = ape->finalframeblocks * 8; ape->frames[ape->totalframes - 1].size = final_size; for (i = 0; i < ape->totalframes; i++) { if(ape->frames[i].skip){ ape->frames[i].pos -= ape->frames[i].skip; ape->frames[i].size += ape->frames[i].skip; } ape->frames[i].size = (ape->frames[i].size + 3) & ~3; } if (ape->fileversion < 3810) { for (i = 0; i < ape->totalframes; i++) { if (i < ape->totalframes - 1 && ape->bittable[i + 1]) ape->frames[i].size += 4; ape->frames[i].skip <<= 3; ape->frames[i].skip += ape->bittable[i]; } } ape_dumpinfo(s, ape); av_log(s, AV_LOG_VERBOSE, "Decoding file - v%d.%02d, compression level %"PRIu16"\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10, ape->compressiontype); /* now we are ready: build format streams */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_APE; st->codec->codec_tag = MKTAG('A', 'P', 'E', ' '); st->codec->channels = ape->channels; st->codec->sample_rate = ape->samplerate; st->codec->bits_per_coded_sample = ape->bps; st->nb_frames = ape->totalframes; st->start_time = 0; st->duration = total_blocks; avpriv_set_pts_info(st, 64, 1, ape->samplerate); if (ff_alloc_extradata(st->codec, APE_EXTRADATA_SIZE)) return AVERROR(ENOMEM); AV_WL16(st->codec->extradata + 0, ape->fileversion); AV_WL16(st->codec->extradata + 2, ape->compressiontype); AV_WL16(st->codec->extradata + 4, ape->formatflags); pts = 0; for (i = 0; i < ape->totalframes; i++) { ape->frames[i].pts = pts; av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME); pts += ape->blocksperframe; } /* try to read APE tags */ if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, 0, SEEK_SET); } return 0; }
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb, RMDemuxContext *rm, RMStream *vst, AVPacket *pkt, int len, int *pseq, int64_t *timestamp) { int hdr, seq, pic_num, len2, pos; int type; hdr = avio_r8(pb); len--; type = hdr >> 6; if(type != 3){ // not frame as a part of packet seq = avio_r8(pb); len--; } if(type != 1){ // not whole frame len2 = get_num(pb, &len); pos = get_num(pb, &len); pic_num = avio_r8(pb); len--; } if(len<0) return -1; rm->remaining_len = len; if(type&1){ // frame, not slice if(type == 3){ // frame as a part of packet len= len2; *timestamp = pos; } if(rm->remaining_len < len) return -1; rm->remaining_len -= len; if(av_new_packet(pkt, len + 9) < 0) return AVERROR(EIO); pkt->data[0] = 0; AV_WL32(pkt->data + 1, 1); AV_WL32(pkt->data + 5, 0); avio_read(pb, pkt->data + 9, len); return 0; } //now we have to deal with single slice *pseq = seq; if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ vst->slices = ((hdr & 0x3F) << 1) + 1; vst->videobufsize = len2 + 8*vst->slices + 1; av_free_packet(&vst->pkt); //FIXME this should be output. if(av_new_packet(&vst->pkt, vst->videobufsize) < 0) return AVERROR(ENOMEM); vst->videobufpos = 8*vst->slices + 1; vst->cur_slice = 0; vst->curpic_num = pic_num; vst->pktpos = avio_tell(pb); } if(type == 2) len = FFMIN(len, pos); if(++vst->cur_slice > vst->slices) return 1; AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1); AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); if(vst->videobufpos + len > vst->videobufsize) return 1; if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len) return AVERROR(EIO); vst->videobufpos += len; rm->remaining_len-= len; if (type == 2 || vst->videobufpos == vst->videobufsize) { vst->pkt.data[0] = vst->cur_slice-1; *pkt= vst->pkt; vst->pkt.data= NULL; vst->pkt.size= 0; vst->pkt.buf = NULL; #if FF_API_DESTRUCT_PACKET vst->pkt.destruct = NULL; #endif if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, vst->videobufpos - 1 - 8*vst->slices); pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices); pkt->pts = AV_NOPTS_VALUE; pkt->pos = vst->pktpos; vst->slices = 0; return 0; } return 1; }
static int yuv4_read_header(AVFormatContext *s) { char header[MAX_YUV4_HEADER + 10]; // Include headroom for // the longest option char *tokstart, *tokend, *header_end; int i; AVIOContext *pb = s->pb; int width = -1, height = -1, raten = 0, rated = 0, aspectn = 0, aspectd = 0; enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE, alt_pix_fmt = AV_PIX_FMT_NONE; enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; enum AVFieldOrder field_order = AV_FIELD_UNKNOWN; AVStream *st; for (i = 0; i < MAX_YUV4_HEADER; i++) { header[i] = avio_r8(pb); if (header[i] == '\n') { header[i + 1] = 0x20; // Add a space after last option. // Makes parsing "444" vs "444alpha" easier. header[i + 2] = 0; break; } } if (i == MAX_YUV4_HEADER) return -1; if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC))) return -1; header_end = &header[i + 1]; // Include space for (tokstart = &header[strlen(Y4M_MAGIC) + 1]; tokstart < header_end; tokstart++) { if (*tokstart == 0x20) continue; switch (*tokstart++) { case 'W': // Width. Required. width = strtol(tokstart, &tokend, 10); tokstart = tokend; break; case 'H': // Height. Required. height = strtol(tokstart, &tokend, 10); tokstart = tokend; break; case 'C': // Color space if (strncmp("420jpeg", tokstart, 7) == 0) { pix_fmt = AV_PIX_FMT_YUV420P; chroma_sample_location = AVCHROMA_LOC_CENTER; } else if (strncmp("420mpeg2", tokstart, 8) == 0) { pix_fmt = AV_PIX_FMT_YUV420P; chroma_sample_location = AVCHROMA_LOC_LEFT; } else if (strncmp("420paldv", tokstart, 8) == 0) { pix_fmt = AV_PIX_FMT_YUV420P; chroma_sample_location = AVCHROMA_LOC_TOPLEFT; } else if (strncmp("420p16", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV420P16; } else if (strncmp("422p16", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV422P16; } else if (strncmp("444p16", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV444P16; } else if (strncmp("420p14", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV420P14; } else if (strncmp("422p14", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV422P14; } else if (strncmp("444p14", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV444P14; } else if (strncmp("420p12", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV420P12; } else if (strncmp("422p12", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV422P12; } else if (strncmp("444p12", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV444P12; } else if (strncmp("420p10", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV420P10; } else if (strncmp("422p10", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV422P10; } else if (strncmp("444p10", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_YUV444P10; } else if (strncmp("420p9", tokstart, 5) == 0) { pix_fmt = AV_PIX_FMT_YUV420P9; } else if (strncmp("422p9", tokstart, 5) == 0) { pix_fmt = AV_PIX_FMT_YUV422P9; } else if (strncmp("444p9", tokstart, 5) == 0) { pix_fmt = AV_PIX_FMT_YUV444P9; } else if (strncmp("420", tokstart, 3) == 0) { pix_fmt = AV_PIX_FMT_YUV420P; chroma_sample_location = AVCHROMA_LOC_CENTER; } else if (strncmp("411", tokstart, 3) == 0) { pix_fmt = AV_PIX_FMT_YUV411P; } else if (strncmp("422", tokstart, 3) == 0) { pix_fmt = AV_PIX_FMT_YUV422P; } else if (strncmp("444alpha", tokstart, 8) == 0 ) { av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 " "YUV4MPEG stream.\n"); return -1; } else if (strncmp("444", tokstart, 3) == 0) { pix_fmt = AV_PIX_FMT_YUV444P; } else if (strncmp("mono16", tokstart, 6) == 0) { pix_fmt = AV_PIX_FMT_GRAY16; } else if (strncmp("mono", tokstart, 4) == 0) { pix_fmt = AV_PIX_FMT_GRAY8; } else { av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown " "pixel format.\n"); return -1; } while (tokstart < header_end && *tokstart != 0x20) tokstart++; break; case 'I': // Interlace type switch (*tokstart++){ case '?': field_order = AV_FIELD_UNKNOWN; break; case 'p': field_order = AV_FIELD_PROGRESSIVE; break; case 't': field_order = AV_FIELD_TT; break; case 'b': field_order = AV_FIELD_BB; break; case 'm': av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed " "interlaced and non-interlaced frames.\n"); default: av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n"); return AVERROR(EINVAL); } break; case 'F': // Frame rate sscanf(tokstart, "%d:%d", &raten, &rated); // 0:0 if unknown while (tokstart < header_end && *tokstart != 0x20) tokstart++; break; case 'A': // Pixel aspect sscanf(tokstart, "%d:%d", &aspectn, &aspectd); // 0:0 if unknown while (tokstart < header_end && *tokstart != 0x20) tokstart++; break; case 'X': // Vendor extensions if (strncmp("YSCSS=", tokstart, 6) == 0) { // Older nonstandard pixel format representation tokstart += 6; if (strncmp("420JPEG", tokstart, 7) == 0) alt_pix_fmt = AV_PIX_FMT_YUV420P; else if (strncmp("420MPEG2", tokstart, 8) == 0) alt_pix_fmt = AV_PIX_FMT_YUV420P; else if (strncmp("420PALDV", tokstart, 8) == 0) alt_pix_fmt = AV_PIX_FMT_YUV420P; else if (strncmp("420P9", tokstart, 5) == 0) alt_pix_fmt = AV_PIX_FMT_YUV420P9; else if (strncmp("422P9", tokstart, 5) == 0) alt_pix_fmt = AV_PIX_FMT_YUV422P9; else if (strncmp("444P9", tokstart, 5) == 0) alt_pix_fmt = AV_PIX_FMT_YUV444P9; else if (strncmp("420P10", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV420P10; else if (strncmp("422P10", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV422P10; else if (strncmp("444P10", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV444P10; else if (strncmp("420P12", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV420P12; else if (strncmp("422P12", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV422P12; else if (strncmp("444P12", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV444P12; else if (strncmp("420P14", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV420P14; else if (strncmp("422P14", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV422P14; else if (strncmp("444P14", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV444P14; else if (strncmp("420P16", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV420P16; else if (strncmp("422P16", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV422P16; else if (strncmp("444P16", tokstart, 6) == 0) alt_pix_fmt = AV_PIX_FMT_YUV444P16; else if (strncmp("411", tokstart, 3) == 0) alt_pix_fmt = AV_PIX_FMT_YUV411P; else if (strncmp("422", tokstart, 3) == 0) alt_pix_fmt = AV_PIX_FMT_YUV422P; else if (strncmp("444", tokstart, 3) == 0) alt_pix_fmt = AV_PIX_FMT_YUV444P; } while (tokstart < header_end && *tokstart != 0x20) tokstart++; break; } } if (width == -1 || height == -1) { av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n"); return -1; } if (pix_fmt == AV_PIX_FMT_NONE) { if (alt_pix_fmt == AV_PIX_FMT_NONE) pix_fmt = AV_PIX_FMT_YUV420P; else pix_fmt = alt_pix_fmt; } if (raten <= 0 || rated <= 0) { // Frame rate unknown raten = 25; rated = 1; } if (aspectn == 0 && aspectd == 0) { // Pixel aspect unknown aspectd = 1; } st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->width = width; st->codec->height = height; av_reduce(&raten, &rated, raten, rated, (1UL << 31) - 1); avpriv_set_pts_info(st, 64, rated, raten); st->avg_frame_rate = av_inv_q(st->time_base); st->codec->pix_fmt = pix_fmt; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; st->sample_aspect_ratio = (AVRational){ aspectn, aspectd }; st->codec->chroma_sample_location = chroma_sample_location; st->codec->field_order = field_order; s->packet_size = av_image_get_buffer_size(st->codec->pix_fmt, width, height, 1) + Y4M_FRAME_MAGIC_LEN; if ((int) s->packet_size < 0) return s->packet_size; s->internal->data_offset = avio_tell(pb); st->duration = (avio_size(pb) - avio_tell(pb)) / s->packet_size; return 0; }
int ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int get_height) { AVIOContext *pb = avctx->pb; char buf[36]; int datatype, filetype, t1, t2, nb_comments; uint64_t start_pos = avio_size(pb) - 128; avio_seek(pb, start_pos, SEEK_SET); if (avio_read(pb, buf, 7) != 7) return -1; if (memcmp(buf, "SAUCE00", 7)) return -1; #define GET_SAUCE_META(name,size) \ if (avio_read(pb, buf, size) == size && buf[0]) { \ buf[size] = 0; \ av_dict_set(&avctx->metadata, name, buf, 0); \ } GET_SAUCE_META("title", 35) GET_SAUCE_META("artist", 20) GET_SAUCE_META("publisher", 20) GET_SAUCE_META("date", 8) avio_skip(pb, 4); datatype = avio_r8(pb); filetype = avio_r8(pb); t1 = avio_rl16(pb); t2 = avio_rl16(pb); nb_comments = avio_r8(pb); avio_skip(pb, 1); /* flags */ avio_skip(pb, 4); GET_SAUCE_META("encoder", 22); if (got_width && datatype && filetype) { if ((datatype == 1 && filetype <=2) || (datatype == 5 && filetype == 255) || datatype == 6) { if (t1) { avctx->streams[0]->codecpar->width = t1<<3; *got_width = 1; } if (get_height && t2) avctx->streams[0]->codecpar->height = t2<<4; } else if (datatype == 5) { if (filetype > 1) { avctx->streams[0]->codecpar->width = (filetype == 1 ? t1 : filetype) << 4; *got_width = 1; } if (get_height && t2) avctx->streams[0]->codecpar->height = t2<<4; } } *fsize -= 128; if (nb_comments > 0) { avio_seek(pb, start_pos - 64*nb_comments - 5, SEEK_SET); if (avio_read(pb, buf, 5) == 5 && !memcmp(buf, "COMNT", 5)) { int i; char *str = av_malloc(65*nb_comments + 1); *fsize -= 64*nb_comments + 5; if (!str) return 0; for (i = 0; i < nb_comments; i++) { if (avio_read(pb, str + 65*i, 64) != 64) break; str[65*i + 64] = '\n'; } str[65*i] = 0; av_dict_set(&avctx->metadata, "comment", str, AV_DICT_DONT_STRDUP_VAL); } } return 0; }
/** * @brief read until we found all data needed for decoding * @param vst video stream of which to change parameters * @param ast video stream of which to change parameters * @param myth set if this is a MythTV Video format file * @return 1 if all required codec data was found */ static int get_codec_data(AVIOContext *pb, AVStream *vst, AVStream *ast, int myth) { nuv_frametype frametype; if (!vst && !myth) return 1; // no codec data needed while (!url_feof(pb)) { int size, subtype; frametype = avio_r8(pb); switch (frametype) { case NUV_EXTRADATA: subtype = avio_r8(pb); avio_skip(pb, 6); size = PKTSIZE(avio_rl32(pb)); if (vst && subtype == 'R') { vst->codec->extradata_size = size; vst->codec->extradata = av_malloc(size); avio_read(pb, vst->codec->extradata, size); size = 0; if (!myth) return 1; } break; case NUV_MYTHEXT: avio_skip(pb, 7); size = PKTSIZE(avio_rl32(pb)); if (size != 128 * 4) break; avio_rl32(pb); // version if (vst) { vst->codec->codec_tag = avio_rl32(pb); vst->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, vst->codec->codec_tag); if (vst->codec->codec_tag == MKTAG('R', 'J', 'P', 'G')) vst->codec->codec_id = CODEC_ID_NUV; } else avio_skip(pb, 4); if (ast) { ast->codec->codec_tag = avio_rl32(pb); ast->codec->sample_rate = avio_rl32(pb); ast->codec->bits_per_coded_sample = avio_rl32(pb); ast->codec->channels = avio_rl32(pb); ast->codec->codec_id = ff_wav_codec_get_id(ast->codec->codec_tag, ast->codec->bits_per_coded_sample); ast->need_parsing = AVSTREAM_PARSE_FULL; } else avio_skip(pb, 4 * 4); size -= 6 * 4; avio_skip(pb, size); return 1; case NUV_SEEKP: size = 11; break; default: avio_skip(pb, 7); size = PKTSIZE(avio_rl32(pb)); break; } avio_skip(pb, size); } return 0; }
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb, RMDemuxContext *rm, RMStream *vst, AVPacket *pkt, int len, int *pseq, int64_t *timestamp) { int hdr; int seq = 0, pic_num = 0, len2 = 0, pos = 0; //init to silcense compiler warning int type; int ret; hdr = avio_r8(pb); len--; type = hdr >> 6; if(type != 3){ // not frame as a part of packet seq = avio_r8(pb); len--; } if(type != 1){ // not whole frame len2 = get_num(pb, &len); pos = get_num(pb, &len); pic_num = avio_r8(pb); len--; } if(len<0) { av_log(s, AV_LOG_ERROR, "Insufficient data\n"); return -1; } rm->remaining_len = len; if(type&1){ // frame, not slice if(type == 3){ // frame as a part of packet len= len2; *timestamp = pos; } if(rm->remaining_len < len) { av_log(s, AV_LOG_ERROR, "Insufficient remaining len\n"); return -1; } rm->remaining_len -= len; if(av_new_packet(pkt, len + 9) < 0) return AVERROR(EIO); pkt->data[0] = 0; AV_WL32(pkt->data + 1, 1); AV_WL32(pkt->data + 5, 0); if ((ret = avio_read(pb, pkt->data + 9, len)) != len) { av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Failed to read %d bytes\n", len); return ret < 0 ? ret : AVERROR(EIO); } return 0; } //now we have to deal with single slice *pseq = seq; if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ if (len2 > ffio_limit(pb, len2)) { av_log(s, AV_LOG_ERROR, "Impossibly sized packet\n"); return AVERROR_INVALIDDATA; } vst->slices = ((hdr & 0x3F) << 1) + 1; vst->videobufsize = len2 + 8*vst->slices + 1; av_free_packet(&vst->pkt); //FIXME this should be output. if(av_new_packet(&vst->pkt, vst->videobufsize) < 0) return AVERROR(ENOMEM); memset(vst->pkt.data, 0, vst->pkt.size); vst->videobufpos = 8*vst->slices + 1; vst->cur_slice = 0; vst->curpic_num = pic_num; vst->pktpos = avio_tell(pb); } if(type == 2) len = FFMIN(len, pos); if(++vst->cur_slice > vst->slices) { av_log(s, AV_LOG_ERROR, "cur slice %d, too large\n", vst->cur_slice); return 1; } if(!vst->pkt.data) return AVERROR(ENOMEM); AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1); AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); if(vst->videobufpos + len > vst->videobufsize) { av_log(s, AV_LOG_ERROR, "outside videobufsize\n"); return 1; } if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len) return AVERROR(EIO); vst->videobufpos += len; rm->remaining_len-= len; if (type == 2 || vst->videobufpos == vst->videobufsize) { vst->pkt.data[0] = vst->cur_slice-1; *pkt= vst->pkt; vst->pkt.data= NULL; vst->pkt.size= 0; vst->pkt.buf = NULL; #if FF_API_DESTRUCT_PACKET FF_DISABLE_DEPRECATION_WARNINGS vst->pkt.destruct = NULL; FF_ENABLE_DEPRECATION_WARNINGS #endif if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, vst->videobufpos - 1 - 8*vst->slices); pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices); pkt->pts = AV_NOPTS_VALUE; pkt->pos = vst->pktpos; vst->slices = 0; return 0; }
static int rsd_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; int i, version, start = 0x800; AVCodecContext *codec; AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avio_skip(pb, 3); // "RSD" version = avio_r8(pb) - '0'; codec = st->codec; codec->codec_type = AVMEDIA_TYPE_AUDIO; codec->codec_tag = avio_rl32(pb); codec->codec_id = ff_codec_get_id(rsd_tags, codec->codec_tag); if (!codec->codec_id) { char tag_buf[5]; av_get_codec_tag_string(tag_buf, sizeof(tag_buf), codec->codec_tag); for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) { if (codec->codec_tag == rsd_unsupported_tags[i]) { avpriv_request_sample(s, "Codec tag: %s", tag_buf); return AVERROR_PATCHWELCOME; } } av_log(s, AV_LOG_ERROR, "Unknown codec tag: %s\n", tag_buf); return AVERROR_INVALIDDATA; } codec->channels = avio_rl32(pb); if (!codec->channels) return AVERROR_INVALIDDATA; avio_skip(pb, 4); // Bit depth codec->sample_rate = avio_rl32(pb); if (!codec->sample_rate) return AVERROR_INVALIDDATA; avio_skip(pb, 4); // Unknown switch (codec->codec_id) { case AV_CODEC_ID_ADPCM_IMA_RAD: codec->block_align = 20 * codec->channels; if (pb->seekable) st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start); break; case AV_CODEC_ID_ADPCM_THP: /* RSD3GADP is mono, so only alloc enough memory to store the coeff table for a single channel. */ start = avio_rl32(pb); if (ff_get_extradata(codec, s->pb, 32) < 0) return AVERROR(ENOMEM); for (i = 0; i < 16; i++) AV_WB16(codec->extradata + i * 2, AV_RL16(codec->extradata + i * 2)); if (pb->seekable) st->duration = (avio_size(pb) - start) / 8 * 14; break; case AV_CODEC_ID_PCM_S16LE: case AV_CODEC_ID_PCM_S16BE: if (version != 4) start = avio_rl32(pb); if (pb->seekable) st->duration = (avio_size(pb) - start) / 2 / codec->channels; break; } avio_skip(pb, start - avio_tell(pb)); avpriv_set_pts_info(st, 64, 1, codec->sample_rate); return 0; }
static int seq_parse_frame_data(SeqDemuxContext *seq, AVIOContext *pb) { unsigned int offset_table[4], buffer_num[4]; TiertexSeqFrameBuffer *seq_buffer; int i, e, err; seq->current_frame_offs += SEQ_FRAME_SIZE; avio_seek(pb, seq->current_frame_offs, SEEK_SET); /* sound data */ seq->current_audio_data_offs = avio_rl16(pb); if (seq->current_audio_data_offs) { seq->current_audio_data_size = SEQ_AUDIO_BUFFER_SIZE * 2; } else { seq->current_audio_data_size = 0; } /* palette data */ seq->current_pal_data_offs = avio_rl16(pb); if (seq->current_pal_data_offs) { seq->current_pal_data_size = 768; } else { seq->current_pal_data_size = 0; } /* video data */ for (i = 0; i < 4; i++) buffer_num[i] = avio_r8(pb); for (i = 0; i < 4; i++) offset_table[i] = avio_rl16(pb); for (i = 0; i < 3; i++) { if (offset_table[i]) { for (e = i + 1; e < 3 && offset_table[e] == 0; e++); err = seq_fill_buffer(seq, pb, buffer_num[1 + i], offset_table[i], offset_table[e] - offset_table[i]); if (err) return err; } } if (buffer_num[0] != 255) { if (buffer_num[0] >= SEQ_NUM_FRAME_BUFFERS) return AVERROR_INVALIDDATA; seq_buffer = &seq->frame_buffers[buffer_num[0]]; seq->current_video_data_size = seq_buffer->fill_size; seq->current_video_data_ptr = seq_buffer->data; seq_buffer->fill_size = 0; } else { seq->current_video_data_size = 0; seq->current_video_data_ptr = 0; } return 0; }
static int ffm2_read_header(AVFormatContext *s) { FFMContext *ffm = s->priv_data; AVStream *st; AVIOContext *pb = s->pb; AVCodecContext *codec; ffm->packet_size = avio_rb32(pb); if (ffm->packet_size != FFM_PACKET_SIZE) goto fail; ffm->write_index = avio_rb64(pb); /* get also filesize */ if (pb->seekable) { ffm->file_size = avio_size(pb); if (ffm->write_index && 0) adjust_write_index(s); } else { ffm->file_size = (UINT64_C(1) << 63) - 1; } while(!url_feof(pb)) { unsigned id = avio_rb32(pb); unsigned size = avio_rb32(pb); int64_t next = avio_tell(pb) + size; char rc_eq_buf[128]; if(!id) break; switch(id) { case MKBETAG('M', 'A', 'I', 'N'): avio_rb32(pb); /* nb_streams */ avio_rb32(pb); /* total bitrate */ break; case MKBETAG('C', 'O', 'M', 'M'): st = avformat_new_stream(s, NULL); if (!st) goto fail; avpriv_set_pts_info(st, 64, 1, 1000000); codec = st->codec; /* generic info */ codec->codec_id = avio_rb32(pb); codec->codec_type = avio_r8(pb); codec->bit_rate = avio_rb32(pb); codec->flags = avio_rb32(pb); codec->flags2 = avio_rb32(pb); codec->debug = avio_rb32(pb); if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0) return AVERROR(ENOMEM); } avio_seek(pb, next, SEEK_SET); id = avio_rb32(pb); size = avio_rb32(pb); next = avio_tell(pb) + size; switch(id) { case MKBETAG('S', 'T', 'V', 'I'): codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); codec->pix_fmt = avio_rb32(pb); codec->qmin = avio_r8(pb); codec->qmax = avio_r8(pb); codec->max_qdiff = avio_r8(pb); codec->qcompress = avio_rb16(pb) / 10000.0; codec->qblur = avio_rb16(pb) / 10000.0; codec->bit_rate_tolerance = avio_rb32(pb); avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf)); codec->rc_eq = av_strdup(rc_eq_buf); codec->rc_max_rate = avio_rb32(pb); codec->rc_min_rate = avio_rb32(pb); codec->rc_buffer_size = avio_rb32(pb); codec->i_quant_factor = av_int2double(avio_rb64(pb)); codec->b_quant_factor = av_int2double(avio_rb64(pb)); codec->i_quant_offset = av_int2double(avio_rb64(pb)); codec->b_quant_offset = av_int2double(avio_rb64(pb)); codec->dct_algo = avio_rb32(pb); codec->strict_std_compliance = avio_rb32(pb); codec->max_b_frames = avio_rb32(pb); codec->mpeg_quant = avio_rb32(pb); codec->intra_dc_precision = avio_rb32(pb); codec->me_method = avio_rb32(pb); codec->mb_decision = avio_rb32(pb); codec->nsse_weight = avio_rb32(pb); codec->frame_skip_cmp = avio_rb32(pb); codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb)); codec->codec_tag = avio_rb32(pb); codec->thread_count = avio_r8(pb); codec->coder_type = avio_rb32(pb); codec->me_cmp = avio_rb32(pb); codec->me_subpel_quality = avio_rb32(pb); codec->me_range = avio_rb32(pb); codec->keyint_min = avio_rb32(pb); codec->scenechange_threshold = avio_rb32(pb); codec->b_frame_strategy = avio_rb32(pb); codec->qcompress = av_int2double(avio_rb64(pb)); codec->qblur = av_int2double(avio_rb64(pb)); codec->max_qdiff = avio_rb32(pb); codec->refs = avio_rb32(pb); break; case MKBETAG('S', 'T', 'A', 'U'): codec->sample_rate = avio_rb32(pb); codec->channels = avio_rl16(pb); codec->frame_size = avio_rl16(pb); break; } break; } avio_seek(pb, next, SEEK_SET); } /* get until end of block reached */ while ((avio_tell(pb) % ffm->packet_size) != 0) avio_r8(pb); /* init packet demux */ ffm->packet_ptr = ffm->packet; ffm->packet_end = ffm->packet; ffm->frame_offset = 0; ffm->dts = 0; ffm->read_state = READ_HEADER; ffm->first_packet = 1; return 0; fail: ffm_close(s); return -1; }
static int vid_read_packet(AVFormatContext *s, AVPacket *pkt) { BVID_DemuxContext *vid = s->priv_data; AVIOContext *pb = s->pb; unsigned char block_type; int audio_length; int ret_value; if(vid->is_finished || pb->eof_reached) return AVERROR(EIO); block_type = avio_r8(pb); switch(block_type){ case PALETTE_BLOCK: if (vid->palette) { av_log(s, AV_LOG_WARNING, "discarding unused palette\n"); av_freep(&vid->palette); } vid->palette = av_malloc(BVID_PALETTE_SIZE); if (!vid->palette) return AVERROR(ENOMEM); if (avio_read(pb, vid->palette, BVID_PALETTE_SIZE) != BVID_PALETTE_SIZE) { av_freep(&vid->palette); return AVERROR(EIO); } return vid_read_packet(s, pkt); case FIRST_AUDIO_BLOCK: avio_rl16(pb); // soundblaster DAC used for sample rate, as on specification page (link above) vid->sample_rate = 1000000 / (256 - avio_r8(pb)); case AUDIO_BLOCK: if (vid->audio_index < 0) { AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); vid->audio_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_PCM_U8; st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; st->codec->bits_per_coded_sample = 8; st->codec->sample_rate = vid->sample_rate; st->codec->bit_rate = 8 * st->codec->sample_rate; st->start_time = 0; avpriv_set_pts_info(st, 64, 1, vid->sample_rate); } audio_length = avio_rl16(pb); if ((ret_value = av_get_packet(pb, pkt, audio_length)) != audio_length) { if (ret_value < 0) return ret_value; av_log(s, AV_LOG_ERROR, "incomplete audio block\n"); return AVERROR(EIO); } pkt->stream_index = vid->audio_index; pkt->duration = audio_length; pkt->flags |= AV_PKT_FLAG_KEY; return 0; case VIDEO_P_FRAME: case VIDEO_YOFF_P_FRAME: case VIDEO_I_FRAME: return read_frame(vid, pb, pkt, block_type, s); case EOF_BLOCK: if(vid->nframes != 0) av_log(s, AV_LOG_VERBOSE, "reached terminating character but not all frames read.\n"); vid->is_finished = 1; return AVERROR(EIO); default: av_log(s, AV_LOG_ERROR, "unknown block (character = %c, decimal = %d, hex = %x)!!!\n", block_type, block_type, block_type); return AVERROR_INVALIDDATA; } }
static int ffm_read_header(AVFormatContext *s) { FFMContext *ffm = s->priv_data; AVStream *st; AVIOContext *pb = s->pb; AVCodecContext *codec; int i, nb_streams; uint32_t tag; /* header */ tag = avio_rl32(pb); if (tag == MKTAG('F', 'F', 'M', '2')) return ffm2_read_header(s); if (tag != MKTAG('F', 'F', 'M', '1')) goto fail; ffm->packet_size = avio_rb32(pb); if (ffm->packet_size != FFM_PACKET_SIZE) goto fail; ffm->write_index = avio_rb64(pb); /* get also filesize */ if (pb->seekable) { ffm->file_size = avio_size(pb); if (ffm->write_index && 0) adjust_write_index(s); } else { ffm->file_size = (UINT64_C(1) << 63) - 1; } nb_streams = avio_rb32(pb); avio_rb32(pb); /* total bitrate */ /* read each stream */ for(i=0;i<nb_streams;i++) { char rc_eq_buf[128]; st = avformat_new_stream(s, NULL); if (!st) goto fail; avpriv_set_pts_info(st, 64, 1, 1000000); codec = st->codec; /* generic info */ codec->codec_id = avio_rb32(pb); codec->codec_type = avio_r8(pb); /* codec_type */ codec->bit_rate = avio_rb32(pb); codec->flags = avio_rb32(pb); codec->flags2 = avio_rb32(pb); codec->debug = avio_rb32(pb); /* specific info */ switch(codec->codec_type) { case AVMEDIA_TYPE_VIDEO: codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); codec->pix_fmt = avio_rb32(pb); codec->qmin = avio_r8(pb); codec->qmax = avio_r8(pb); codec->max_qdiff = avio_r8(pb); codec->qcompress = avio_rb16(pb) / 10000.0; codec->qblur = avio_rb16(pb) / 10000.0; codec->bit_rate_tolerance = avio_rb32(pb); avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf)); codec->rc_eq = av_strdup(rc_eq_buf); codec->rc_max_rate = avio_rb32(pb); codec->rc_min_rate = avio_rb32(pb); codec->rc_buffer_size = avio_rb32(pb); codec->i_quant_factor = av_int2double(avio_rb64(pb)); codec->b_quant_factor = av_int2double(avio_rb64(pb)); codec->i_quant_offset = av_int2double(avio_rb64(pb)); codec->b_quant_offset = av_int2double(avio_rb64(pb)); codec->dct_algo = avio_rb32(pb); codec->strict_std_compliance = avio_rb32(pb); codec->max_b_frames = avio_rb32(pb); codec->mpeg_quant = avio_rb32(pb); codec->intra_dc_precision = avio_rb32(pb); codec->me_method = avio_rb32(pb); codec->mb_decision = avio_rb32(pb); codec->nsse_weight = avio_rb32(pb); codec->frame_skip_cmp = avio_rb32(pb); codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb)); codec->codec_tag = avio_rb32(pb); codec->thread_count = avio_r8(pb); codec->coder_type = avio_rb32(pb); codec->me_cmp = avio_rb32(pb); codec->me_subpel_quality = avio_rb32(pb); codec->me_range = avio_rb32(pb); codec->keyint_min = avio_rb32(pb); codec->scenechange_threshold = avio_rb32(pb); codec->b_frame_strategy = avio_rb32(pb); codec->qcompress = av_int2double(avio_rb64(pb)); codec->qblur = av_int2double(avio_rb64(pb)); codec->max_qdiff = avio_rb32(pb); codec->refs = avio_rb32(pb); break; case AVMEDIA_TYPE_AUDIO: codec->sample_rate = avio_rb32(pb); codec->channels = avio_rl16(pb); codec->frame_size = avio_rl16(pb); break; default: goto fail; } if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0) return AVERROR(ENOMEM); } } /* get until end of block reached */ while ((avio_tell(pb) % ffm->packet_size) != 0) avio_r8(pb); /* init packet demux */ ffm->packet_ptr = ffm->packet; ffm->packet_end = ffm->packet; ffm->frame_offset = 0; ffm->dts = 0; ffm->read_state = READ_HEADER; ffm->first_packet = 1; return 0; fail: ffm_close(s); return -1; }
/* mmf input */ static int mmf_read_header(AVFormatContext *s) { MMFContext *mmf = s->priv_data; unsigned int tag; AVIOContext *pb = s->pb; AVStream *st; int64_t size; int rate, params; tag = avio_rl32(pb); if (tag != MKTAG('M', 'M', 'M', 'D')) return -1; avio_skip(pb, 4); /* file_size */ /* Skip some unused chunks that may or may not be present */ for(;; avio_skip(pb, size)) { tag = avio_rl32(pb); size = avio_rb32(pb); if(tag == MKTAG('C','N','T','I')) continue; if(tag == MKTAG('O','P','D','A')) continue; break; } /* Tag = "ATRx", where "x" = track number */ if ((tag & 0xffffff) == MKTAG('M', 'T', 'R', 0)) { av_log(s, AV_LOG_ERROR, "MIDI like format found, unsupported\n"); return -1; } if ((tag & 0xffffff) != MKTAG('A', 'T', 'R', 0)) { av_log(s, AV_LOG_ERROR, "Unsupported SMAF chunk %08x\n", tag); return -1; } avio_r8(pb); /* format type */ avio_r8(pb); /* sequence type */ params = avio_r8(pb); /* (channel << 7) | (format << 4) | rate */ rate = mmf_rate(params & 0x0f); if(rate < 0) { av_log(s, AV_LOG_ERROR, "Invalid sample rate\n"); return -1; } avio_r8(pb); /* wave base bit */ avio_r8(pb); /* time base d */ avio_r8(pb); /* time base g */ /* Skip some unused chunks that may or may not be present */ for(;; avio_skip(pb, size)) { tag = avio_rl32(pb); size = avio_rb32(pb); if(tag == MKTAG('A','t','s','q')) continue; if(tag == MKTAG('A','s','p','I')) continue; break; } /* Make sure it's followed by an Awa chunk, aka wave data */ if ((tag & 0xffffff) != MKTAG('A', 'w', 'a', 0)) { av_log(s, AV_LOG_ERROR, "Unexpected SMAF chunk %08x\n", tag); return -1; } mmf->data_size = size; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_ADPCM_YAMAHA; st->codec->sample_rate = rate; st->codec->channels = 1; st->codec->bits_per_coded_sample = 4; st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); return 0; }
static int ipmovie_read_header(AVFormatContext *s, AVFormatParameters *ap) { IPMVEContext *ipmovie = s->priv_data; AVIOContext *pb = s->pb; AVPacket pkt; AVStream *st; unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; int chunk_type; uint8_t signature_buffer[sizeof(signature)]; avio_read(pb, signature_buffer, sizeof(signature_buffer)); while (memcmp(signature_buffer, signature, sizeof(signature))) { memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1); signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb); if (url_feof(pb)) return AVERROR_EOF; } /* initialize private context members */ ipmovie->video_pts = ipmovie->audio_frame_count = 0; ipmovie->audio_chunk_offset = ipmovie->video_chunk_offset = ipmovie->decode_map_chunk_offset = 0; /* on the first read, this will position the stream at the first chunk */ ipmovie->next_chunk_offset = avio_tell(pb) + 4; /* process the first chunk which should be CHUNK_INIT_VIDEO */ if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO) return AVERROR_INVALIDDATA; /* peek ahead to the next chunk-- if it is an init audio chunk, process * it; if it is the first video chunk, this is a silent file */ if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) != CHUNK_PREAMBLE_SIZE) return AVERROR(EIO); chunk_type = AV_RL16(&chunk_preamble[2]); avio_seek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR); if (chunk_type == CHUNK_VIDEO) ipmovie->audio_type = CODEC_ID_NONE; /* no audio */ else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO) return AVERROR_INVALIDDATA; /* initialize the stream decoders */ st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); av_set_pts_info(st, 63, 1, 1000000); ipmovie->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_INTERPLAY_VIDEO; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = ipmovie->video_width; st->codec->height = ipmovie->video_height; st->codec->bits_per_coded_sample = ipmovie->video_bpp; if (ipmovie->audio_type) { st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); av_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate); ipmovie->audio_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = ipmovie->audio_type; st->codec->codec_tag = 0; /* no tag */ st->codec->channels = ipmovie->audio_channels; st->codec->sample_rate = ipmovie->audio_sample_rate; st->codec->bits_per_coded_sample = ipmovie->audio_bits; st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; if (st->codec->codec_id == CODEC_ID_INTERPLAY_DPCM) st->codec->bit_rate /= 2; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; } return 0; }
static int read_header(AVFormatContext *s) { AnmDemuxContext *anm = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; int i, ret; avio_skip(pb, 4); /* magic number */ if (avio_rl16(pb) != MAX_PAGES) { avpriv_request_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES)); return AVERROR_PATCHWELCOME; } anm->nb_pages = avio_rl16(pb); anm->nb_records = avio_rl32(pb); avio_skip(pb, 2); /* max records per page */ anm->page_table_offset = avio_rl16(pb); if (avio_rl32(pb) != ANIM_TAG) return AVERROR_INVALIDDATA; /* video stream */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_ANM; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = avio_rl16(pb); st->codec->height = avio_rl16(pb); if (avio_r8(pb) != 0) goto invalid; avio_skip(pb, 1); /* frame rate multiplier info */ /* ignore last delta record (used for looping) */ if (avio_r8(pb)) /* has_last_delta */ anm->nb_records = FFMAX(anm->nb_records - 1, 0); avio_skip(pb, 1); /* last_delta_valid */ if (avio_r8(pb) != 0) goto invalid; if (avio_r8(pb) != 1) goto invalid; avio_skip(pb, 1); /* other recs per frame */ if (avio_r8(pb) != 1) goto invalid; avio_skip(pb, 32); /* record_types */ st->nb_frames = avio_rl32(pb); avpriv_set_pts_info(st, 64, 1, avio_rl16(pb)); avio_skip(pb, 58); /* color cycling and palette data */ st->codec->extradata_size = 16*8 + 4*256; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { return AVERROR(ENOMEM); } ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size); if (ret < 0) return ret; /* read page table */ ret = avio_seek(pb, anm->page_table_offset, SEEK_SET); if (ret < 0) return ret; for (i = 0; i < MAX_PAGES; i++) { Page *p = &anm->pt[i]; p->base_record = avio_rl16(pb); p->nb_records = avio_rl16(pb); p->size = avio_rl16(pb); } /* find page of first frame */ anm->page = find_record(anm, 0); if (anm->page < 0) { return anm->page; } anm->record = -1; return 0; invalid: avpriv_request_sample(s, "Invalid header element"); return AVERROR_PATCHWELCOME; }
static int read_header(AVFormatContext *s) { BRSTMDemuxContext *b = s->priv_data; int bom, major, minor, codec, chunk; int64_t pos, h1offset, toffset; uint32_t size, start, asize; AVStream *st; int ret = AVERROR_EOF; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; avio_skip(s->pb, 4); bom = avio_rb16(s->pb); if (bom != 0xFEFF && bom != 0xFFFE) { av_log(s, AV_LOG_ERROR, "invalid byte order: %X\n", bom); return AVERROR_INVALIDDATA; } if (bom == 0xFFFE) { av_log_ask_for_sample(s, "unsupported byte order"); return AVERROR_PATCHWELCOME; } major = avio_r8(s->pb); minor = avio_r8(s->pb); avio_skip(s->pb, 4); // size of file size = avio_rb16(s->pb); if (size < 14) return AVERROR_INVALIDDATA; avio_skip(s->pb, size - 14); pos = avio_tell(s->pb); if (avio_rl32(s->pb) != MKTAG('H','E','A','D')) return AVERROR_INVALIDDATA; size = avio_rb32(s->pb); if (size < 256) return AVERROR_INVALIDDATA; avio_skip(s->pb, 4); // unknown h1offset = avio_rb32(s->pb); if (h1offset > size) return AVERROR_INVALIDDATA; avio_skip(s->pb, 12); toffset = avio_rb32(s->pb) + 16LL; if (toffset > size) return AVERROR_INVALIDDATA; avio_skip(s->pb, pos + h1offset + 8 - avio_tell(s->pb)); codec = avio_r8(s->pb); switch (codec) { case 0: codec = AV_CODEC_ID_PCM_S8_PLANAR; break; case 1: codec = AV_CODEC_ID_PCM_S16BE_PLANAR; break; case 2: codec = AV_CODEC_ID_ADPCM_THP; break; default: av_log_ask_for_sample(s, "unsupported codec: %d", codec); return AVERROR_PATCHWELCOME; } avio_skip(s->pb, 1); // loop flag st->codec->codec_id = codec; st->codec->channels = avio_r8(s->pb); if (!st->codec->channels) return AVERROR_INVALIDDATA; avio_skip(s->pb, 1); // padding st->codec->sample_rate = avio_rb16(s->pb); if (!st->codec->sample_rate) return AVERROR_INVALIDDATA; avio_skip(s->pb, 2); // padding avio_skip(s->pb, 4); // loop start sample st->start_time = 0; st->duration = avio_rb32(s->pb); avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); start = avio_rb32(s->pb); b->current_block = 0; b->block_count = avio_rb32(s->pb); if (b->block_count > UINT16_MAX) { av_log(s, AV_LOG_WARNING, "too many blocks: %u\n", b->block_count); return AVERROR_INVALIDDATA; } b->block_size = avio_rb32(s->pb); if (b->block_size > UINT16_MAX / st->codec->channels) return AVERROR_INVALIDDATA; b->block_size *= st->codec->channels; b->samples_per_block = avio_rb32(s->pb); b->last_block_used_bytes = avio_rb32(s->pb); if (b->last_block_used_bytes > UINT16_MAX / st->codec->channels) return AVERROR_INVALIDDATA; b->last_block_used_bytes *= st->codec->channels; avio_skip(s->pb, 4); // last block samples avio_skip(s->pb, 4); // last block size if (codec == AV_CODEC_ID_ADPCM_THP) { int ch; avio_skip(s->pb, pos + toffset - avio_tell(s->pb)); toffset = avio_rb32(s->pb) + 16LL; if (toffset > size) return AVERROR_INVALIDDATA; avio_skip(s->pb, pos + toffset - avio_tell(s->pb)); b->table = av_mallocz(32 * st->codec->channels); if (!b->table) return AVERROR(ENOMEM); for (ch = 0; ch < st->codec->channels; ch++) { if (avio_read(s->pb, b->table + ch * 32, 32) != 32) { ret = AVERROR_INVALIDDATA; goto fail; } avio_skip(s->pb, 24); } } if (size < (avio_tell(s->pb) - pos)) { ret = AVERROR_INVALIDDATA; goto fail; } avio_skip(s->pb, size - (avio_tell(s->pb) - pos)); while (!url_feof(s->pb)) { chunk = avio_rl32(s->pb); size = avio_rb32(s->pb); if (size < 8) { ret = AVERROR_INVALIDDATA; goto fail; } size -= 8; switch (chunk) { case MKTAG('A','D','P','C'): if (codec != AV_CODEC_ID_ADPCM_THP) goto skip; asize = b->block_count * st->codec->channels * 4; if (size < asize) { ret = AVERROR_INVALIDDATA; goto fail; } if (b->adpc) { av_log(s, AV_LOG_WARNING, "skipping additonal ADPC chunk\n"); goto skip; } else { b->adpc = av_mallocz(asize); if (!b->adpc) { ret = AVERROR(ENOMEM); goto fail; } avio_read(s->pb, b->adpc, asize); avio_skip(s->pb, size - asize); } break; case MKTAG('D','A','T','A'): if ((start < avio_tell(s->pb)) || (!b->adpc && codec == AV_CODEC_ID_ADPCM_THP)) { ret = AVERROR_INVALIDDATA; goto fail; } avio_skip(s->pb, start - avio_tell(s->pb)); return 0; default: av_log(s, AV_LOG_WARNING, "skipping unknown chunk: %X\n", chunk); skip: avio_skip(s->pb, size); } } fail: read_close(s); return ret; }
static int iff_read_header(AVFormatContext *s, AVFormatParameters *ap) { IffDemuxContext *iff = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; uint32_t chunk_id, data_size; int compression = -1; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->channels = 1; avio_skip(pb, 8); // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content st->codec->codec_tag = avio_rl32(pb); while(!url_feof(pb)) { uint64_t orig_pos; int res; const char *metadata_tag = NULL; chunk_id = avio_rl32(pb); data_size = avio_rb32(pb); orig_pos = avio_tell(pb); switch(chunk_id) { case ID_VHDR: st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (data_size < 14) return AVERROR_INVALIDDATA; avio_skip(pb, 12); st->codec->sample_rate = avio_rb16(pb); if (data_size >= 16) { avio_skip(pb, 1); compression = avio_r8(pb); } break; case ID_BODY: iff->body_pos = avio_tell(pb); iff->body_size = data_size; break; case ID_CHAN: if (data_size < 4) return AVERROR_INVALIDDATA; st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2; break; case ID_CMAP: st->codec->extradata_size = data_size; st->codec->extradata = av_malloc(data_size); if (!st->codec->extradata) return AVERROR(ENOMEM); if (avio_read(pb, st->codec->extradata, data_size) < 0) return AVERROR(EIO); break; case ID_BMHD: st->codec->codec_type = AVMEDIA_TYPE_VIDEO; if (data_size <= 8) return AVERROR_INVALIDDATA; st->codec->width = avio_rb16(pb); st->codec->height = avio_rb16(pb); avio_skip(pb, 4); // x, y offset st->codec->bits_per_coded_sample = avio_r8(pb); if (data_size >= 11) { avio_skip(pb, 1); // masking compression = avio_r8(pb); } if (data_size >= 16) { avio_skip(pb, 3); // paddding, transparent st->sample_aspect_ratio.num = avio_r8(pb); st->sample_aspect_ratio.den = avio_r8(pb); } break; case ID_ANNO: case ID_TEXT: metadata_tag = "comment"; break; case ID_AUTH: metadata_tag = "artist"; break; case ID_COPYRIGHT: metadata_tag = "copyright"; break; case ID_NAME: metadata_tag = "title"; break; } if (metadata_tag) { if ((res = get_metadata(s, metadata_tag, data_size)) < 0) { av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!", metadata_tag); return res; } } avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1)); } avio_seek(pb, iff->body_pos, SEEK_SET); switch(st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: av_set_pts_info(st, 32, 1, st->codec->sample_rate); switch(compression) { case COMP_NONE: st->codec->codec_id = CODEC_ID_PCM_S8; break; case COMP_FIB: st->codec->codec_id = CODEC_ID_8SVX_FIB; break; case COMP_EXP: st->codec->codec_id = CODEC_ID_8SVX_EXP; break; default: av_log(s, AV_LOG_ERROR, "unknown compression method\n"); return -1; } st->codec->bits_per_coded_sample = 8; st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; break; case AVMEDIA_TYPE_VIDEO: switch (compression) { case BITMAP_RAW: st->codec->codec_id = CODEC_ID_IFF_ILBM; break; case BITMAP_BYTERUN1: st->codec->codec_id = CODEC_ID_IFF_BYTERUN1; break; default: av_log(s, AV_LOG_ERROR, "unknown compression method\n"); return AVERROR_INVALIDDATA; } break; default: return -1; } return 0; }
static int ape_tag_read_field(AVFormatContext *s) { AVIOContext *pb = s->pb; uint8_t key[1024], *value; uint32_t size, flags; int i, c; size = avio_rl32(pb); /* field size */ flags = avio_rl32(pb); /* field flags */ for (i = 0; i < sizeof(key) - 1; i++) { c = avio_r8(pb); if (c < 0x20 || c > 0x7E) break; else key[i] = c; } key[i] = 0; if (c != 0) { av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key); return -1; } if (size > INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { av_log(s, AV_LOG_ERROR, "APE tag size too large.\n"); return AVERROR_INVALIDDATA; } if (flags & APE_TAG_FLAG_IS_BINARY) { uint8_t filename[1024]; enum AVCodecID id; AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); size -= avio_get_str(pb, size, filename, sizeof(filename)); if (size <= 0) { av_log(s, AV_LOG_WARNING, "Skipping binary tag '%s'.\n", key); return 0; } av_dict_set(&st->metadata, key, filename, 0); if ((id = ff_guess_image2_codec(filename)) != AV_CODEC_ID_NONE) { AVPacket pkt; int ret; ret = av_get_packet(s->pb, &pkt, size); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Error reading cover art.\n"); return ret; } st->disposition |= AV_DISPOSITION_ATTACHED_PIC; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = id; st->attached_pic = pkt; st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; } else { if (ff_get_extradata(st->codec, s->pb, size) < 0) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; } } else { value = av_malloc(size+1); if (!value) return AVERROR(ENOMEM); c = avio_read(pb, value, size); if (c < 0) { av_free(value); return c; } value[c] = 0; av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); } return 0; }
static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){ RMDemuxContext *rm = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; uint32_t state=0xFFFFFFFF; while(!avio_feof(pb)){ int len, num, i; *pos= avio_tell(pb) - 3; if(rm->remaining_len > 0){ num= rm->current_stream; len= rm->remaining_len; *timestamp = AV_NOPTS_VALUE; *flags= 0; }else{ state= (state<<8) + avio_r8(pb); if(state == MKBETAG('I', 'N', 'D', 'X')){ int n_pkts, expected_len; len = avio_rb32(pb); avio_skip(pb, 2); n_pkts = avio_rb32(pb); expected_len = 20 + n_pkts * 14; if (len == 20) /* some files don't add index entries to chunk size... */ len = expected_len; else if (len != expected_len) av_log(s, AV_LOG_WARNING, "Index size %d (%d pkts) is wrong, should be %d.\n", len, n_pkts, expected_len); len -= 14; // we already read part of the index header if(len<0) continue; goto skip; } else if (state == MKBETAG('D','A','T','A')) { av_log(s, AV_LOG_WARNING, "DATA tag in middle of chunk, file may be broken.\n"); } if(state > (unsigned)0xFFFF || state <= 12) continue; len=state - 12; state= 0xFFFFFFFF; num = avio_rb16(pb); *timestamp = avio_rb32(pb); avio_r8(pb); /* reserved */ *flags = avio_r8(pb); /* flags */ } for(i=0;i<s->nb_streams;i++) { st = s->streams[i]; if (num == st->id) break; } if (i == s->nb_streams) { skip: /* skip packet if unknown number */ avio_skip(pb, len); rm->remaining_len = 0; continue; } *stream_index= i; return len; } return -1; }
static int read_header(AVFormatContext *s) { MviDemuxContext *mvi = s->priv_data; AVIOContext *pb = s->pb; AVStream *ast, *vst; unsigned int version, frames_count, msecs_per_frame, player_version; ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); if (ff_alloc_extradata(vst->codec, 2)) return AVERROR(ENOMEM); version = avio_r8(pb); vst->codec->extradata[0] = avio_r8(pb); vst->codec->extradata[1] = avio_r8(pb); frames_count = avio_rl32(pb); msecs_per_frame = avio_rl32(pb); vst->codec->width = avio_rl16(pb); vst->codec->height = avio_rl16(pb); avio_r8(pb); ast->codec->sample_rate = avio_rl16(pb); mvi->audio_data_size = avio_rl32(pb); avio_r8(pb); player_version = avio_rl32(pb); avio_rl16(pb); avio_r8(pb); if (frames_count == 0 || mvi->audio_data_size == 0) return AVERROR_INVALIDDATA; if (version != 7 || player_version > 213) { av_log(s, AV_LOG_ERROR, "unhandled version (%d,%d)\n", version, player_version); return AVERROR_INVALIDDATA; } avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = AV_CODEC_ID_PCM_U8; ast->codec->channels = 1; ast->codec->channel_layout = AV_CH_LAYOUT_MONO; ast->codec->bits_per_coded_sample = 8; ast->codec->bit_rate = ast->codec->sample_rate * 8; avpriv_set_pts_info(vst, 64, msecs_per_frame, 1000000); vst->avg_frame_rate = av_inv_q(vst->time_base); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_MOTIONPIXELS; mvi->get_int = (vst->codec->width * vst->codec->height < (1 << 16)) ? avio_rl16 : avio_rl24; mvi->audio_frame_size = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count; if (mvi->audio_frame_size <= 1 << MVI_FRAC_BITS - 1) { av_log(s, AV_LOG_ERROR, "Invalid audio_data_size (%"PRIu32") or frames_count (%u)\n", mvi->audio_data_size, frames_count); return AVERROR_INVALIDDATA; } mvi->audio_size_counter = (ast->codec->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size; mvi->audio_size_left = mvi->audio_data_size; return 0; }