static int gxf_write_umf_packet(ByteIOContext *pb, GXFContext *ctx) { offset_t pos = url_ftell(pb); gxf_write_packet_header(pb, PKT_UMF); /* preamble */ put_byte(pb, 3); /* first and last (only) packet */ put_be32(pb, ctx->umf_length); /* data length */ ctx->umf_start_offset = url_ftell(pb); gxf_write_umf_payload(pb, ctx); gxf_write_umf_material_description(pb, ctx); ctx->umf_track_size = gxf_write_umf_track_description(pb, ctx); ctx->umf_media_size = gxf_write_umf_media_description(pb, ctx); ctx->umf_user_data_size = gxf_write_umf_user_data(pb, ctx); ctx->umf_length = url_ftell(pb) - ctx->umf_start_offset; return updatePacketSize(pb, pos); }
static int gxf_write_umf_track_description(AVFormatContext *s) { AVIOContext *pb = s->pb; GXFContext *gxf = s->priv_data; int64_t pos = url_ftell(pb); int i; gxf->umf_track_offset = pos - gxf->umf_start_offset; for (i = 0; i < s->nb_streams; ++i) { GXFStreamContext *sc = s->streams[i]->priv_data; avio_wl16(pb, sc->media_info); avio_wl16(pb, 1); } avio_wl16(pb, gxf->timecode_track.media_info); avio_wl16(pb, 1); return url_ftell(pb) - pos; }
static int64_t updateSize(AVIOContext *pb, int64_t pos) { int64_t curpos; curpos = url_ftell(pb); avio_seek(pb, pos, SEEK_SET); avio_wb16(pb, curpos - pos - 2); avio_seek(pb, curpos, SEEK_SET); return curpos - pos; }
static offset_t updateSize(ByteIOContext *pb, offset_t pos) { offset_t curpos; curpos = url_ftell(pb); url_fseek(pb, pos, SEEK_SET); put_be16(pb, curpos - pos - 2); url_fseek(pb, curpos, SEEK_SET); return curpos - pos; }
static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt) { GXFContext *gxf = s->priv_data; ByteIOContext *pb = s->pb; AVStream *st = s->streams[pkt->stream_index]; int64_t pos = url_ftell(pb); int padding = 0; int packet_start_offset = url_ftell(pb) / 1024; gxf_write_packet_header(pb, PKT_MEDIA); if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */ padding = 4 - pkt->size % 4; else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) padding = GXF_AUDIO_PACKET_SIZE - pkt->size; gxf_write_media_preamble(s, pkt, pkt->size + padding); put_buffer(pb, pkt->data, pkt->size); gxf_write_padding(pb, padding); if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { if (!(gxf->flt_entries_nb % 500)) { gxf->flt_entries = av_realloc(gxf->flt_entries, (gxf->flt_entries_nb+500)*sizeof(*gxf->flt_entries)); if (!gxf->flt_entries) { av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n"); return -1; } } gxf->flt_entries[gxf->flt_entries_nb++] = packet_start_offset; gxf->nb_fields += 2; // count fields } updatePacketSize(pb, pos); gxf->packet_count++; if (gxf->packet_count == 100) { gxf_write_map_packet(s, 0); gxf->packet_count = 0; } put_flush_packet(pb); return 0; }
static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb) { WVContext *wc = ctx->priv_data; uint32_t tag, ver; int size; int rate, bpp, chan; wc->pos = url_ftell(pb); tag = get_le32(pb); if (tag != MKTAG('w', 'v', 'p', 'k')) return -1; size = get_le32(pb); if(size < 24 || size > WV_BLOCK_LIMIT){ av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size); return -1; } wc->blksize = size; ver = get_le16(pb); if(ver < 0x402 || ver > 0x410){ av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return -1; } get_byte(pb); // track no get_byte(pb); // track sub index wc->samples = get_le32(pb); // total samples in file wc->soff = get_le32(pb); // offset in samples of current block get_buffer(pb, wc->extra, WV_EXTRA_SIZE); wc->flags = AV_RL32(wc->extra + 4); //parse flags bpp = ((wc->flags & 3) + 1) << 3; chan = 1 + !(wc->flags & WV_MONO); rate = wv_rates[(wc->flags >> 23) & 0xF]; if(rate == -1){ av_log(ctx, AV_LOG_ERROR, "Unknown sampling rate\n"); return -1; } if(!wc->bpp) wc->bpp = bpp; if(!wc->chan) wc->chan = chan; if(!wc->rate) wc->rate = rate; if(wc->flags && bpp != wc->bpp){ av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp); return -1; } if(wc->flags && chan != wc->chan){ av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan); return -1; } if(wc->flags && rate != wc->rate){ av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate); return -1; } wc->blksize = size - 24; return 0; }
AVParserState *ff_store_parser_state(AVFormatContext *s) { int i; AVStream *st; AVParserStreamState *ss; AVParserState *state = av_malloc(sizeof(AVParserState)); if (!state) return NULL; state->stream_states = av_malloc(sizeof(AVParserStreamState) * s->nb_streams); if (!state->stream_states) { av_free(state); return NULL; } state->fpos = url_ftell(s->pb); // copy context structures state->cur_st = s->cur_st; state->packet_buffer = s->packet_buffer; state->raw_packet_buffer = s->raw_packet_buffer; state->raw_packet_buffer_remaining_size = s->raw_packet_buffer_remaining_size; s->cur_st = NULL; s->packet_buffer = NULL; s->raw_packet_buffer = NULL; s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; // copy stream structures state->nb_streams = s->nb_streams; for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; ss = &state->stream_states[i]; ss->parser = st->parser; ss->last_IP_pts = st->last_IP_pts; ss->cur_dts = st->cur_dts; ss->reference_dts = st->reference_dts; ss->cur_ptr = st->cur_ptr; ss->cur_len = st->cur_len; ss->probe_packets = st->probe_packets; ss->cur_pkt = st->cur_pkt; st->parser = NULL; st->last_IP_pts = AV_NOPTS_VALUE; st->cur_dts = AV_NOPTS_VALUE; st->reference_dts = AV_NOPTS_VALUE; st->cur_ptr = NULL; st->cur_len = 0; st->probe_packets = MAX_PROBE_PACKETS; av_init_packet(&st->cur_pkt); } return state; }
static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index) { ByteIOContext *pb = s->pb; int64_t pos; int mpeg = sc->track_type == 4 || sc->track_type == 9; /* track description section */ put_byte(pb, sc->media_type + 0x80); put_byte(pb, index + 0xC0); pos = url_ftell(pb); put_be16(pb, 0); /* size */ /* media file name */ put_byte(pb, TRACK_NAME); put_byte(pb, strlen(ES_NAME_PATTERN) + 3); put_tag(pb, ES_NAME_PATTERN); put_be16(pb, sc->media_info); put_byte(pb, 0); if (!mpeg) { /* auxiliary information */ put_byte(pb, TRACK_AUX); put_byte(pb, 8); if (sc->track_type == 3) gxf_write_timecode_auxiliary(pb, sc); else put_le64(pb, 0); } /* file system version */ put_byte(pb, TRACK_VER); put_byte(pb, 4); put_be32(pb, 0); if (mpeg) gxf_write_mpeg_auxiliary(pb, s->streams[index]); /* frame rate */ put_byte(pb, TRACK_FPS); put_byte(pb, 4); put_be32(pb, sc->frame_rate_index); /* lines per frame */ put_byte(pb, TRACK_LINES); put_byte(pb, 4); put_be32(pb, sc->lines_index); /* fields per frame */ put_byte(pb, TRACK_FPF); put_byte(pb, 4); put_be32(pb, sc->fields); return updateSize(pb, pos); }
static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) { AVStream *st = s->streams[1]; int tmp, tmp2, samples, size; uint64_t pos = url_ftell(s->pb); unsigned dts; dts = get_be32(s->pb); st->codec->sample_rate = get_be32(s->pb); samples = get_be32(s->pb); tmp = get_be32(s->pb); dprintf(s, "packet num %d\n", tmp); tmp = get_be16(s->pb); // unkown dprintf(s, "unknown %d\n", tmp); tmp = get_byte(s->pb); // major version tmp2 = get_byte(s->pb); // minor version dprintf(s, "version %d.%d\n", tmp, tmp2); tmp = get_be32(s->pb); // unknown dprintf(s, "unknown %d\n", tmp); size = atom->size - 8 - (url_ftell(s->pb) - pos); if (size < 0) return -1; if (av_get_packet(s->pb, pkt, size) != size) { av_log(s, AV_LOG_ERROR, "error reading video packet\n"); return -1; } pkt->stream_index = 1; pkt->dts = dts; pkt->duration = av_rescale(samples, st->time_base.den, st->codec->sample_rate); dprintf(s, "pkt dts %lld duration %d samples %d sample rate %d\n", pkt->dts, pkt->duration, samples, st->codec->sample_rate); return 0; }
static int gxf_write_track_description_section(ByteIOContext *pb, GXFContext *ctx) { int64_t pos; int i; pos = url_ftell(pb); put_be16(pb, 0); /* size */ for (i = 0; i < ctx->fc->nb_streams; ++i) gxf_write_track_description(pb, &ctx->streams[i]); return updateSize(pb, pos); }
/* * Process EA file header * Returns 1 if the EA file is valid and successfully opened, 0 otherwise */ static int process_ea_header(AVFormatContext *s) { uint32_t blockid, size = 0; EaDemuxContext *ea = s->priv_data; ByteIOContext *pb = &s->pb; int i; for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) { unsigned int startpos = url_ftell(pb); int err = 0; blockid = get_le32(pb); size = get_le32(pb); if (i == 0) ea->big_endian = size > 0x000FFFFF; if (ea->big_endian) size = bswap_32(size); switch (blockid) { case ISNh_TAG: if (get_le32(pb) != EACS_TAG) { av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n"); return 0; } err = process_audio_header_eacs(s); break; case SCHl_TAG : blockid = get_le32(pb); if (blockid == GSTR_TAG) { url_fskip(pb, 4); } else if (blockid != PT00_TAG) { av_log (s, AV_LOG_ERROR, "unknown SCHl headerid\n"); return 0; } err = process_audio_header_elements(s); break; case MVhd_TAG : err = process_video_header_vp6(s); break; } if (err < 0) { av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err); return err; } url_fseek(pb, startpos + size, SEEK_SET); } url_fseek(pb, 0, SEEK_SET); return 1; }
static int avs_read_audio_packet(AVFormatContext * s, AVPacket * pkt) { avs_format_t *avs = s->priv_data; int ret, size; size = url_ftell(&s->pb); ret = voc_get_packet(s, pkt, avs->st_audio, avs->remaining_audio_size); size = url_ftell(&s->pb) - size; avs->remaining_audio_size -= size; if (ret == AVERROR_IO) return 0; /* this indicate EOS */ if (ret < 0) return ret; pkt->stream_index = avs->st_audio->index; pkt->flags |= PKT_FLAG_KEY; return size; }
static int avi_write_trailer(AVFormatContext *s) { AVIContext *avi = s->priv_data; ByteIOContext *pb = s->pb; int res = 0; int i, j, n, nb_frames; int64_t file_size; if (!url_is_streamed(pb)){ if (avi->riff_id == 1) { ff_end_tag(pb, avi->movi_list); res = avi_write_idx1(s); ff_end_tag(pb, avi->riff_start); } else { avi_write_ix(s); ff_end_tag(pb, avi->movi_list); ff_end_tag(pb, avi->riff_start); file_size = url_ftell(pb); url_fseek(pb, avi->odml_list - 8, SEEK_SET); put_tag(pb, "LIST"); /* Making this AVI OpenDML one */ url_fskip(pb, 16); for (n=nb_frames=0;n<s->nb_streams;n++) { AVCodecContext *stream = s->streams[n]->codec; AVIStream *avist= s->streams[n]->priv_data; if (stream->codec_type == AVMEDIA_TYPE_VIDEO) { if (nb_frames < avist->packet_count) nb_frames = avist->packet_count; } else { if (stream->codec_id == CODEC_ID_MP2 || stream->codec_id == CODEC_ID_MP3) { nb_frames += avist->packet_count; } } } put_le32(pb, nb_frames); url_fseek(pb, file_size, SEEK_SET); avi_write_counters(s, avi->riff_id); } } put_flush_packet(pb); for (i=0; i<s->nb_streams; i++) { AVIStream *avist= s->streams[i]->priv_data; for (j=0; j<avist->indexes.ents_allocated/AVI_INDEX_CLUSTER_SIZE; j++) av_free(avist->indexes.cluster[j]); av_freep(&avist->indexes.cluster); avist->indexes.ents_allocated = avist->indexes.entry = 0; } return res; }
static int nuv_packet(AVFormatContext *s, AVPacket *pkt) { NUVContext *ctx = s->priv_data; ByteIOContext *pb = s->pb; uint8_t hdr[HDRSIZE]; frametype_t frametype; int ret, size; while (!url_feof(pb)) { int copyhdrsize = ctx->rtjpg_video ? HDRSIZE : 0; ret = get_buffer(pb, hdr, HDRSIZE); if (ret <= 0) return ret ? ret : -1; frametype = hdr[0]; size = PKTSIZE(AV_RL32(&hdr[8])); switch (frametype) { case NUV_EXTRADATA: if (!ctx->rtjpg_video) { url_fskip(pb, size); break; } case NUV_VIDEO: if (ctx->v_id < 0) { av_log(s, AV_LOG_ERROR, "Video packet in file without video stream!\n"); url_fskip(pb, size); break; } ret = av_new_packet(pkt, copyhdrsize + size); if (ret < 0) return ret; pkt->pos = url_ftell(pb) - copyhdrsize; pkt->pts = AV_RL32(&hdr[4]); pkt->stream_index = ctx->v_id; memcpy(pkt->data, hdr, copyhdrsize); ret = get_buffer(pb, pkt->data + copyhdrsize, size); return ret; case NUV_AUDIO: if (ctx->a_id < 0) { av_log(s, AV_LOG_ERROR, "Audio packet in file without audio stream!\n"); url_fskip(pb, size); break; } ret = av_get_packet(pb, pkt, size); pkt->pts = AV_RL32(&hdr[4]); pkt->stream_index = ctx->a_id; return ret; case NUV_SEEKP: // contains no data, size value is invalid break; default: url_fskip(pb, size); break; } } return AVERROR(EIO); }
static int gxf_write_umf_packet(AVFormatContext *s) { GXFContext *gxf = s->priv_data; ByteIOContext *pb = s->pb; int64_t pos = url_ftell(pb); gxf_write_packet_header(pb, PKT_UMF); /* preamble */ put_byte(pb, 3); /* first and last (only) packet */ put_be32(pb, gxf->umf_length); /* data length */ gxf->umf_start_offset = url_ftell(pb); gxf_write_umf_payload(s); gxf_write_umf_material_description(s); gxf->umf_track_size = gxf_write_umf_track_description(s); gxf->umf_media_size = gxf_write_umf_media_description(s); gxf->umf_length = url_ftell(pb) - gxf->umf_start_offset; return updatePacketSize(pb, pos); }
static int read_atom(AVFormatContext *s, Atom *atom) { atom->offset = url_ftell(s->pb); atom->size = get_be32(s->pb); if (atom->size < 8) return -1; atom->tag = get_le32(s->pb); dprintf(s, "atom %d %.4s offset %#llx\n", atom->size, (char*)&atom->tag, atom->offset); return atom->size; }
static int gxf_write_track_description(ByteIOContext *pb, GXFStreamContext *stream) { int64_t pos; /* track description section */ put_byte(pb, stream->media_type + 0x80); put_byte(pb, stream->index + 0xC0); pos = url_ftell(pb); put_be16(pb, 0); /* size */ /* media file name */ put_byte(pb, TRACK_NAME); put_byte(pb, strlen(ES_NAME_PATTERN) + 3); put_tag(pb, ES_NAME_PATTERN); put_be16(pb, stream->media_info); put_byte(pb, 0); if (stream->codec->codec_id != CODEC_ID_MPEG2VIDEO) { /* auxiliary information */ put_byte(pb, TRACK_AUX); put_byte(pb, 8); if (stream->codec->codec_id == CODEC_ID_NONE) gxf_write_timecode_auxiliary(pb, stream); else put_le64(pb, 0); } /* file system version */ put_byte(pb, TRACK_VER); put_byte(pb, 4); put_be32(pb, 0); if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO) gxf_write_mpeg_auxiliary(pb, stream); /* frame rate */ put_byte(pb, TRACK_FPS); put_byte(pb, 4); put_be32(pb, stream->frame_rate_index); /* lines per frame */ put_byte(pb, TRACK_LINES); put_byte(pb, 4); put_be32(pb, stream->lines_index); /* fields per frame */ put_byte(pb, TRACK_FPF); put_byte(pb, 4); put_be32(pb, stream->fields); return updateSize(pb, pos); }
static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) { MPCContext *c = s->priv_data; AVStream *st; if(get_le24(s->pb) != MKTAG('M', 'P', '+', 0)){ av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); return -1; } c->ver = get_byte(s->pb); if(c->ver != 0x07 && c->ver != 0x17){ av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver); return -1; } c->fcount = get_le32(s->pb); if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){ av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); return -1; } c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); c->curframe = 0; c->lastframe = -1; c->curbits = 8; c->frames_noted = 0; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_MUSEPACK7; st->codec->channels = 2; st->codec->bits_per_coded_sample = 16; st->codec->extradata_size = 16; st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); get_buffer(s->pb, st->codec->extradata, 16); st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate); /* scan for seekpoints */ st->start_time = 0; st->duration = c->fcount; /* try to read APE tags */ if (!url_is_streamed(s->pb)) { int64_t pos = url_ftell(s->pb); ff_ape_parse_tag(s); if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) ff_id3v1_read(s); url_fseek(s->pb, pos, SEEK_SET); } return 0; }
static int read_packet(AVFormatContext *s, AVPacket *pkt) { ByteIOContext *pb = s->pb; AVStream *st = s->streams[0]; CaffContext *caf = s->priv_data; int res, pkt_size = 0, pkt_frames = 0; int64_t left = CAF_MAX_PKT_SIZE; if (url_feof(pb)) return AVERROR(EIO); /* don't read past end of data chunk */ if (caf->data_size > 0) { left = (caf->data_start + caf->data_size) - url_ftell(pb); if (left <= 0) return AVERROR(EIO); } pkt_frames = caf->frames_per_packet; pkt_size = caf->bytes_per_packet; if (pkt_size > 0 && pkt_frames == 1) { pkt_size = (CAF_MAX_PKT_SIZE / pkt_size) * pkt_size; pkt_size = FFMIN(pkt_size, left); pkt_frames = pkt_size / caf->bytes_per_packet; } else if (st->nb_index_entries) { if (caf->packet_cnt < st->nb_index_entries - 1) { pkt_size = st->index_entries[caf->packet_cnt + 1].pos - st->index_entries[caf->packet_cnt].pos; pkt_frames = st->index_entries[caf->packet_cnt + 1].timestamp - st->index_entries[caf->packet_cnt].timestamp; } else if (caf->packet_cnt == st->nb_index_entries - 1) { pkt_size = caf->num_bytes - st->index_entries[caf->packet_cnt].pos; pkt_frames = st->duration - st->index_entries[caf->packet_cnt].timestamp; } else { return AVERROR(EIO); } } if (pkt_size == 0 || pkt_frames == 0 || pkt_size > left) return AVERROR(EIO); res = av_get_packet(pb, pkt, pkt_size); if (res < 0) return res; pkt->size = res; pkt->stream_index = 0; pkt->dts = pkt->pts = caf->frame_cnt; caf->packet_cnt++; caf->frame_cnt += pkt_frames; return 0; }
static int mp3_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVStream *st; uint8_t buf[ID3v1_TAG_SIZE]; int len, ret, filesize; offset_t off; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = CODEC_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_MP3; st->need_parsing = AVSTREAM_PARSE_FULL; st->start_time = 0; /* try to get the TAG */ if (!url_is_streamed(s->pb)) { /* XXX: change that */ filesize = url_fsize(s->pb); if (filesize > 128) { url_fseek(s->pb, filesize - 128, SEEK_SET); ret = get_buffer(s->pb, buf, ID3v1_TAG_SIZE); if (ret == ID3v1_TAG_SIZE) { id3v1_parse_tag(s, buf); } url_fseek(s->pb, 0, SEEK_SET); } } /* if ID3v2 header found, skip it */ ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); if (ret != ID3v2_HEADER_SIZE) return -1; if (id3v2_match(buf)) { /* parse ID3v2 header */ len = ((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f); id3v2_parse(s, len, buf[3], buf[5]); } else { url_fseek(s->pb, 0, SEEK_SET); } off = url_ftell(s->pb); mp3_parse_vbr_tags(s, st, off); url_fseek(s->pb, off, SEEK_SET); /* the parameters will be extracted from the compressed bitstream */ return 0; }
static int wav_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, size; int64_t left; AVStream *st; WAVContext *wav = s->priv_data; if (url_feof(s->pb)) return AVERROR(EIO); st = s->streams[0]; left = wav->data_end - url_ftell(s->pb); if (left <= 0){ if (CONFIG_W64_DEMUXER && wav->w64) left = find_guid(s->pb, guid_data) - 24; else left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a')); if (left < 0) return AVERROR(EIO); wav->data_end= url_ftell(s->pb) + left; } size = MAX_SIZE; if (st->codec->block_align > 1) { if (size < st->codec->block_align) size = st->codec->block_align; size = (size / st->codec->block_align) * st->codec->block_align; } size = FFMIN(size, left); ret = av_get_packet(s->pb, pkt, size); if (ret <= 0) return AVERROR(EIO); pkt->stream_index = 0; /* note: we need to modify the packet size here to handle the last packet */ pkt->size = ret; return ret; }
/* read a run length encoded sgi image */ static int read_rle_sgi(const SGIInfo *sgi_info, AVPicture *pict, ByteIOContext *f) { uint8_t *dest_row; unsigned long *start_table; int y, z, xsize, ysize, zsize, tablen; long start_offset; int ret = 0; xsize = sgi_info->xsize; ysize = sgi_info->ysize; zsize = sgi_info->zsize; /* skip header */ url_fseek(f, SGI_HEADER_SIZE, SEEK_SET); /* size of rle offset and length tables */ tablen = ysize * zsize * sizeof(long); start_table = (unsigned long *)av_malloc(tablen); if (!get_buffer(f, (uint8_t *)start_table, tablen)) { ret = AVERROR_IO; goto fail; } /* skip run length table */ url_fseek(f, tablen, SEEK_CUR); for (z = 0; z < zsize; z++) { for (y = 0; y < ysize; y++) { dest_row = pict->data[0] + (ysize - 1 - y) * (xsize * zsize); start_offset = BE_32(&start_table[y + z * ysize]); /* don't seek if already at the next rle start offset */ if (url_ftell(f) != start_offset) { url_fseek(f, start_offset, SEEK_SET); } if (expand_rle_row(f, dest_row, z, zsize) != xsize) { ret = AVERROR_INVALIDDATA; goto fail; } } } fail: av_free(start_table); return ret; }
static int qcp_read_packet(AVFormatContext *s, AVPacket *pkt) { ByteIOContext *pb = s->pb; QCPContext *c = s->priv_data; unsigned int chunk_size, tag; while(!url_feof(pb)) { if (c->data_size) { int pkt_size, ret, mode = get_byte(pb); if (s->packet_size) { pkt_size = s->packet_size - 1; } else if (mode > QCP_MAX_MODE || (pkt_size = c->rates_per_mode[mode]) < 0) { c->data_size--; continue; } if (c->data_size <= pkt_size) { av_log(s, AV_LOG_WARNING, "Data chunk is too small.\n"); pkt_size = c->data_size - 1; } if ((ret = av_get_packet(pb, pkt, pkt_size)) >= 0) { if (pkt_size != ret) av_log(s, AV_LOG_ERROR, "Packet size is too small.\n"); c->data_size -= pkt_size + 1; } return ret; } if (url_ftell(pb) & 1 && get_byte(pb)) av_log(s, AV_LOG_WARNING, "Padding should be 0.\n"); tag = get_le32(pb); chunk_size = get_le32(pb); switch (tag) { case MKTAG('v', 'r', 'a', 't'): if (get_le32(pb)) // var-rate-flag s->packet_size = 0; url_fskip(pb, 4); // size-in-packets break; case MKTAG('d', 'a', 't', 'a'): c->data_size = chunk_size; break; default: url_fskip(pb, chunk_size); } } return AVERROR_EOF; }
static int read_packet(AVFormatContext *s, AVPacket *pkt) { AnmDemuxContext *anm = s->priv_data; ByteIOContext *pb = s->pb; Page *p; int tmp, record_size; if (url_feof(s->pb)) return AVERROR(EIO); if (anm->page < 0) return 0; repeat: p = &anm->pt[anm->page]; /* parse page header */ if (anm->record < 0) { url_fseek(pb, anm->page_table_offset + MAX_PAGES*6 + (anm->page<<16), SEEK_SET); url_fskip(pb, 8 + 2*p->nb_records); anm->record = 0; } /* if we have fetched all records in this page, then find the next page and repeat */ if (anm->record >= p->nb_records) { anm->page = find_record(anm, p->base_record + p->nb_records); if (anm->page < 0) return anm->page; anm->record = -1; goto repeat; } /* fetch record size */ tmp = url_ftell(pb); url_fseek(pb, anm->page_table_offset + MAX_PAGES*6 + (anm->page<<16) + 8 + anm->record * 2, SEEK_SET); record_size = get_le16(pb); url_fseek(pb, tmp, SEEK_SET); /* fetch record */ pkt->size = av_get_packet(s->pb, pkt, record_size); if (pkt->size < 0) return pkt->size; if (p->base_record + anm->record == 0) pkt->flags |= PKT_FLAG_KEY; anm->record++; return 0; }
static int iss_read_packet(AVFormatContext *s, AVPacket *pkt) { IssDemuxContext *iss = s->priv_data; int ret = av_get_packet(s->pb, pkt, iss->packet_size); if(ret != iss->packet_size) return AVERROR(EIO); pkt->stream_index = 0; pkt->pts = url_ftell(s->pb) - iss->sample_start_pos; if(s->streams[0]->codec->channels > 0) pkt->pts /= s->streams[0]->codec->channels*2; return 0; }
static int gxf_write_material_data_section(AVFormatContext *s) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; int64_t pos; int len; const char *filename = strrchr(s->filename, '/'); pos = url_ftell(pb); avio_wb16(pb, 0); /* size */ /* name */ if (filename) filename++; else filename = s->filename; len = strlen(filename); avio_w8(pb, MAT_NAME); avio_w8(pb, strlen(SERVER_PATH) + len + 1); avio_write(pb, SERVER_PATH, sizeof(SERVER_PATH) - 1); avio_write(pb, filename, len); avio_w8(pb, 0); /* first field */ avio_w8(pb, MAT_FIRST_FIELD); avio_w8(pb, 4); avio_wb32(pb, 0); /* last field */ avio_w8(pb, MAT_LAST_FIELD); avio_w8(pb, 4); avio_wb32(pb, gxf->nb_fields); /* reserved */ avio_w8(pb, MAT_MARK_IN); avio_w8(pb, 4); avio_wb32(pb, 0); avio_w8(pb, MAT_MARK_OUT); avio_w8(pb, 4); avio_wb32(pb, gxf->nb_fields); /* estimated size */ avio_w8(pb, MAT_SIZE); avio_w8(pb, 4); avio_wb32(pb, url_fsize(pb) / 1024); return updateSize(pb, pos); }
static int r3d_read_header(AVFormatContext *s, AVFormatParameters *ap) { R3DContext *r3d = s->priv_data; Atom atom; int ret; if (read_atom(s, &atom) < 0) { av_log(s, AV_LOG_ERROR, "error reading atom\n"); return -1; } if (atom.tag == MKTAG('R','E','D','1')) { if ((ret = r3d_read_red1(s)) < 0) { av_log(s, AV_LOG_ERROR, "error parsing 'red1' atom\n"); return ret; } } else { av_log(s, AV_LOG_ERROR, "could not find 'red1' atom\n"); return -1; } s->data_offset = url_ftell(s->pb); dprintf(s, "data offset %#llx\n", s->data_offset); if (url_is_streamed(s->pb)) return 0; // find REOB/REOF/REOS to load index url_fseek(s->pb, url_fsize(s->pb)-48-8, SEEK_SET); if (read_atom(s, &atom) < 0) av_log(s, AV_LOG_ERROR, "error reading end atom\n"); if (atom.tag != MKTAG('R','E','O','B') && atom.tag != MKTAG('R','E','O','F') && atom.tag != MKTAG('R','E','O','S')) goto out; r3d_read_reos(s); if (r3d->rdvo_offset) { url_fseek(s->pb, r3d->rdvo_offset, SEEK_SET); if (read_atom(s, &atom) < 0) av_log(s, AV_LOG_ERROR, "error reading 'rdvo' atom\n"); if (atom.tag == MKTAG('R','D','V','O')) { if (r3d_read_rdvo(s, &atom) < 0) av_log(s, AV_LOG_ERROR, "error parsing 'rdvo' atom\n"); } } out: url_fseek(s->pb, s->data_offset, SEEK_SET); return 0; }
static int wav_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, size, left; AVStream *st; WAVContext *wav = s->priv_data; if (url_feof(&s->pb)) return AVERROR_IO; st = s->streams[0]; left= wav->data_end - url_ftell(&s->pb); if(left <= 0){ left = find_tag(&(s->pb), MKTAG('d', 'a', 't', 'a')); if (left < 0) { return AVERROR_IO; } wav->data_end= url_ftell(&s->pb) + left; } size = MAX_SIZE; if (st->codec->block_align > 1) { if (size < st->codec->block_align) size = st->codec->block_align; size = (size / st->codec->block_align) * st->codec->block_align; } size= FFMIN(size, left); ret= av_get_packet(&s->pb, pkt, size); if (ret <= 0) return AVERROR_IO; pkt->stream_index = 0; /* note: we need to modify the packet size here to handle the last packet */ pkt->size = ret; return ret; }
static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap) { int64_t size; ByteIOContext *pb = s->pb; WAVContext *wav = s->priv_data; AVStream *st; uint8_t guid[16]; get_buffer(pb, guid, 16); if (memcmp(guid, guid_riff, 16)) return -1; if (get_le64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */ return -1; get_buffer(pb, guid, 16); if (memcmp(guid, guid_wave, 16)) { av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); return -1; } size = find_guid(pb, guid_fmt); if (size < 0) { av_log(s, AV_LOG_ERROR, "could not find fmt guid\n"); return -1; } st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); /* subtract chunk header size - normal wav file doesn't count it */ ff_get_wav_header(pb, st->codec, size - 24); url_fskip(pb, FFALIGN(size, INT64_C(8)) - size); st->need_parsing = AVSTREAM_PARSE_FULL; av_set_pts_info(st, 64, 1, st->codec->sample_rate); size = find_guid(pb, guid_data); if (size < 0) { av_log(s, AV_LOG_ERROR, "could not find data guid\n"); return -1; } wav->data_end = url_ftell(pb) + size - 24; wav->w64 = 1; return 0; }
static void put_swf_tag(AVFormatContext *s, int tag) { SWFContext *swf = s->priv_data; ByteIOContext *pb = s->pb; swf->tag_pos = url_ftell(pb); swf->tag = tag; /* reserve some room for the tag */ if (tag & TAG_LONG) { put_le16(pb, 0); put_le32(pb, 0); } else { put_le16(pb, 0); } }