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->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = AV_CODEC_ID_ANM; st->codecpar->codec_tag = 0; /* no fourcc */ st->codecpar->width = avio_rl16(pb); st->codecpar->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->codecpar->extradata_size = 16*8 + 4*256; st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!st->codecpar->extradata) { return AVERROR(ENOMEM); } ret = avio_read(pb, st->codecpar->extradata, st->codecpar->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 fourxm_read_packet(AVFormatContext *s, AVPacket *pkt) { FourxmDemuxContext *fourxm = s->priv_data; AVIOContext *pb = s->pb; unsigned int fourcc_tag; unsigned int size; int ret = 0; unsigned int track_number; int packet_read = 0; unsigned char header[8]; int audio_frame_count; while (!packet_read) { if ((ret = avio_read(s->pb, header, 8)) < 0) return ret; fourcc_tag = AV_RL32(&header[0]); size = AV_RL32(&header[4]); if (pb->eof_reached) return AVERROR(EIO); switch (fourcc_tag) { case LIST_TAG: /* this is a good time to bump the video pts */ fourxm->video_pts++; /* skip the LIST-* tag and move on to the next fourcc */ avio_rl32(pb); break; case ifrm_TAG: case pfrm_TAG: case cfrm_TAG: case ifr2_TAG: case pfr2_TAG: case cfr2_TAG: /* allocate 8 more bytes than 'size' to account for fourcc * and size */ if (size + 8 < size || av_new_packet(pkt, size + 8)) return AVERROR(EIO); pkt->stream_index = fourxm->video_stream_index; pkt->pts = fourxm->video_pts; pkt->pos = avio_tell(s->pb); memcpy(pkt->data, header, 8); ret = avio_read(s->pb, &pkt->data[8], size); if (ret < 0) { av_free_packet(pkt); } else packet_read = 1; break; case snd__TAG: track_number = avio_rl32(pb); avio_skip(pb, 4); size -= 8; if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels > 0) { ret = av_get_packet(s->pb, pkt, size); if (ret < 0) return AVERROR(EIO); pkt->stream_index = fourxm->tracks[track_number].stream_index; pkt->pts = fourxm->tracks[track_number].audio_pts; packet_read = 1; /* pts accounting */ audio_frame_count = size; if (fourxm->tracks[track_number].adpcm) audio_frame_count -= 2 * (fourxm->tracks[track_number].channels); audio_frame_count /= fourxm->tracks[track_number].channels; if (fourxm->tracks[track_number].adpcm) { audio_frame_count *= 2; } else audio_frame_count /= (fourxm->tracks[track_number].bits / 8); fourxm->tracks[track_number].audio_pts += audio_frame_count; } else { avio_skip(pb, size); } break; default: avio_skip(pb, size); break; } } return ret; }
static int idcin_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; IdcinDemuxContext *idcin = s->priv_data; AVStream *st; unsigned int width, height; unsigned int sample_rate, bytes_per_sample, channels; /* get the 5 header parameters */ width = avio_rl32(pb); height = avio_rl32(pb); sample_rate = avio_rl32(pb); bytes_per_sample = avio_rl32(pb); channels = avio_rl32(pb); st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 33, 1, IDCIN_FPS); idcin->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_IDCIN; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = width; st->codec->height = height; /* load up the Huffman tables into extradata */ st->codec->extradata_size = HUFFMAN_TABLE_SIZE; st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE); if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) != HUFFMAN_TABLE_SIZE) return AVERROR(EIO); /* if sample rate is 0, assume no audio */ if (sample_rate) { idcin->audio_present = 1; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 33, 1, IDCIN_FPS); idcin->audio_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = 1; st->codec->channels = channels; st->codec->sample_rate = sample_rate; st->codec->bits_per_coded_sample = bytes_per_sample * 8; st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels; st->codec->block_align = bytes_per_sample * channels; if (bytes_per_sample == 1) st->codec->codec_id = AV_CODEC_ID_PCM_U8; else st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; if (sample_rate % 14 != 0) { idcin->audio_chunk_size1 = (sample_rate / 14) * bytes_per_sample * channels; idcin->audio_chunk_size2 = (sample_rate / 14 + 1) * bytes_per_sample * channels; } else { idcin->audio_chunk_size1 = idcin->audio_chunk_size2 = (sample_rate / 14) * bytes_per_sample * channels; } idcin->current_audio_chunk = 0; } else idcin->audio_present = 1; idcin->next_chunk_is_video = 1; idcin->pts = 0; return 0; }
static int nsv_parse_NSVf_header(AVFormatContext *s) { NSVContext *nsv = s->priv_data; AVIOContext *pb = s->pb; unsigned int av_unused file_size; unsigned int size; int64_t duration; int strings_size; int table_entries; int table_entries_used; av_log(s, AV_LOG_TRACE, "%s()\n", __FUNCTION__); nsv->state = NSV_UNSYNC; /* in case we fail */ size = avio_rl32(pb); if (size < 28) return -1; nsv->NSVf_end = size; //s->file_size = (uint32_t)avio_rl32(pb); file_size = (uint32_t)avio_rl32(pb); av_log(s, AV_LOG_TRACE, "NSV NSVf chunk_size %u\n", size); av_log(s, AV_LOG_TRACE, "NSV NSVf file_size %u\n", file_size); nsv->duration = duration = avio_rl32(pb); /* in ms */ av_log(s, AV_LOG_TRACE, "NSV NSVf duration %"PRId64" ms\n", duration); // XXX: store it in AVStreams strings_size = avio_rl32(pb); table_entries = avio_rl32(pb); table_entries_used = avio_rl32(pb); av_log(s, AV_LOG_TRACE, "NSV NSVf info-strings size: %d, table entries: %d, bis %d\n", strings_size, table_entries, table_entries_used); if (pb->eof_reached) return -1; av_log(s, AV_LOG_TRACE, "NSV got header; filepos %"PRId64"\n", avio_tell(pb)); if (strings_size > 0) { char *strings; /* last byte will be '\0' to play safe with str*() */ char *p, *endp; char *token, *value; char quote; p = strings = av_mallocz((size_t)strings_size + 1); if (!p) return AVERROR(ENOMEM); endp = strings + strings_size; avio_read(pb, strings, strings_size); while (p < endp) { while (*p == ' ') p++; /* strip out spaces */ if (p >= endp-2) break; token = p; p = strchr(p, '='); if (!p || p >= endp-2) break; *p++ = '\0'; quote = *p++; value = p; p = strchr(p, quote); if (!p || p >= endp) break; *p++ = '\0'; av_log(s, AV_LOG_TRACE, "NSV NSVf INFO: %s='%s'\n", token, value); av_dict_set(&s->metadata, token, value, 0); } av_free(strings); } if (pb->eof_reached) return -1; av_log(s, AV_LOG_TRACE, "NSV got infos; filepos %"PRId64"\n", avio_tell(pb)); if (table_entries_used > 0) { int i; nsv->index_entries = table_entries_used; if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t)) return -1; nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t)); if (!nsv->nsvs_file_offset) return AVERROR(ENOMEM); for(i=0;i<table_entries_used;i++) nsv->nsvs_file_offset[i] = avio_rl32(pb) + size; if(table_entries > table_entries_used && avio_rl32(pb) == MKTAG('T','O','C','2')) { nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t)); if (!nsv->nsvs_timestamps) return AVERROR(ENOMEM); for(i=0;i<table_entries_used;i++) { nsv->nsvs_timestamps[i] = avio_rl32(pb); } } } av_log(s, AV_LOG_TRACE, "NSV got index; filepos %"PRId64"\n", avio_tell(pb)); avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */ if (pb->eof_reached) return -1; nsv->state = NSV_HAS_READ_NSVF; return 0; }
static int flac_read_header(AVFormatContext *s) { int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0; uint8_t header[4]; uint8_t *buffer=NULL,*tmp=NULL; AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_FLAC; st->need_parsing = AVSTREAM_PARSE_FULL_RAW; /* the parameters will be extracted from the compressed bitstream */ /* if fLaC marker is not found, assume there is no header */ if (avio_rl32(s->pb) != MKTAG('f','L','a','C')) { avio_seek(s->pb, -4, SEEK_CUR); return 0; } /* process metadata blocks */ while (!url_feof(s->pb) && !metadata_last) { avio_read(s->pb, header, 4); avpriv_flac_parse_block_header(header, &metadata_last, &metadata_type, &metadata_size); switch (metadata_type) { /* allocate and read metadata block for supported types */ case FLAC_METADATA_TYPE_STREAMINFO: case FLAC_METADATA_TYPE_CUESHEET: case FLAC_METADATA_TYPE_PICTURE: case FLAC_METADATA_TYPE_VORBIS_COMMENT: buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!buffer) { return AVERROR(ENOMEM); } if (avio_read(s->pb, buffer, metadata_size) != metadata_size) { RETURN_ERROR(AVERROR(EIO)); } break; /* skip metadata block for unsupported types */ default: ret = avio_skip(s->pb, metadata_size); if (ret < 0) return ret; } if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) { FLACStreaminfo si; /* STREAMINFO can only occur once */ if (found_streaminfo) { RETURN_ERROR(AVERROR_INVALIDDATA); } if (metadata_size != FLAC_STREAMINFO_SIZE) { RETURN_ERROR(AVERROR_INVALIDDATA); } found_streaminfo = 1; st->codec->extradata = av_malloc(metadata_size + 8 + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { RETURN_ERROR(AVERROR(ENOMEM)); } st->codec->extradata_size = metadata_size + 8; AV_WL32(st->codec->extradata, MKTAG('f','L','a','C')); memcpy(st->codec->extradata + 4, header, 4); memcpy(st->codec->extradata + 8, buffer, metadata_size); av_freep(&buffer); /* get codec params from STREAMINFO header */ avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata + 8); /* set time base and duration */ if (si.samplerate > 0) { avpriv_set_pts_info(st, 64, 1, si.samplerate); if (si.samples > 0) st->duration = si.samples; } } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) { uint8_t isrc[13]; uint64_t start; const uint8_t *offset; int i, chapters, track, ti; if (metadata_size < 431) RETURN_ERROR(AVERROR_INVALIDDATA); offset = buffer + 395; chapters = bytestream_get_byte(&offset) - 1; if (chapters <= 0) RETURN_ERROR(AVERROR_INVALIDDATA); for (i = 0; i < chapters; i++) { if (offset + 36 - buffer > metadata_size) RETURN_ERROR(AVERROR_INVALIDDATA); start = bytestream_get_be64(&offset); track = bytestream_get_byte(&offset); bytestream_get_buffer(&offset, isrc, 12); isrc[12] = 0; offset += 14; ti = bytestream_get_byte(&offset); if (ti <= 0) RETURN_ERROR(AVERROR_INVALIDDATA); offset += ti * 12; avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc); } av_freep(&buffer); } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) { ret = ff_flac_parse_picture(s, buffer, metadata_size); av_freep(&buffer); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n"); return ret; } } else { /* STREAMINFO must be the first block */ if (!found_streaminfo) { RETURN_ERROR(AVERROR_INVALIDDATA); } /* process supported blocks other than STREAMINFO */ if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) { /* append VorbisComment to extradata */ tmp = av_realloc(st->codec->extradata, st->codec->extradata_size + 4 + metadata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!tmp) { RETURN_ERROR(AVERROR(ENOMEM)); } st->codec->extradata = tmp; tmp += st->codec->extradata_size; memcpy(tmp, header, 4); memcpy(tmp + 4, buffer, metadata_size); st->codec->extradata_size = st->codec->extradata_size + 4 + metadata_size; if (ff_vorbis_comment(s, &s->metadata, buffer, metadata_size)) { av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n"); } } av_freep(&buffer); } } return 0; fail: av_free(buffer); return ret; }
/** Read magic cookie chunk */ static int read_kuki_chunk(AVFormatContext *s, int64_t size) { AVIOContext *pb = s->pb; AVStream *st = s->streams[0]; if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) return -1; if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { /* The magic cookie format for AAC is an mp4 esds atom. The lavc AAC decoder requires the data from the codec specific description as extradata input. */ int strt, skip; strt = avio_tell(pb); ff_mov_read_esds(s, pb); skip = size - (avio_tell(pb) - strt); if (skip < 0 || !st->codecpar->extradata || st->codecpar->codec_id != AV_CODEC_ID_AAC) { av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n"); return AVERROR_INVALIDDATA; } avio_skip(pb, skip); } else if (st->codecpar->codec_id == AV_CODEC_ID_ALAC) { #define ALAC_PREAMBLE 12 #define ALAC_HEADER 36 #define ALAC_NEW_KUKI 24 uint8_t preamble[12]; if (size < ALAC_NEW_KUKI) { av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n"); avio_skip(pb, size); return AVERROR_INVALIDDATA; } if (avio_read(pb, preamble, ALAC_PREAMBLE) != ALAC_PREAMBLE) { av_log(s, AV_LOG_ERROR, "failed to read preamble\n"); return AVERROR_INVALIDDATA; } av_freep(&st->codecpar->extradata); if (ff_alloc_extradata(st->codecpar, ALAC_HEADER)) return AVERROR(ENOMEM); /* For the old style cookie, we skip 12 bytes, then read 36 bytes. * The new style cookie only contains the last 24 bytes of what was * 36 bytes in the old style cookie, so we fabricate the first 12 bytes * in that case to maintain compatibility. */ if (!memcmp(&preamble[4], "frmaalac", 8)) { if (size < ALAC_PREAMBLE + ALAC_HEADER) { av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n"); av_freep(&st->codecpar->extradata); return AVERROR_INVALIDDATA; } if (avio_read(pb, st->codecpar->extradata, ALAC_HEADER) != ALAC_HEADER) { av_log(s, AV_LOG_ERROR, "failed to read kuki header\n"); av_freep(&st->codecpar->extradata); return AVERROR_INVALIDDATA; } avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER); } else { AV_WB32(st->codecpar->extradata, 36); memcpy(&st->codecpar->extradata[4], "alac", 4); AV_WB32(&st->codecpar->extradata[8], 0); memcpy(&st->codecpar->extradata[12], preamble, 12); if (avio_read(pb, &st->codecpar->extradata[24], ALAC_NEW_KUKI - 12) != ALAC_NEW_KUKI - 12) { av_log(s, AV_LOG_ERROR, "failed to read new kuki header\n"); av_freep(&st->codecpar->extradata); return AVERROR_INVALIDDATA; } avio_skip(pb, size - ALAC_NEW_KUKI); } } else { av_freep(&st->codecpar->extradata); if (ff_get_extradata(st->codecpar, pb, size) < 0) return AVERROR(ENOMEM); } return 0; }
/* This function loads and processes a single chunk in an IP movie file. * It returns the type of chunk that was processed. */ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, AVPacket *pkt) { unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; int chunk_type; int chunk_size; unsigned char opcode_preamble[OPCODE_PREAMBLE_SIZE]; unsigned char opcode_type; unsigned char opcode_version; int opcode_size; unsigned char scratch[1024]; int i, j; int first_color, last_color; int audio_flags; unsigned char r, g, b; unsigned int width, height; /* see if there are any pending packets */ chunk_type = load_ipmovie_packet(s, pb, pkt); if (chunk_type != CHUNK_DONE) return chunk_type; /* read the next chunk, wherever the file happens to be pointing */ if (avio_feof(pb)) return CHUNK_EOF; if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) != CHUNK_PREAMBLE_SIZE) return CHUNK_BAD; chunk_size = AV_RL16(&chunk_preamble[0]); chunk_type = AV_RL16(&chunk_preamble[2]); av_log(NULL, AV_LOG_TRACE, "chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size); switch (chunk_type) { case CHUNK_INIT_AUDIO: av_log(NULL, AV_LOG_TRACE, "initialize audio\n"); break; case CHUNK_AUDIO_ONLY: av_log(NULL, AV_LOG_TRACE, "audio only\n"); break; case CHUNK_INIT_VIDEO: av_log(NULL, AV_LOG_TRACE, "initialize video\n"); break; case CHUNK_VIDEO: av_log(NULL, AV_LOG_TRACE, "video (and audio)\n"); break; case CHUNK_SHUTDOWN: av_log(NULL, AV_LOG_TRACE, "shutdown\n"); break; case CHUNK_END: av_log(NULL, AV_LOG_TRACE, "end\n"); break; default: av_log(NULL, AV_LOG_TRACE, "invalid chunk\n"); chunk_type = CHUNK_BAD; break; } while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) { /* read the next chunk, wherever the file happens to be pointing */ if (avio_feof(pb)) { chunk_type = CHUNK_EOF; break; } if (avio_read(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) != CHUNK_PREAMBLE_SIZE) { chunk_type = CHUNK_BAD; break; } opcode_size = AV_RL16(&opcode_preamble[0]); opcode_type = opcode_preamble[2]; opcode_version = opcode_preamble[3]; chunk_size -= OPCODE_PREAMBLE_SIZE; chunk_size -= opcode_size; if (chunk_size < 0) { av_log(NULL, AV_LOG_TRACE, "chunk_size countdown just went negative\n"); chunk_type = CHUNK_BAD; break; } av_log(NULL, AV_LOG_TRACE, " opcode type %02X, version %d, 0x%04X bytes: ", opcode_type, opcode_version, opcode_size); switch (opcode_type) { case OPCODE_END_OF_STREAM: av_log(NULL, AV_LOG_TRACE, "end of stream\n"); avio_skip(pb, opcode_size); break; case OPCODE_END_OF_CHUNK: av_log(NULL, AV_LOG_TRACE, "end of chunk\n"); avio_skip(pb, opcode_size); break; case OPCODE_CREATE_TIMER: av_log(NULL, AV_LOG_TRACE, "create timer\n"); if ((opcode_version > 0) || (opcode_size != 6)) { av_log(NULL, AV_LOG_TRACE, "bad create_timer opcode\n"); chunk_type = CHUNK_BAD; break; } if (avio_read(pb, scratch, opcode_size) != opcode_size) { chunk_type = CHUNK_BAD; break; } s->frame_pts_inc = ((uint64_t)AV_RL32(&scratch[0])) * AV_RL16(&scratch[4]); av_log(NULL, AV_LOG_TRACE, " %.2f frames/second (timer div = %d, subdiv = %d)\n", 1000000.0 / s->frame_pts_inc, AV_RL32(&scratch[0]), AV_RL16(&scratch[4])); break; case OPCODE_INIT_AUDIO_BUFFERS: av_log(NULL, AV_LOG_TRACE, "initialize audio buffers\n"); if (opcode_version > 1 || opcode_size > 10 || opcode_size < 6) { av_log(NULL, AV_LOG_TRACE, "bad init_audio_buffers opcode\n"); chunk_type = CHUNK_BAD; break; } if (avio_read(pb, scratch, opcode_size) != opcode_size) { chunk_type = CHUNK_BAD; break; } s->audio_sample_rate = AV_RL16(&scratch[4]); audio_flags = AV_RL16(&scratch[2]); /* bit 0 of the flags: 0 = mono, 1 = stereo */ s->audio_channels = (audio_flags & 1) + 1; /* bit 1 of the flags: 0 = 8 bit, 1 = 16 bit */ s->audio_bits = (((audio_flags >> 1) & 1) + 1) * 8; /* bit 2 indicates compressed audio in version 1 opcode */ if ((opcode_version == 1) && (audio_flags & 0x4)) s->audio_type = AV_CODEC_ID_INTERPLAY_DPCM; else if (s->audio_bits == 16) s->audio_type = AV_CODEC_ID_PCM_S16LE; else s->audio_type = AV_CODEC_ID_PCM_U8; av_log(NULL, AV_LOG_TRACE, "audio: %d bits, %d Hz, %s, %s format\n", s->audio_bits, s->audio_sample_rate, (s->audio_channels == 2) ? "stereo" : "mono", (s->audio_type == AV_CODEC_ID_INTERPLAY_DPCM) ? "Interplay audio" : "PCM"); break; case OPCODE_START_STOP_AUDIO: av_log(NULL, AV_LOG_TRACE, "start/stop audio\n"); avio_skip(pb, opcode_size); break; case OPCODE_INIT_VIDEO_BUFFERS: av_log(NULL, AV_LOG_TRACE, "initialize video buffers\n"); if ((opcode_version > 2) || (opcode_size > 8) || opcode_size < 4 || opcode_version == 2 && opcode_size < 8 ) { av_log(NULL, AV_LOG_TRACE, "bad init_video_buffers opcode\n"); chunk_type = CHUNK_BAD; break; } if (avio_read(pb, scratch, opcode_size) != opcode_size) { chunk_type = CHUNK_BAD; break; } width = AV_RL16(&scratch[0]) * 8; height = AV_RL16(&scratch[2]) * 8; if (width != s->video_width) { s->video_width = width; s->changed++; } if (height != s->video_height) { s->video_height = height; s->changed++; } if (opcode_version < 2 || !AV_RL16(&scratch[6])) { s->video_bpp = 8; } else { s->video_bpp = 16; } av_log(NULL, AV_LOG_TRACE, "video resolution: %d x %d\n", s->video_width, s->video_height); break; case OPCODE_UNKNOWN_06: case OPCODE_UNKNOWN_0E: case OPCODE_UNKNOWN_10: case OPCODE_UNKNOWN_12: case OPCODE_UNKNOWN_13: case OPCODE_UNKNOWN_14: case OPCODE_UNKNOWN_15: av_log(NULL, AV_LOG_TRACE, "unknown (but documented) opcode %02X\n", opcode_type); avio_skip(pb, opcode_size); break; case OPCODE_SEND_BUFFER: av_log(NULL, AV_LOG_TRACE, "send buffer\n"); avio_skip(pb, opcode_size); break; case OPCODE_AUDIO_FRAME: av_log(NULL, AV_LOG_TRACE, "audio frame\n"); /* log position and move on for now */ s->audio_chunk_offset = avio_tell(pb); s->audio_chunk_size = opcode_size; avio_skip(pb, opcode_size); break; case OPCODE_SILENCE_FRAME: av_log(NULL, AV_LOG_TRACE, "silence frame\n"); avio_skip(pb, opcode_size); break; case OPCODE_INIT_VIDEO_MODE: av_log(NULL, AV_LOG_TRACE, "initialize video mode\n"); avio_skip(pb, opcode_size); break; case OPCODE_CREATE_GRADIENT: av_log(NULL, AV_LOG_TRACE, "create gradient\n"); avio_skip(pb, opcode_size); break; case OPCODE_SET_PALETTE: av_log(NULL, AV_LOG_TRACE, "set palette\n"); /* check for the logical maximum palette size * (3 * 256 + 4 bytes) */ if (opcode_size > 0x304 || opcode_size < 4) { av_log(NULL, AV_LOG_TRACE, "demux_ipmovie: set_palette opcode with invalid size\n"); chunk_type = CHUNK_BAD; break; } if (avio_read(pb, scratch, opcode_size) != opcode_size) { chunk_type = CHUNK_BAD; break; } /* load the palette into internal data structure */ first_color = AV_RL16(&scratch[0]); last_color = first_color + AV_RL16(&scratch[2]) - 1; /* sanity check (since they are 16 bit values) */ if ( (first_color > 0xFF) || (last_color > 0xFF) || (last_color - first_color + 1)*3 + 4 > opcode_size) { av_log(NULL, AV_LOG_TRACE, "demux_ipmovie: set_palette indexes out of range (%d -> %d)\n", first_color, last_color); chunk_type = CHUNK_BAD; break; } j = 4; /* offset of first palette data */ for (i = first_color; i <= last_color; i++) { /* the palette is stored as a 6-bit VGA palette, thus each * component is shifted up to a 8-bit range */ r = scratch[j++] * 4; g = scratch[j++] * 4; b = scratch[j++] * 4; s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b); s->palette[i] |= s->palette[i] >> 6 & 0x30303; } s->has_palette = 1; break; case OPCODE_SET_PALETTE_COMPRESSED: av_log(NULL, AV_LOG_TRACE, "set palette compressed\n"); avio_skip(pb, opcode_size); break; case OPCODE_SET_DECODING_MAP: av_log(NULL, AV_LOG_TRACE, "set decoding map\n"); /* log position and move on for now */ s->decode_map_chunk_offset = avio_tell(pb); s->decode_map_chunk_size = opcode_size; avio_skip(pb, opcode_size); break; case OPCODE_VIDEO_DATA: av_log(NULL, AV_LOG_TRACE, "set video data\n"); /* log position and move on for now */ s->video_chunk_offset = avio_tell(pb); s->video_chunk_size = opcode_size; avio_skip(pb, opcode_size); break; default: av_log(NULL, AV_LOG_TRACE, "*** unknown opcode type\n"); chunk_type = CHUNK_BAD; break; } } if (s->avf->nb_streams == 1 && s->audio_type) init_audio(s->avf); /* make a note of where the stream is sitting */ s->next_chunk_offset = avio_tell(pb); /* dispatch the first of any pending packets */ if ((chunk_type == CHUNK_VIDEO) || (chunk_type == CHUNK_AUDIO_ONLY)) chunk_type = load_ipmovie_packet(s, pb, pkt); return chunk_type; }
static int film_read_packet(AVFormatContext *s, AVPacket *pkt) { FilmDemuxContext *film = s->priv_data; AVIOContext *pb = s->pb; film_sample *sample; int ret = 0; int i; int left, right; if (film->current_sample >= film->sample_count) return AVERROR(EIO); sample = &film->sample_table[film->current_sample]; /* position the stream (will probably be there anyway) */ avio_seek(pb, sample->sample_offset, SEEK_SET); /* do a special song and dance when loading FILM Cinepak chunks */ if ((sample->stream == film->video_stream_index) && (film->video_type == CODEC_ID_CINEPAK)) { pkt->pos= avio_tell(pb); if (av_new_packet(pkt, sample->sample_size)) return AVERROR(ENOMEM); avio_read(pb, pkt->data, sample->sample_size); } else if ((sample->stream == film->audio_stream_index) && (film->audio_channels == 2) && (film->audio_type != CODEC_ID_ADPCM_ADX)) { /* stereo PCM needs to be interleaved */ if (av_new_packet(pkt, sample->sample_size)) return AVERROR(ENOMEM); /* make sure the interleave buffer is large enough */ if (sample->sample_size > film->stereo_buffer_size) { av_free(film->stereo_buffer); film->stereo_buffer_size = sample->sample_size; film->stereo_buffer = av_malloc(film->stereo_buffer_size); if (!film->stereo_buffer) { film->stereo_buffer_size = 0; return AVERROR(ENOMEM); } } pkt->pos= avio_tell(pb); ret = avio_read(pb, film->stereo_buffer, sample->sample_size); if (ret != sample->sample_size) ret = AVERROR(EIO); left = 0; right = sample->sample_size / 2; for (i = 0; i < sample->sample_size; ) { if (film->audio_bits == 8) { pkt->data[i++] = film->stereo_buffer[left++]; pkt->data[i++] = film->stereo_buffer[right++]; } else { pkt->data[i++] = film->stereo_buffer[left++]; pkt->data[i++] = film->stereo_buffer[left++]; pkt->data[i++] = film->stereo_buffer[right++]; pkt->data[i++] = film->stereo_buffer[right++]; } } } else { ret= av_get_packet(pb, pkt, sample->sample_size); if (ret != sample->sample_size) ret = AVERROR(EIO); } pkt->stream_index = sample->stream; pkt->pts = sample->pts; film->current_sample++; return ret; }
static int film_read_header(AVFormatContext *s, AVFormatParameters *ap) { FilmDemuxContext *film = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; unsigned char scratch[256]; int i; unsigned int data_offset; unsigned int audio_frame_counter; film->sample_table = NULL; film->stereo_buffer = NULL; film->stereo_buffer_size = 0; /* load the main FILM header */ if (avio_read(pb, scratch, 16) != 16) return AVERROR(EIO); data_offset = AV_RB32(&scratch[4]); film->version = AV_RB32(&scratch[8]); /* load the FDSC chunk */ if (film->version == 0) { /* special case for Lemmings .film files; 20-byte header */ if (avio_read(pb, scratch, 20) != 20) return AVERROR(EIO); /* make some assumptions about the audio parameters */ film->audio_type = CODEC_ID_PCM_S8; film->audio_samplerate = 22050; film->audio_channels = 1; film->audio_bits = 8; } else { /* normal Saturn .cpk files; 32-byte header */ if (avio_read(pb, scratch, 32) != 32) return AVERROR(EIO); film->audio_samplerate = AV_RB16(&scratch[24]); film->audio_channels = scratch[21]; film->audio_bits = scratch[22]; if (scratch[23] == 2) film->audio_type = CODEC_ID_ADPCM_ADX; else if (film->audio_channels > 0) { if (film->audio_bits == 8) film->audio_type = CODEC_ID_PCM_S8; else if (film->audio_bits == 16) film->audio_type = CODEC_ID_PCM_S16BE; else film->audio_type = CODEC_ID_NONE; } else film->audio_type = CODEC_ID_NONE; } if (AV_RB32(&scratch[0]) != FDSC_TAG) return AVERROR_INVALIDDATA; if (AV_RB32(&scratch[8]) == CVID_TAG) { film->video_type = CODEC_ID_CINEPAK; } else if (AV_RB32(&scratch[8]) == RAW_TAG) { film->video_type = CODEC_ID_RAWVIDEO; } else { film->video_type = CODEC_ID_NONE; } /* initialize the decoder streams */ if (film->video_type) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); film->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = film->video_type; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = AV_RB32(&scratch[16]); st->codec->height = AV_RB32(&scratch[12]); if (film->video_type == CODEC_ID_RAWVIDEO) { if (scratch[20] == 24) { st->codec->pix_fmt = PIX_FMT_RGB24; } else { av_log(s, AV_LOG_ERROR, "raw video is using unhandled %dbpp\n", scratch[20]); return -1; } } } if (film->audio_type) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); film->audio_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = film->audio_type; st->codec->codec_tag = 1; st->codec->channels = film->audio_channels; st->codec->sample_rate = film->audio_samplerate; if (film->audio_type == CODEC_ID_ADPCM_ADX) { st->codec->bits_per_coded_sample = 18 * 8 / 32; st->codec->block_align = st->codec->channels * 18; } else { st->codec->bits_per_coded_sample = film->audio_bits; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample / 8; } st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; } /* load the sample table */ if (avio_read(pb, scratch, 16) != 16) return AVERROR(EIO); if (AV_RB32(&scratch[0]) != STAB_TAG) return AVERROR_INVALIDDATA; film->base_clock = AV_RB32(&scratch[8]); film->sample_count = AV_RB32(&scratch[12]); if(film->sample_count >= UINT_MAX / sizeof(film_sample)) return -1; film->sample_table = av_malloc(film->sample_count * sizeof(film_sample)); if (!film->sample_table) return AVERROR(ENOMEM); for(i=0; i<s->nb_streams; i++) av_set_pts_info(s->streams[i], 33, 1, film->base_clock); audio_frame_counter = 0; for (i = 0; i < film->sample_count; i++) { /* load the next sample record and transfer it to an internal struct */ if (avio_read(pb, scratch, 16) != 16) { av_free(film->sample_table); return AVERROR(EIO); } film->sample_table[i].sample_offset = data_offset + AV_RB32(&scratch[0]); film->sample_table[i].sample_size = AV_RB32(&scratch[4]); if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) { film->sample_table[i].stream = film->audio_stream_index; film->sample_table[i].pts = audio_frame_counter; film->sample_table[i].pts *= film->base_clock; film->sample_table[i].pts /= film->audio_samplerate; if (film->audio_type == CODEC_ID_ADPCM_ADX) audio_frame_counter += (film->sample_table[i].sample_size * 32 / (18 * film->audio_channels)); else if (film->audio_type != CODEC_ID_NONE) audio_frame_counter += (film->sample_table[i].sample_size / (film->audio_channels * film->audio_bits / 8)); } else { film->sample_table[i].stream = film->video_stream_index; film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF; film->sample_table[i].keyframe = (scratch[8] & 0x80) ? 0 : 1; } } film->current_sample = 0; return 0; }
static int yop_read_packet(AVFormatContext *s, AVPacket *pkt) { YopDecContext *yop = s->priv_data; AVIOContext *pb = s->pb; int ret; int actual_video_data_size = yop->frame_size - yop->audio_block_length - yop->palette_size; yop->video_packet.stream_index = 1; if (yop->video_packet.data) { *pkt = yop->video_packet; yop->video_packet.data = NULL; yop->video_packet.buf = NULL; #if FF_API_DESTRUCT_PACKET FF_DISABLE_DEPRECATION_WARNINGS yop->video_packet.destruct = NULL; FF_ENABLE_DEPRECATION_WARNINGS #endif yop->video_packet.size = 0; pkt->data[0] = yop->odd_frame; pkt->flags |= AV_PKT_FLAG_KEY; yop->odd_frame ^= 1; return pkt->size; } ret = av_new_packet(&yop->video_packet, yop->frame_size - yop->audio_block_length); if (ret < 0) return ret; yop->video_packet.pos = avio_tell(pb); ret = avio_read(pb, yop->video_packet.data, yop->palette_size); if (ret < 0) { goto err_out; }else if (ret < yop->palette_size) { ret = AVERROR_EOF; goto err_out; } ret = av_get_packet(pb, pkt, 920); if (ret < 0) goto err_out; // Set position to the start of the frame pkt->pos = yop->video_packet.pos; avio_skip(pb, yop->audio_block_length - ret); ret = avio_read(pb, yop->video_packet.data + yop->palette_size, actual_video_data_size); if (ret < 0) goto err_out; else if (ret < actual_video_data_size) av_shrink_packet(&yop->video_packet, yop->palette_size + ret); // Arbitrarily return the audio data first return yop->audio_block_length; err_out: av_free_packet(&yop->video_packet); return ret; }
static int yop_read_header(AVFormatContext *s) { YopDecContext *yop = s->priv_data; AVIOContext *pb = s->pb; AVCodecContext *audio_dec, *video_dec; AVStream *audio_stream, *video_stream; int frame_rate, ret; audio_stream = avformat_new_stream(s, NULL); video_stream = avformat_new_stream(s, NULL); if (!audio_stream || !video_stream) return AVERROR(ENOMEM); // Extra data that will be passed to the decoder if (ff_alloc_extradata(video_stream->codec, 8)) return AVERROR(ENOMEM); // Audio audio_dec = audio_stream->codec; audio_dec->codec_type = AVMEDIA_TYPE_AUDIO; audio_dec->codec_id = AV_CODEC_ID_ADPCM_IMA_APC; audio_dec->channels = 1; audio_dec->channel_layout = AV_CH_LAYOUT_MONO; audio_dec->sample_rate = 22050; // Video video_dec = video_stream->codec; video_dec->codec_type = AVMEDIA_TYPE_VIDEO; video_dec->codec_id = AV_CODEC_ID_YOP; avio_skip(pb, 6); frame_rate = avio_r8(pb); yop->frame_size = avio_r8(pb) * 2048; video_dec->width = avio_rl16(pb); video_dec->height = avio_rl16(pb); video_stream->sample_aspect_ratio = (AVRational){1, 2}; ret = avio_read(pb, video_dec->extradata, 8); if (ret < 8) return ret < 0 ? ret : AVERROR_EOF; yop->palette_size = video_dec->extradata[0] * 3 + 4; yop->audio_block_length = AV_RL16(video_dec->extradata + 6); video_dec->bit_rate = 8 * (yop->frame_size - yop->audio_block_length) * frame_rate; // 1840 samples per frame, 1 nibble per sample; hence 1840/2 = 920 if (yop->audio_block_length < 920 || yop->audio_block_length + yop->palette_size >= yop->frame_size) { av_log(s, AV_LOG_ERROR, "YOP has invalid header\n"); return AVERROR_INVALIDDATA; } avio_seek(pb, 2048, SEEK_SET); avpriv_set_pts_info(video_stream, 32, 1, frame_rate); return 0; }
static int ipmovie_read_header(AVFormatContext *s) { 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 (pb->eof_reached) 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 = AV_CODEC_ID_NONE; /* no audio */ else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO) return AVERROR_INVALIDDATA; /* initialize the stream decoders */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 63, 1, 1000000); ipmovie->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_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 = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_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->channel_layout = st->codec->channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; 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 == AV_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 sox_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; unsigned header_size, comment_size; double sample_rate, sample_rate_frac; AVStream *st; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (avio_rl32(pb) == SOX_TAG) { st->codec->codec_id = AV_CODEC_ID_PCM_S32LE; header_size = avio_rl32(pb); avio_skip(pb, 8); /* sample count */ sample_rate = av_int2double(avio_rl64(pb)); st->codec->channels = avio_rl32(pb); comment_size = avio_rl32(pb); } else { st->codec->codec_id = AV_CODEC_ID_PCM_S32BE; header_size = avio_rb32(pb); avio_skip(pb, 8); /* sample count */ sample_rate = av_int2double(avio_rb64(pb)); st->codec->channels = avio_rb32(pb); comment_size = avio_rb32(pb); } if (comment_size > 0xFFFFFFFFU - SOX_FIXED_HDR - 4U) { av_log(s, AV_LOG_ERROR, "invalid comment size (%u)\n", comment_size); return AVERROR_INVALIDDATA; } if (sample_rate <= 0 || sample_rate > INT_MAX) { av_log(s, AV_LOG_ERROR, "invalid sample rate (%f)\n", sample_rate); return AVERROR_INVALIDDATA; } sample_rate_frac = sample_rate - floor(sample_rate); if (sample_rate_frac) av_log(s, AV_LOG_WARNING, "truncating fractional part of sample rate (%f)\n", sample_rate_frac); if ((header_size + 4) & 7 || header_size < SOX_FIXED_HDR + comment_size || st->codec->channels > 65535) /* Reserve top 16 bits */ { av_log(s, AV_LOG_ERROR, "invalid header\n"); return AVERROR_INVALIDDATA; } if (comment_size && comment_size < UINT_MAX) { char *comment = av_malloc(comment_size+1); if(!comment) return AVERROR(ENOMEM); if (avio_read(pb, comment, comment_size) != comment_size) { av_freep(&comment); return AVERROR(EIO); } comment[comment_size] = 0; av_dict_set(&s->metadata, "comment", comment, AV_DICT_DONT_STRDUP_VAL); } avio_skip(pb, header_size - SOX_FIXED_HDR - comment_size); st->codec->sample_rate = sample_rate; st->codec->bits_per_coded_sample = 32; st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels; st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); return 0; }
int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size) { AVProbeData pd = { filename ? filename : "" }; uint8_t *buf = NULL; int ret = 0, probe_size, buf_offset = 0; int score = 0; int ret2; if (!max_probe_size) max_probe_size = PROBE_BUF_MAX; else if (max_probe_size < PROBE_BUF_MIN) { av_log(logctx, AV_LOG_ERROR, "Specified probe size value %u cannot be < %u\n", max_probe_size, PROBE_BUF_MIN); return AVERROR(EINVAL); } if (offset >= max_probe_size) return AVERROR(EINVAL); if (pb->av_class) { uint8_t *mime_type_opt = NULL; char *semi; av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type_opt); pd.mime_type = (const char *)mime_type_opt; semi = pd.mime_type ? strchr(pd.mime_type, ';') : NULL; if (semi) { *semi = '\0'; } } #if 0 if (!*fmt && pb->av_class && av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type) >= 0 && mime_type) { if (!av_strcasecmp(mime_type, "audio/aacp")) { *fmt = av_find_input_format("aac"); } av_freep(&mime_type); } #endif for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt; probe_size = FFMIN(probe_size << 1, FFMAX(max_probe_size, probe_size + 1))) { score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0; /* Read probe data. */ if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0) goto fail; if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) { /* Fail if error was not end of file, otherwise, lower score. */ if (ret != AVERROR_EOF) goto fail; score = 0; ret = 0; /* error was end of file, nothing read */ } buf_offset += ret; if (buf_offset < offset) continue; pd.buf_size = buf_offset - offset; pd.buf = &buf[offset]; memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); /* Guess file format. */ *fmt = av_probe_input_format2(&pd, 1, &score); if (*fmt) { /* This can only be true in the last iteration. */ if (score <= AVPROBE_SCORE_RETRY) { av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, " "misdetection possible!\n", (*fmt)->name, score); } else av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score); #if 0 FILE *f = fopen("probestat.tmp", "ab"); fprintf(f, "probe_size:%d format:%s score:%d filename:%s\n", probe_size, (*fmt)->name, score, filename); fclose(f); #endif } } if (!*fmt) ret = AVERROR_INVALIDDATA; fail: /* Rewind. Reuse probe buffer to avoid seeking. */ ret2 = ffio_rewind_with_probe_data(pb, &buf, buf_offset); if (ret >= 0) ret = ret2; av_freep(&pd.mime_type); return ret < 0 ? ret : score; }
/* Returns the number of sound data frames or negative on error */ static unsigned int get_aiff_header(AVIOContext *pb, AVCodecContext *codec, int size, unsigned version) { AVExtFloat ext; double sample_rate; unsigned int num_frames; if (size & 1) size++; codec->codec_type = AVMEDIA_TYPE_AUDIO; codec->channels = avio_rb16(pb); num_frames = avio_rb32(pb); codec->bits_per_coded_sample = avio_rb16(pb); avio_read(pb, (uint8_t*)&ext, sizeof(ext));/* Sample rate is in */ sample_rate = av_ext2dbl(ext); /* 80 bits BE IEEE extended float */ codec->sample_rate = sample_rate; size -= 18; /* Got an AIFF-C? */ if (version == AIFF_C_VERSION1) { codec->codec_tag = avio_rl32(pb); codec->codec_id = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag); switch (codec->codec_id) { case CODEC_ID_PCM_S16BE: codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample); codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id); break; case CODEC_ID_ADPCM_IMA_QT: codec->block_align = 34*codec->channels; codec->frame_size = 64; break; case CODEC_ID_MACE3: codec->block_align = 2*codec->channels; codec->frame_size = 6; break; case CODEC_ID_MACE6: codec->block_align = 1*codec->channels; codec->frame_size = 6; break; case CODEC_ID_GSM: codec->block_align = 33; codec->frame_size = 160; break; case CODEC_ID_QCELP: codec->block_align = 35; codec->frame_size= 160; break; default: break; } size -= 4; } else { /* Need the codec type */ codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample); codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id); } /* Block align needs to be computed in all cases, as the definition * is specific to applications -> here we use the WAVE format definition */ if (!codec->block_align) codec->block_align = (codec->bits_per_coded_sample * codec->channels) >> 3; codec->bit_rate = (codec->frame_size ? codec->sample_rate/codec->frame_size : codec->sample_rate) * (codec->block_align << 3); /* Chunk is over */ if (size) avio_skip(pb, size); return num_frames; }
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', '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) { codec->extradata_size = avio_rb32(pb); codec->extradata = av_malloc(codec->extradata_size); if (!codec->extradata) return AVERROR(ENOMEM); avio_read(pb, codec->extradata, codec->extradata_size); } } /* 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 r3d_read_red1(AVFormatContext *s) { AVStream *st = avformat_new_stream(s, NULL); char filename[258]; int tmp; int av_unused tmp2; AVRational framerate; if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_JPEG2000; tmp = avio_r8(s->pb); // major version tmp2 = avio_r8(s->pb); // minor version av_dlog(s, "version %d.%d\n", tmp, tmp2); tmp = avio_rb16(s->pb); // unknown av_dlog(s, "unknown1 %d\n", tmp); tmp = avio_rb32(s->pb); avpriv_set_pts_info(st, 32, 1, tmp); tmp = avio_rb32(s->pb); // filenum av_dlog(s, "filenum %d\n", tmp); avio_skip(s->pb, 32); // unknown st->codec->width = avio_rb32(s->pb); st->codec->height = avio_rb32(s->pb); tmp = avio_rb16(s->pb); // unknown av_dlog(s, "unknown2 %d\n", tmp); framerate.num = avio_rb16(s->pb); framerate.den = avio_rb16(s->pb); if (framerate.num > 0 && framerate.den > 0) { #if FF_API_R_FRAME_RATE st->r_frame_rate = #endif st->avg_frame_rate = framerate; } tmp = avio_r8(s->pb); // audio channels av_dlog(s, "audio channels %d\n", tmp); if (tmp > 0) { AVStream *ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = AV_CODEC_ID_PCM_S32BE; ast->codec->channels = tmp; avpriv_set_pts_info(ast, 32, 1, st->time_base.den); } avio_read(s->pb, filename, 257); filename[sizeof(filename)-1] = 0; av_dict_set(&st->metadata, "filename", filename, 0); av_dlog(s, "filename %s\n", filename); av_dlog(s, "resolution %dx%d\n", st->codec->width, st->codec->height); av_dlog(s, "timescale %d\n", st->time_base.den); av_dlog(s, "frame rate %d/%d\n", framerate.num, framerate.den); return 0; }
/* first is true if we read the frame header */ static int ffm_read_data(AVFormatContext *s, uint8_t *buf, int size, int header) { FFMContext *ffm = s->priv_data; AVIOContext *pb = s->pb; int len, fill_size, size1, frame_offset, id; size1 = size; while (size > 0) { redo: len = ffm->packet_end - ffm->packet_ptr; if (len < 0) return -1; if (len > size) len = size; if (len == 0) { if (avio_tell(pb) == ffm->file_size) avio_seek(pb, ffm->packet_size, SEEK_SET); retry_read: if (pb->buffer_size != ffm->packet_size) { int64_t tell = avio_tell(pb); ffio_set_buf_size(pb, ffm->packet_size); avio_seek(pb, tell, SEEK_SET); } id = avio_rb16(pb); /* PACKET_ID */ if (id != PACKET_ID) if (ffm_resync(s, id) < 0) return -1; fill_size = avio_rb16(pb); ffm->dts = avio_rb64(pb); frame_offset = avio_rb16(pb); avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE); ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size); if (ffm->packet_end < ffm->packet || frame_offset < 0) return -1; /* if first packet or resynchronization packet, we must handle it specifically */ if (ffm->first_packet || (frame_offset & 0x8000)) { if (!frame_offset) { /* This packet has no frame headers in it */ if (avio_tell(pb) >= ffm->packet_size * 3) { avio_seek(pb, -ffm->packet_size * 2, SEEK_CUR); goto retry_read; } /* This is bad, we cannot find a valid frame header */ return 0; } ffm->first_packet = 0; if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE) return -1; ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE; if (!header) break; } else { ffm->packet_ptr = ffm->packet; } goto redo; } memcpy(buf, ffm->packet_ptr, len); buf += len; ffm->packet_ptr += len; size -= len; header = 0; } return size1 - size; }
static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, AVPacket *pkt) { int chunk_type; if (s->audio_chunk_offset && s->audio_channels && s->audio_bits) { if (s->audio_type == AV_CODEC_ID_NONE) { av_log(NULL, AV_LOG_ERROR, "Can not read audio packet before" "audio codec is known\n"); return CHUNK_BAD; } /* adjust for PCM audio by skipping chunk header */ if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM) { s->audio_chunk_offset += 6; s->audio_chunk_size -= 6; } avio_seek(pb, s->audio_chunk_offset, SEEK_SET); s->audio_chunk_offset = 0; if (s->audio_chunk_size != av_get_packet(pb, pkt, s->audio_chunk_size)) return CHUNK_EOF; pkt->stream_index = s->audio_stream_index; pkt->pts = s->audio_frame_count; /* audio frame maintenance */ if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM) s->audio_frame_count += (s->audio_chunk_size / s->audio_channels / (s->audio_bits / 8)); else s->audio_frame_count += (s->audio_chunk_size - 6 - s->audio_channels) / s->audio_channels; av_log(NULL, AV_LOG_TRACE, "sending audio frame with pts %"PRId64" (%d audio frames)\n", pkt->pts, s->audio_frame_count); chunk_type = CHUNK_VIDEO; } else if (s->decode_map_chunk_offset) { /* send both the decode map and the video data together */ if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size)) return CHUNK_NOMEM; if (s->has_palette) { uint8_t *pal; pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); if (pal) { memcpy(pal, s->palette, AVPALETTE_SIZE); s->has_palette = 0; } } if (s->changed) { ff_add_param_change(pkt, 0, 0, 0, s->video_width, s->video_height); s->changed = 0; } pkt->pos= s->decode_map_chunk_offset; avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); s->decode_map_chunk_offset = 0; if (avio_read(pb, pkt->data, s->decode_map_chunk_size) != s->decode_map_chunk_size) { av_free_packet(pkt); return CHUNK_EOF; } avio_seek(pb, s->video_chunk_offset, SEEK_SET); s->video_chunk_offset = 0; if (avio_read(pb, pkt->data + s->decode_map_chunk_size, s->video_chunk_size) != s->video_chunk_size) { av_free_packet(pkt); return CHUNK_EOF; } pkt->stream_index = s->video_stream_index; pkt->pts = s->video_pts; av_log(NULL, AV_LOG_TRACE, "sending video frame with pts %"PRId64"\n", pkt->pts); s->video_pts += s->frame_pts_inc; chunk_type = CHUNK_VIDEO; } else { avio_seek(pb, s->next_chunk_offset, SEEK_SET); chunk_type = CHUNK_DONE; } return chunk_type; }
int ff_img_read_header(AVFormatContext *s1) { VideoDemuxData *s = s1->priv_data; int first_index = 1, last_index = 1; AVStream *st; enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; s1->ctx_flags |= AVFMTCTX_NOHEADER; st = avformat_new_stream(s1, NULL); if (!st) { return AVERROR(ENOMEM); } if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) { av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format); return AVERROR(EINVAL); } av_strlcpy(s->path, s1->filename, sizeof(s->path)); s->img_number = 0; s->img_count = 0; /* find format */ if (s1->iformat->flags & AVFMT_NOFILE) s->is_pipe = 0; else { s->is_pipe = 1; st->need_parsing = AVSTREAM_PARSE_FULL; } if (s->ts_from_file == 2) { #if !HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC av_log(s1, AV_LOG_ERROR, "POSIX.1-2008 not supported, nanosecond file timestamps unavailable\n"); return AVERROR(ENOSYS); #endif avpriv_set_pts_info(st, 64, 1, 1000000000); } else if (s->ts_from_file) avpriv_set_pts_info(st, 64, 1, 1); else avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num); if (s->width && s->height) { st->codec->width = s->width; st->codec->height = s->height; } if (!s->is_pipe) { if (s->pattern_type == PT_GLOB_SEQUENCE) { s->use_glob = is_glob(s->path); if (s->use_glob) { #if HAVE_GLOB char *p = s->path, *q, *dup; int gerr; #endif av_log(s1, AV_LOG_WARNING, "Pattern type 'glob_sequence' is deprecated: " "use pattern_type 'glob' instead\n"); #if HAVE_GLOB dup = q = av_strdup(p); while (*q) { /* Do we have room for the next char and a \ insertion? */ if ((p - s->path) >= (sizeof(s->path) - 2)) break; if (*q == '%' && strspn(q + 1, "%*?[]{}")) ++q; else if (strspn(q, "\\*?[]{}")) *p++ = '\\'; *p++ = *q++; } *p = 0; av_free(dup); gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); if (gerr != 0) { return AVERROR(ENOENT); } first_index = 0; last_index = s->globstate.gl_pathc - 1; #endif } } if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) { if (find_image_range(s1->pb, &first_index, &last_index, s->path, s->start_number, s->start_number_range) < 0) { av_log(s1, AV_LOG_ERROR, "Could find no file with path '%s' and index in the range %d-%d\n", s->path, s->start_number, s->start_number + s->start_number_range - 1); return AVERROR(ENOENT); } } else if (s->pattern_type == PT_GLOB) { #if HAVE_GLOB int gerr; gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); if (gerr != 0) { return AVERROR(ENOENT); } first_index = 0; last_index = s->globstate.gl_pathc - 1; s->use_glob = 1; #else av_log(s1, AV_LOG_ERROR, "Pattern type 'glob' was selected but globbing " "is not supported by this libavformat build\n"); return AVERROR(ENOSYS); #endif } else if (s->pattern_type != PT_GLOB_SEQUENCE && s->pattern_type != PT_NONE) { av_log(s1, AV_LOG_ERROR, "Unknown value '%d' for pattern_type option\n", s->pattern_type); return AVERROR(EINVAL); } s->img_first = first_index; s->img_last = last_index; s->img_number = first_index; /* compute duration */ if (!s->ts_from_file) { st->start_time = 0; st->duration = last_index - first_index + 1; } } if (s1->video_codec_id) { st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = s1->video_codec_id; } else if (s1->audio_codec_id) { st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = s1->audio_codec_id; } else if (s1->iformat->raw_codec_id) { st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = s1->iformat->raw_codec_id; } else { const char *str = strrchr(s->path, '.'); s->split_planes = str && !av_strcasecmp(str + 1, "y"); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; if (s1->pb) { int probe_buffer_size = 2048; uint8_t *probe_buffer = av_realloc(NULL, probe_buffer_size + AVPROBE_PADDING_SIZE); AVInputFormat *fmt = NULL; AVProbeData pd = { 0 }; if (!probe_buffer) return AVERROR(ENOMEM); probe_buffer_size = avio_read(s1->pb, probe_buffer, probe_buffer_size); if (probe_buffer_size < 0) { av_free(probe_buffer); return probe_buffer_size; } memset(probe_buffer + probe_buffer_size, 0, AVPROBE_PADDING_SIZE); pd.buf = probe_buffer; pd.buf_size = probe_buffer_size; pd.filename = s1->filename; while ((fmt = av_iformat_next(fmt))) { if (fmt->read_header != ff_img_read_header || !fmt->read_probe || (fmt->flags & AVFMT_NOFILE) || !fmt->raw_codec_id) continue; if (fmt->read_probe(&pd) > 0) { st->codec->codec_id = fmt->raw_codec_id; break; } } if (s1->flags & AVFMT_FLAG_CUSTOM_IO) { avio_seek(s1->pb, 0, SEEK_SET); } else ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size); } if (st->codec->codec_id == AV_CODEC_ID_NONE) st->codec->codec_id = ff_guess_image2_codec(s->path); if (st->codec->codec_id == AV_CODEC_ID_LJPEG) st->codec->codec_id = AV_CODEC_ID_MJPEG; if (st->codec->codec_id == AV_CODEC_ID_ALIAS_PIX) // we cannot distingiush this from BRENDER_PIX st->codec->codec_id = AV_CODEC_ID_NONE; } if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pix_fmt != AV_PIX_FMT_NONE) st->codec->pix_fmt = pix_fmt; return 0; }
static int ipmovie_read_header(AVFormatContext *s) { IPMVEContext *ipmovie = s->priv_data; AVIOContext *pb = s->pb; AVPacket pkt; AVStream *st; unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; int chunk_type, i; uint8_t signature_buffer[sizeof(signature)]; ipmovie->avf = s; 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 (avio_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; for (i = 0; i < 256; i++) ipmovie->palette[i] = 0xFFU << 24; /* 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 = AV_CODEC_ID_NONE; /* no audio */ else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO) return AVERROR_INVALIDDATA; /* initialize the stream decoders */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 63, 1, 1000000); ipmovie->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_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) { return init_audio(s); } else s->ctx_flags |= AVFMTCTX_NOHEADER; return 0; }
int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoDemuxData *s = s1->priv_data; char filename_bytes[1024]; char *filename = filename_bytes; int i, res; int size[3] = { 0 }, ret[3] = { 0 }; AVIOContext *f[3] = { NULL }; AVCodecContext *codec = s1->streams[0]->codec; if (!s->is_pipe) { /* loop over input */ if (s->loop && s->img_number > s->img_last) { s->img_number = s->img_first; } if (s->img_number > s->img_last) return AVERROR_EOF; if (s->pattern_type == PT_NONE) { av_strlcpy(filename_bytes, s->path, sizeof(filename_bytes)); } else if (s->use_glob) { #if HAVE_GLOB filename = s->globstate.gl_pathv[s->img_number]; #endif } else { if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes), s->path, s->img_number) < 0 && s->img_number > 1) return AVERROR(EIO); } for (i = 0; i < 3; i++) { if (s1->pb && !strcmp(filename_bytes, s->path) && !s->loop && !s->split_planes) { f[i] = s1->pb; } else if (avio_open2(&f[i], filename, AVIO_FLAG_READ, &s1->interrupt_callback, NULL) < 0) { if (i >= 1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n", filename); return AVERROR(EIO); } size[i] = avio_size(f[i]); if (!s->split_planes) break; filename[strlen(filename) - 1] = 'U' + i; } if (codec->codec_id == AV_CODEC_ID_NONE) { AVProbeData pd = { 0 }; AVInputFormat *ifmt; uint8_t header[PROBE_BUF_MIN + AVPROBE_PADDING_SIZE]; int ret; int score = 0; ret = avio_read(f[0], header, PROBE_BUF_MIN); if (ret < 0) return ret; memset(header + ret, 0, sizeof(header) - ret); avio_skip(f[0], -ret); pd.buf = header; pd.buf_size = ret; pd.filename = filename; ifmt = av_probe_input_format3(&pd, 1, &score); if (ifmt && ifmt->read_packet == ff_img_read_packet && ifmt->raw_codec_id) codec->codec_id = ifmt->raw_codec_id; } if (codec->codec_id == AV_CODEC_ID_RAWVIDEO && !codec->width) infer_size(&codec->width, &codec->height, size[0]); } else { f[0] = s1->pb; if (avio_feof(f[0]) && s->loop && s->is_pipe) avio_seek(f[0], 0, SEEK_SET); if (avio_feof(f[0])) return AVERROR_EOF; if (s->frame_size > 0) { size[0] = s->frame_size; } else if (!s1->streams[0]->parser) { size[0] = avio_size(s1->pb); } else { size[0] = 4096; } } res = av_new_packet(pkt, size[0] + size[1] + size[2]); if (res < 0) { goto fail; } pkt->stream_index = 0; pkt->flags |= AV_PKT_FLAG_KEY; if (s->ts_from_file) { struct stat img_stat; if (stat(filename, &img_stat)) { res = AVERROR(EIO); goto fail; } pkt->pts = (int64_t)img_stat.st_mtime; #if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC if (s->ts_from_file == 2) pkt->pts = 1000000000*pkt->pts + img_stat.st_mtim.tv_nsec; #endif av_add_index_entry(s1->streams[0], s->img_number, pkt->pts, 0, 0, AVINDEX_KEYFRAME); } else if (!s->is_pipe) { pkt->pts = s->pts; } if (s->is_pipe) pkt->pos = avio_tell(f[0]); pkt->size = 0; for (i = 0; i < 3; i++) { if (f[i]) { ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); if (s->loop && s->is_pipe && ret[i] == AVERROR_EOF) { if (avio_seek(f[i], 0, SEEK_SET) >= 0) { pkt->pos = 0; ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); } } if (!s->is_pipe && f[i] != s1->pb) avio_closep(&f[i]); if (ret[i] > 0) pkt->size += ret[i]; } } if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) { av_packet_unref(pkt); if (ret[0] < 0) { res = ret[0]; } else if (ret[1] < 0) { res = ret[1]; } else if (ret[2] < 0) { res = ret[2]; } else { res = AVERROR_EOF; } goto fail; } else { s->img_count++; s->img_number++; s->pts++; return 0; } fail: if (!s->is_pipe) { for (i = 0; i < 3; i++) { if (f[i] != s1->pb) avio_closep(&f[i]); } } return res; }
/** * read rl2 header data and setup the avstreams * @param s demuxer context * @param ap format parameters * @return 0 on success, AVERROR otherwise */ static av_cold int rl2_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVIOContext *pb = s->pb; AVStream *st; unsigned int frame_count; unsigned int audio_frame_counter = 0; unsigned int video_frame_counter = 0; unsigned int back_size; unsigned short sound_rate; unsigned short rate; unsigned short channels; unsigned short def_sound_size; unsigned int signature; unsigned int pts_den = 11025; /* video only case */ unsigned int pts_num = 1103; unsigned int* chunk_offset = NULL; int* chunk_size = NULL; int* audio_size = NULL; int i; int ret = 0; avio_skip(pb,4); /* skip FORM tag */ back_size = avio_rl32(pb); /**< get size of the background frame */ signature = avio_rb32(pb); avio_skip(pb, 4); /* data size */ frame_count = avio_rl32(pb); /* disallow back_sizes and frame_counts that may lead to overflows later */ if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t)) return AVERROR_INVALIDDATA; avio_skip(pb, 2); /* encoding mentod */ sound_rate = avio_rl16(pb); rate = avio_rl16(pb); channels = avio_rl16(pb); def_sound_size = avio_rl16(pb); /** setup video stream */ st = avformat_new_stream(s, NULL); if(!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_RL2; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = 320; st->codec->height = 200; /** allocate and fill extradata */ st->codec->extradata_size = EXTRADATA1_SIZE; if(signature == RLV3_TAG && back_size > 0) st->codec->extradata_size += back_size; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!st->codec->extradata) return AVERROR(ENOMEM); if(avio_read(pb,st->codec->extradata,st->codec->extradata_size) != st->codec->extradata_size) return AVERROR(EIO); /** setup audio stream if present */ if(sound_rate){ pts_num = def_sound_size; pts_den = rate; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_PCM_U8; st->codec->codec_tag = 1; st->codec->channels = channels; st->codec->bits_per_coded_sample = 8; st->codec->sample_rate = rate; 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 / 8; av_set_pts_info(st,32,1,rate); } av_set_pts_info(s->streams[0], 32, pts_num, pts_den); chunk_size = av_malloc(frame_count * sizeof(uint32_t)); audio_size = av_malloc(frame_count * sizeof(uint32_t)); chunk_offset = av_malloc(frame_count * sizeof(uint32_t)); if(!chunk_size || !audio_size || !chunk_offset){ av_free(chunk_size); av_free(audio_size); av_free(chunk_offset); return AVERROR(ENOMEM); } /** read offset and size tables */ for(i=0; i < frame_count;i++) chunk_size[i] = avio_rl32(pb); for(i=0; i < frame_count;i++) chunk_offset[i] = avio_rl32(pb); for(i=0; i < frame_count;i++) audio_size[i] = avio_rl32(pb) & 0xFFFF; /** build the sample index */ for(i=0;i<frame_count;i++){ if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){ ret = AVERROR_INVALIDDATA; break; } if(sound_rate && audio_size[i]){ av_add_index_entry(s->streams[1], chunk_offset[i], audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME); audio_frame_counter += audio_size[i] / channels; } av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i], video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME); ++video_frame_counter; } av_free(chunk_size); av_free(audio_size); av_free(chunk_offset); return ret; }
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 { st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); if (avio_read(pb, st->codec->extradata, size) != size) { av_freep(&st->codec->extradata); return AVERROR(EIO); } st->codec->extradata_size = size; 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 fourxm_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; unsigned int fourcc_tag; unsigned int size; int header_size; FourxmDemuxContext *fourxm = s->priv_data; unsigned char *header; int i, ret; fourxm->track_count = 0; fourxm->tracks = NULL; fourxm->fps = 1.0; /* skip the first 3 32-bit numbers */ avio_skip(pb, 12); /* check for LIST-HEAD */ GET_LIST_HEADER(); header_size = size - 4; if (fourcc_tag != HEAD_TAG || header_size < 0) return AVERROR_INVALIDDATA; /* allocate space for the header and load the whole thing */ header = av_malloc(header_size); if (!header) return AVERROR(ENOMEM); if (avio_read(pb, header, header_size) != header_size) { av_free(header); return AVERROR(EIO); } /* take the lazy approach and search for any and all vtrk and strk chunks */ for (i = 0; i < header_size - 8; i++) { fourcc_tag = AV_RL32(&header[i]); size = AV_RL32(&header[i + 4]); if (fourcc_tag == std__TAG) { if (header_size - i < 16) { ret = AVERROR_INVALIDDATA; goto fail; } fourxm->fps = av_int2float(AV_RL32(&header[i + 12])); } else if (fourcc_tag == vtrk_TAG) { if ((ret = parse_vtrk(s, fourxm, header + i, size, header_size - i)) < 0) goto fail; i += 8 + size; } else if (fourcc_tag == strk_TAG) { if ((ret = parse_strk(s, fourxm, header + i, size, header_size - i)) < 0) goto fail; i += 8 + size; } } /* skip over the LIST-MOVI chunk (which is where the stream should be */ GET_LIST_HEADER(); if (fourcc_tag != MOVI_TAG) { ret = AVERROR_INVALIDDATA; goto fail; } av_free(header); /* initialize context members */ fourxm->video_pts = -1; /* first frame will push to 0 */ return 0; fail: av_freep(&fourxm->tracks); av_free(header); return ret; }
static int read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoData *s = s1->priv_data; char filename[1024]; int i; int size[3]={0}, ret[3]={0}; AVIOContext *f[3]; AVCodecContext *codec= s1->streams[0]->codec; if (!s->is_pipe) { /* loop over input */ if (s1->loop_input && s->img_number > s->img_last) { s->img_number = s->img_first; } if (s->img_number > s->img_last) return AVERROR_EOF; if (av_get_frame_filename(filename, sizeof(filename), s->path, s->img_number)<0 && s->img_number > 1) return AVERROR(EIO); for(i=0; i<3; i++){ if (avio_open(&f[i], filename, AVIO_FLAG_READ) < 0) { if(i==1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",filename); return AVERROR(EIO); } size[i]= avio_size(f[i]); if(!s->split_planes) break; filename[ strlen(filename) - 1 ]= 'U' + i; } if(codec->codec_id == CODEC_ID_RAWVIDEO && !codec->width) infer_size(&codec->width, &codec->height, size[0]); } else { f[0] = s1->pb; if (url_feof(f[0])) return AVERROR(EIO); size[0]= 4096; } av_new_packet(pkt, size[0] + size[1] + size[2]); pkt->stream_index = 0; pkt->flags |= AV_PKT_FLAG_KEY; pkt->size= 0; for(i=0; i<3; i++){ if(size[i]){ ret[i]= avio_read(f[i], pkt->data + pkt->size, size[i]); if (!s->is_pipe) avio_close(f[i]); if(ret[i]>0) pkt->size += ret[i]; } } if (ret[0] <= 0 || ret[1]<0 || ret[2]<0) { av_free_packet(pkt); return AVERROR(EIO); /* signal EOF */ } else { s->img_count++; s->img_number++; return 0; } }
static int mpc_read_header(AVFormatContext *s) { MPCContext *c = s->priv_data; AVStream *st; if(avio_rl24(s->pb) != MKTAG('M', 'P', '+', 0)){ av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); return -1; } c->ver = avio_r8(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 = avio_rl32(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; } if(c->fcount){ c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); if(!c->frames){ av_log(s, AV_LOG_ERROR, "Cannot allocate seektable\n"); return AVERROR(ENOMEM); } }else{ av_log(s, AV_LOG_WARNING, "Container reports no frames\n"); } c->curframe = 0; c->lastframe = -1; c->curbits = 8; c->frames_noted = 0; st = avformat_new_stream(s, NULL); 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); avio_read(s->pb, st->codec->extradata, 16); st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; avpriv_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 (s->pb->seekable) { int64_t pos = avio_tell(s->pb); ff_ape_parse_tag(s); if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) ff_id3v1_read(s); avio_seek(s->pb, pos, SEEK_SET); } return 0; }
/* aiff input */ static int aiff_read_header(AVFormatContext *s, AVFormatParameters *ap) { int size, filesize; int64_t offset = 0; uint32_t tag; unsigned version = AIFF_C_VERSION1; AVIOContext *pb = s->pb; AVStream * st; AIFFInputContext *aiff = s->priv_data; /* check FORM header */ filesize = get_tag(pb, &tag); if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M')) return AVERROR_INVALIDDATA; /* AIFF data type */ tag = avio_rl32(pb); if (tag == MKTAG('A', 'I', 'F', 'F')) /* Got an AIFF file */ version = AIFF; else if (tag != MKTAG('A', 'I', 'F', 'C')) /* An AIFF-C file then */ return AVERROR_INVALIDDATA; filesize -= 4; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); while (filesize > 0) { /* parse different chunks */ size = get_tag(pb, &tag); if (size < 0) return size; filesize -= size + 8; switch (tag) { case MKTAG('C', 'O', 'M', 'M'): /* Common chunk */ /* Then for the complete header info */ st->nb_frames = get_aiff_header(pb, st->codec, size, version); if (st->nb_frames < 0) return st->nb_frames; if (offset > 0) // COMM is after SSND goto got_sound; break; case MKTAG('F', 'V', 'E', 'R'): /* Version chunk */ version = avio_rb32(pb); break; case MKTAG('N', 'A', 'M', 'E'): /* Sample name chunk */ get_meta(s, "title" , size); break; case MKTAG('A', 'U', 'T', 'H'): /* Author chunk */ get_meta(s, "author" , size); break; case MKTAG('(', 'c', ')', ' '): /* Copyright chunk */ get_meta(s, "copyright", size); break; case MKTAG('A', 'N', 'N', 'O'): /* Annotation chunk */ get_meta(s, "comment" , size); break; case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */ aiff->data_end = avio_tell(pb) + size; offset = avio_rb32(pb); /* Offset of sound data */ avio_rb32(pb); /* BlockSize... don't care */ offset += avio_tell(pb); /* Compute absolute data offset */ if (st->codec->block_align) /* Assume COMM already parsed */ goto got_sound; if (!pb->seekable) { av_log(s, AV_LOG_ERROR, "file is not seekable\n"); return -1; } avio_skip(pb, size - 8); break; case MKTAG('w', 'a', 'v', 'e'): if ((uint64_t)size > (1<<30)) return -1; st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); st->codec->extradata_size = size; avio_read(pb, st->codec->extradata, size); break; default: /* Jump */ if (size & 1) /* Always even aligned */ size++; avio_skip(pb, size); } } if (!st->codec->block_align) { av_log(s, AV_LOG_ERROR, "could not find COMM tag\n"); return -1; } got_sound: /* Now positioned, get the sound data start and end */ if (st->nb_frames) s->file_size = st->nb_frames * st->codec->block_align; av_set_pts_info(st, 64, 1, st->codec->sample_rate); st->start_time = 0; st->duration = st->codec->frame_size ? st->nb_frames * st->codec->frame_size : st->nb_frames; /* Position the stream at the first block */ avio_seek(pb, offset, SEEK_SET); return 0; }
static int idcin_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret; unsigned int command; unsigned int chunk_size; IdcinDemuxContext *idcin = s->priv_data; AVIOContext *pb = s->pb; int i; int palette_scale; unsigned char r, g, b; unsigned char palette_buffer[768]; uint32_t palette[256]; if (url_feof(s->pb)) return AVERROR(EIO); if (idcin->next_chunk_is_video) { command = avio_rl32(pb); if (command == 2) { return AVERROR(EIO); } else if (command == 1) { /* trigger a palette change */ if (avio_read(pb, palette_buffer, 768) != 768) return AVERROR(EIO); /* scale the palette as necessary */ palette_scale = 2; for (i = 0; i < 768; i++) if (palette_buffer[i] > 63) { palette_scale = 0; break; } for (i = 0; i < 256; i++) { r = palette_buffer[i * 3 ] << palette_scale; g = palette_buffer[i * 3 + 1] << palette_scale; b = palette_buffer[i * 3 + 2] << palette_scale; palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b); if (palette_scale == 2) palette[i] |= palette[i] >> 6 & 0x30303; } } chunk_size = avio_rl32(pb); /* skip the number of decoded bytes (always equal to width * height) */ avio_skip(pb, 4); if (chunk_size < 4) return AVERROR_INVALIDDATA; chunk_size -= 4; ret= av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; if (command == 1) { uint8_t *pal; pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); if (!pal) return AVERROR(ENOMEM); memcpy(pal, palette, AVPALETTE_SIZE); } pkt->stream_index = idcin->video_stream_index; pkt->pts = idcin->pts; } else {
static int avs_read_packet(AVFormatContext * s, AVPacket * pkt) { AvsFormat *avs = s->priv_data; int sub_type = 0, size = 0; AvsBlockType type = AVS_NONE; int palette_size = 0; uint8_t palette[4 + 3 * 256]; int ret; if (avs->remaining_audio_size > 0) if (avs_read_audio_packet(s, pkt) > 0) return 0; while (1) { if (avs->remaining_frame_size <= 0) { if (!avio_rl16(s->pb)) /* found EOF */ return AVERROR(EIO); avs->remaining_frame_size = avio_rl16(s->pb) - 4; } while (avs->remaining_frame_size > 0) { sub_type = avio_r8(s->pb); type = avio_r8(s->pb); size = avio_rl16(s->pb); if (size < 4) return AVERROR_INVALIDDATA; avs->remaining_frame_size -= size; switch (type) { case AVS_PALETTE: if (size - 4 > sizeof(palette)) return AVERROR_INVALIDDATA; ret = avio_read(s->pb, palette, size - 4); if (ret < size - 4) return AVERROR(EIO); palette_size = size; break; case AVS_VIDEO: if (!avs->st_video) { avs->st_video = avformat_new_stream(s, NULL); if (avs->st_video == NULL) return AVERROR(ENOMEM); avs->st_video->codec->codec_type = AVMEDIA_TYPE_VIDEO; avs->st_video->codec->codec_id = CODEC_ID_AVS; avs->st_video->codec->width = avs->width; avs->st_video->codec->height = avs->height; avs->st_video->codec->bits_per_coded_sample=avs->bits_per_sample; avs->st_video->nb_frames = avs->nb_frames; avs->st_video->r_frame_rate = avs->st_video->avg_frame_rate = (AVRational){avs->fps, 1}; } return avs_read_video_packet(s, pkt, type, sub_type, size, palette, palette_size); case AVS_AUDIO: if (!avs->st_audio) { avs->st_audio = avformat_new_stream(s, NULL); if (avs->st_audio == NULL) return AVERROR(ENOMEM); avs->st_audio->codec->codec_type = AVMEDIA_TYPE_AUDIO; } avs->remaining_audio_size = size - 4; size = avs_read_audio_packet(s, pkt); if (size != 0) return size; break; default: avio_skip(s->pb, size - 4); } } } }