static int iff_read_header(AVFormatContext *s) { IffDemuxContext *iff = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; uint8_t *buf; uint32_t chunk_id, data_size; uint32_t screenmode = 0, num, den; unsigned transparency = 0; unsigned masking = 0; // no mask uint8_t fmt[16]; int fmt_size; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; avio_skip(pb, 8); // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content st->codec->codec_tag = avio_rl32(pb); iff->bitmap_compression = -1; iff->svx8_compression = -1; iff->maud_bits = -1; iff->maud_compression = -1; while(!url_feof(pb)) { uint64_t orig_pos; int res; const char *metadata_tag = NULL; chunk_id = avio_rl32(pb); data_size = avio_rb32(pb); orig_pos = avio_tell(pb); switch(chunk_id) { case ID_VHDR: st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (data_size < 14) return AVERROR_INVALIDDATA; avio_skip(pb, 12); st->codec->sample_rate = avio_rb16(pb); if (data_size >= 16) { avio_skip(pb, 1); iff->svx8_compression = avio_r8(pb); } break; case ID_MHDR: st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (data_size < 32) return AVERROR_INVALIDDATA; avio_skip(pb, 4); iff->maud_bits = avio_rb16(pb); avio_skip(pb, 2); num = avio_rb32(pb); den = avio_rb16(pb); if (!den) return AVERROR_INVALIDDATA; avio_skip(pb, 2); st->codec->sample_rate = num / den; st->codec->channels = avio_rb16(pb); iff->maud_compression = avio_rb16(pb); if (st->codec->channels == 1) st->codec->channel_layout = AV_CH_LAYOUT_MONO; else if (st->codec->channels == 2) st->codec->channel_layout = AV_CH_LAYOUT_STEREO; break; case ID_ABIT: case ID_BODY: case ID_DBOD: case ID_MDAT: iff->body_pos = avio_tell(pb); iff->body_end = iff->body_pos + data_size; iff->body_size = data_size; break; case ID_CHAN: if (data_size < 4) return AVERROR_INVALIDDATA; if (avio_rb32(pb) < 6) { st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; } else { st->codec->channels = 2; st->codec->channel_layout = AV_CH_LAYOUT_STEREO; } break; case ID_CAMG: if (data_size < 4) return AVERROR_INVALIDDATA; screenmode = avio_rb32(pb); break; case ID_CMAP: if (data_size > INT_MAX - IFF_EXTRA_VIDEO_SIZE - FF_INPUT_BUFFER_PADDING_SIZE) return AVERROR_INVALIDDATA; st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE; st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0) return AVERROR(EIO); break; case ID_BMHD: st->codec->codec_type = AVMEDIA_TYPE_VIDEO; if (data_size <= 8) return AVERROR_INVALIDDATA; st->codec->width = avio_rb16(pb); st->codec->height = avio_rb16(pb); avio_skip(pb, 4); // x, y offset st->codec->bits_per_coded_sample = avio_r8(pb); if (data_size >= 10) masking = avio_r8(pb); if (data_size >= 11) iff->bitmap_compression = avio_r8(pb); if (data_size >= 14) { avio_skip(pb, 1); // padding transparency = avio_rb16(pb); } if (data_size >= 16) { st->sample_aspect_ratio.num = avio_r8(pb); st->sample_aspect_ratio.den = avio_r8(pb); } break; case ID_DPEL: if (data_size < 4 || (data_size & 3)) return AVERROR_INVALIDDATA; if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0) return fmt_size; if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24))) st->codec->pix_fmt = AV_PIX_FMT_RGB24; else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba))) st->codec->pix_fmt = AV_PIX_FMT_RGBA; else if (fmt_size == sizeof(deep_bgra) && !memcmp(fmt, deep_bgra, sizeof(deep_bgra))) st->codec->pix_fmt = AV_PIX_FMT_BGRA; else if (fmt_size == sizeof(deep_argb) && !memcmp(fmt, deep_argb, sizeof(deep_argb))) st->codec->pix_fmt = AV_PIX_FMT_ARGB; else if (fmt_size == sizeof(deep_abgr) && !memcmp(fmt, deep_abgr, sizeof(deep_abgr))) st->codec->pix_fmt = AV_PIX_FMT_ABGR; else { av_log_ask_for_sample(s, "unsupported color format\n"); return AVERROR_PATCHWELCOME; } break; case ID_DGBL: st->codec->codec_type = AVMEDIA_TYPE_VIDEO; if (data_size < 8) return AVERROR_INVALIDDATA; st->codec->width = avio_rb16(pb); st->codec->height = avio_rb16(pb); iff->bitmap_compression = avio_rb16(pb); st->sample_aspect_ratio.num = avio_r8(pb); st->sample_aspect_ratio.den = avio_r8(pb); st->codec->bits_per_coded_sample = 24; break; case ID_DLOC: if (data_size < 4) return AVERROR_INVALIDDATA; st->codec->width = avio_rb16(pb); st->codec->height = avio_rb16(pb); break; case ID_TVDC: if (data_size < sizeof(iff->tvdc)) return AVERROR_INVALIDDATA; res = avio_read(pb, iff->tvdc, sizeof(iff->tvdc)); if (res < 0) return res; break; case ID_ANNO: case ID_TEXT: metadata_tag = "comment"; break; case ID_AUTH: metadata_tag = "artist"; break; case ID_COPYRIGHT: metadata_tag = "copyright"; break; case ID_NAME: metadata_tag = "title"; break; } if (metadata_tag) { if ((res = get_metadata(s, metadata_tag, data_size)) < 0) { av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!\n", metadata_tag); return res; } } avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1)); } avio_seek(pb, iff->body_pos, SEEK_SET); switch(st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); if (st->codec->codec_tag == ID_16SV) st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR; else if (st->codec->codec_tag == ID_MAUD) { if (iff->maud_bits == 8 && !iff->maud_compression) { st->codec->codec_id = AV_CODEC_ID_PCM_U8; } else if (iff->maud_bits == 16 && !iff->maud_compression) { st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; } else if (iff->maud_bits == 8 && iff->maud_compression == 2) { st->codec->codec_id = AV_CODEC_ID_PCM_ALAW; } else if (iff->maud_bits == 8 && iff->maud_compression == 3) { st->codec->codec_id = AV_CODEC_ID_PCM_MULAW; } else { av_log_ask_for_sample(s, "unsupported compression %d and bit depth %d\n", iff->maud_compression, iff->maud_bits); return AVERROR_PATCHWELCOME; } st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8; } else { switch (iff->svx8_compression) { case COMP_NONE: st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR; break; case COMP_FIB: st->codec->codec_id = AV_CODEC_ID_8SVX_FIB; break; case COMP_EXP: st->codec->codec_id = AV_CODEC_ID_8SVX_EXP; break; default: av_log(s, AV_LOG_ERROR, "Unknown SVX8 compression method '%d'\n", iff->svx8_compression); return -1; } } st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; break; case AVMEDIA_TYPE_VIDEO: iff->bpp = st->codec->bits_per_coded_sample; if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) { iff->ham = iff->bpp > 6 ? 6 : 4; st->codec->bits_per_coded_sample = 24; } iff->flags = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8; iff->masking = masking; iff->transparency = transparency; if (!st->codec->extradata) { st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE; st->codec->extradata = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); } av_assert0(st->codec->extradata_size >= IFF_EXTRA_VIDEO_SIZE); buf = st->codec->extradata; bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE); bytestream_put_byte(&buf, iff->bitmap_compression); bytestream_put_byte(&buf, iff->bpp); bytestream_put_byte(&buf, iff->ham); bytestream_put_byte(&buf, iff->flags); bytestream_put_be16(&buf, iff->transparency); bytestream_put_byte(&buf, iff->masking); bytestream_put_buffer(&buf, iff->tvdc, sizeof(iff->tvdc)); st->codec->codec_id = AV_CODEC_ID_IFF_ILBM; break; default: return -1; } 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; 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->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 (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; } } if (av_new_packet(pkt, size[0] + size[1] + size[2]) < 0) return AVERROR(ENOMEM); pkt->stream_index = 0; pkt->flags |= AV_PKT_FLAG_KEY; if (s->ts_from_file) { struct stat img_stat; if (stat(filename, &img_stat)) return AVERROR(EIO); 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) 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); if (ret[0] < 0) { return ret[0]; } else if (ret[1] < 0) { return ret[1]; } else if (ret[2] < 0) return ret[2]; return AVERROR_EOF; } else { s->img_count++; s->img_number++; s->pts++; return 0; } }
static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap) { TTAContext *c = s->priv_data; AVStream *st; int i, channels, bps, samplerate, datalen, framelen; uint64_t framepos, start_offset; if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) ff_id3v1_read(s); start_offset = avio_tell(s->pb); if (avio_rl32(s->pb) != AV_RL32("TTA1")) return -1; // not tta file avio_skip(s->pb, 2); // FIXME: flags channels = avio_rl16(s->pb); bps = avio_rl16(s->pb); samplerate = avio_rl32(s->pb); if(samplerate <= 0 || samplerate > 1000000){ av_log(s, AV_LOG_ERROR, "nonsense samplerate\n"); return -1; } datalen = avio_rl32(s->pb); if(datalen < 0){ av_log(s, AV_LOG_ERROR, "nonsense datalen\n"); return -1; } avio_skip(s->pb, 4); // header crc framelen = samplerate*256/245; c->totalframes = datalen / framelen + ((datalen % framelen) ? 1 : 0); c->currentframe = 0; if(c->totalframes >= UINT_MAX/sizeof(uint32_t)){ av_log(s, AV_LOG_ERROR, "totalframes too large\n"); return -1; } st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); av_set_pts_info(st, 64, 1, samplerate); st->start_time = 0; st->duration = datalen; framepos = avio_tell(s->pb) + 4*c->totalframes + 4; for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); av_add_index_entry(st, framepos, i*framelen, size, 0, AVINDEX_KEYFRAME); framepos += size; } avio_skip(s->pb, 4); // seektable crc st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_TTA; st->codec->channels = channels; st->codec->sample_rate = samplerate; st->codec->bits_per_coded_sample = bps; st->codec->extradata_size = avio_tell(s->pb) - start_offset; if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){ //this check is redundant as avio_read should fail av_log(s, AV_LOG_ERROR, "extradata_size too large\n"); return -1; } st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); avio_seek(s->pb, start_offset, SEEK_SET); avio_read(s->pb, st->codec->extradata, st->codec->extradata_size); return 0; }
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) return AVERROR(ENOMEM); avs->st_video->codec->codec_type = AVMEDIA_TYPE_VIDEO; avs->st_video->codec->codec_id = AV_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; #if FF_API_R_FRAME_RATE avs->st_video->r_frame_rate = #endif 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) 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); } } } }
static int wsvqa_read_header(AVFormatContext *s) { WsVqaDemuxContext *wsvqa = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; uint8_t *header; uint8_t scratch[VQA_PREAMBLE_SIZE]; uint32_t chunk_tag; uint32_t chunk_size; int fps; /* initialize the video decoder stream */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->start_time = 0; wsvqa->video_stream_index = st->index; st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = AV_CODEC_ID_WS_VQA; st->codecpar->codec_tag = 0; /* no fourcc */ /* skip to the start of the VQA header */ avio_seek(pb, 20, SEEK_SET); /* the VQA header needs to go to the decoder */ if (ff_get_extradata(st->codecpar, pb, VQA_HEADER_SIZE) < 0) return AVERROR(ENOMEM); header = st->codecpar->extradata; st->codecpar->width = AV_RL16(&header[6]); st->codecpar->height = AV_RL16(&header[8]); fps = header[12]; st->nb_frames = st->duration = AV_RL16(&header[4]); if (fps < 1 || fps > 30) { av_log(s, AV_LOG_ERROR, "invalid fps: %d\n", fps); return AVERROR_INVALIDDATA; } avpriv_set_pts_info(st, 64, 1, fps); wsvqa->version = AV_RL16(&header[ 0]); wsvqa->sample_rate = AV_RL16(&header[24]); wsvqa->channels = header[26]; wsvqa->bps = header[27]; wsvqa->audio_stream_index = -1; s->ctx_flags |= AVFMTCTX_NOHEADER; /* there are 0 or more chunks before the FINF chunk; iterate until * FINF has been skipped and the file will be ready to be demuxed */ do { if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) return AVERROR(EIO); chunk_tag = AV_RB32(&scratch[0]); chunk_size = AV_RB32(&scratch[4]); /* catch any unknown header tags, for curiousity */ switch (chunk_tag) { case CINF_TAG: case CINH_TAG: case CIND_TAG: case PINF_TAG: case PINH_TAG: case PIND_TAG: case FINF_TAG: case CMDS_TAG: break; default: av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n", scratch[0], scratch[1], scratch[2], scratch[3]); break; } avio_skip(pb, chunk_size); } while (chunk_tag != FINF_TAG); return 0; }
int av_probe_input_buffer(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; uint8_t *mime_type_opt = NULL; if (!max_probe_size) max_probe_size = PROBE_BUF_MAX; else if (max_probe_size > PROBE_BUF_MAX) max_probe_size = PROBE_BUF_MAX; else if (max_probe_size < PROBE_BUF_MIN) return AVERROR(EINVAL); if (offset >= max_probe_size) return AVERROR(EINVAL); avio_skip(pb, offset); max_probe_size -= offset; if (pb->av_class) { av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type_opt); pd.mime_type = (const char *)mime_type_opt; mime_type_opt = NULL; } 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))) { int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX / 4 : 0; /* Read probe data. */ if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0) goto fail; if ((ret = avio_read(pb, buf + pd.buf_size, probe_size - pd.buf_size)) < 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 */ } pd.buf_size += ret; pd.buf = buf; 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_MAX / 4) { av_log(logctx, AV_LOG_WARNING, "Format detected only with low score of %d, " "misdetection possible!\n", score); } else av_log(logctx, AV_LOG_DEBUG, "Probed with size=%d and score=%d\n", probe_size, score); } } if (!*fmt) ret = AVERROR_INVALIDDATA; fail: /* Rewind. Reuse probe buffer to avoid seeking. */ if (ret < 0 || (ret = ffio_rewind_with_probe_data(pb, buf, pd.buf_size)) < 0) { av_free(buf); } av_freep(&pd.mime_type); return ret; }
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 (s->pb->eof_reached) 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] = (r << 16) | (g << 8) | (b); } } chunk_size = avio_rl32(pb); /* skip the number of decoded bytes (always equal to width * height) */ avio_skip(pb, 4); 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 (ret < 0) return ret; memcpy(pal, palette, AVPALETTE_SIZE); } pkt->stream_index = idcin->video_stream_index; pkt->pts = idcin->pts; } else { /* send out the audio chunk */ if (idcin->current_audio_chunk) chunk_size = idcin->audio_chunk_size2; else chunk_size = idcin->audio_chunk_size1; ret= av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; pkt->stream_index = idcin->audio_stream_index; pkt->pts = idcin->pts; idcin->current_audio_chunk ^= 1; idcin->pts++; } if (idcin->audio_present) idcin->next_chunk_is_video ^= 1; return ret; }
static int threedostr_read_header(AVFormatContext *s) { unsigned chunk, codec = 0, size, ctrl_size = -1, found_shdr = 0; AVStream *st; while (!avio_feof(s->pb) && !found_shdr) { chunk = avio_rl32(s->pb); size = avio_rb32(s->pb); if (size < 8) return AVERROR_INVALIDDATA; size -= 8; switch (chunk) { case MKTAG('C','T','R','L'): ctrl_size = size; break; case MKTAG('S','N','D','S'): if (size < 56) return AVERROR_INVALIDDATA; avio_skip(s->pb, 8); if (avio_rl32(s->pb) != MKTAG('S','H','D','R')) return AVERROR_INVALIDDATA; avio_skip(s->pb, 24); st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->sample_rate = avio_rb32(s->pb); st->codecpar->channels = avio_rb32(s->pb); if (st->codecpar->channels <= 0) return AVERROR_INVALIDDATA; codec = avio_rl32(s->pb); avio_skip(s->pb, 4); if (ctrl_size == 20 || ctrl_size == 3 || ctrl_size == -1) st->duration = (avio_rb32(s->pb) - 1) / st->codecpar->channels; else st->duration = avio_rb32(s->pb) * 16 / st->codecpar->channels; size -= 56; found_shdr = 1; break; case MKTAG('S','H','D','R'): if (size > 0x78) { avio_skip(s->pb, 0x74); size -= 0x78; if (avio_rl32(s->pb) == MKTAG('C','T','R','L') && size > 4) { ctrl_size = avio_rb32(s->pb); size -= 4; } } break; default: av_log(s, AV_LOG_DEBUG, "skipping unknown chunk: %X\n", chunk); break; } avio_skip(s->pb, size); } switch (codec) { case MKTAG('S','D','X','2'): st->codecpar->codec_id = AV_CODEC_ID_SDX2_DPCM; st->codecpar->block_align = 1 * st->codecpar->channels; break; default: avpriv_request_sample(s, "codec %X", codec); return AVERROR_PATCHWELCOME; } avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); return 0; }
static int gif_read_packet(AVFormatContext *s, AVPacket *pkt) { GIFDemuxContext *gdc = s->priv_data; AVIOContext *pb = s->pb; int packed_fields, block_label, ct_size, keyframe, frame_parsed = 0, ret; int64_t frame_start = avio_tell(pb), frame_end; unsigned char buf[6]; if ((ret = avio_read(pb, buf, 6)) == 6) { keyframe = memcmp(buf, gif87a_sig, 6) == 0 || memcmp(buf, gif89a_sig, 6) == 0; } else if (ret < 0) { return ret; } else { keyframe = 0; } if (keyframe) { parse_keyframe: /* skip 2 bytes of width and 2 of height */ if ((ret = avio_skip(pb, 4)) < 0) return ret; packed_fields = avio_r8(pb); /* skip 1 byte of Background Color Index and 1 byte of Pixel Aspect Ratio */ if ((ret = avio_skip(pb, 2)) < 0) return ret; /* global color table presence */ if (packed_fields & 0x80) { ct_size = 3 * (1 << ((packed_fields & 0x07) + 1)); if ((ret = avio_skip(pb, ct_size)) < 0) return ret; } } else { avio_seek(pb, -ret, SEEK_CUR); ret = AVERROR_EOF; } while (GIF_TRAILER != (block_label = avio_r8(pb)) && !avio_feof(pb)) { if (block_label == GIF_EXTENSION_INTRODUCER) { if ((ret = gif_read_ext (s)) < 0 ) goto resync; } else if (block_label == GIF_IMAGE_SEPARATOR) { /* skip to last byte of Image Descriptor header */ if ((ret = avio_skip(pb, 8)) < 0) return ret; packed_fields = avio_r8(pb); /* local color table presence */ if (packed_fields & 0x80) { ct_size = 3 * (1 << ((packed_fields & 0x07) + 1)); if ((ret = avio_skip(pb, ct_size)) < 0) return ret; } /* read LZW Minimum Code Size */ if (avio_r8(pb) < 1) { av_log(s, AV_LOG_ERROR, "lzw minimum code size must be >= 1\n"); goto resync; } if ((ret = gif_skip_subblocks(pb)) < 0) goto resync; frame_end = avio_tell(pb); if (avio_seek(pb, frame_start, SEEK_SET) != frame_start) return AVERROR(EIO); ret = av_get_packet(pb, pkt, frame_end - frame_start); if (ret < 0) return ret; if (keyframe) pkt->flags |= AV_PKT_FLAG_KEY; pkt->stream_index = 0; pkt->duration = gdc->delay; /* Graphic Control Extension's scope is single frame. * Remove its influence. */ gdc->delay = gdc->default_delay; frame_parsed = 1; break; } else { av_log(s, AV_LOG_ERROR, "invalid block label\n"); resync: if (!keyframe) avio_seek(pb, frame_start, SEEK_SET); if ((ret = resync(pb)) < 0) return ret; frame_start = avio_tell(pb) - 6; keyframe = 1; goto parse_keyframe; } } if ((ret >= 0 && !frame_parsed) || ret == AVERROR_EOF) { /* This might happen when there is no image block * between extension blocks and GIF_TRAILER or EOF */ if (!gdc->ignore_loop && (block_label == GIF_TRAILER || avio_feof(pb)) && (gdc->total_iter < 0 || ++gdc->iter_count < gdc->total_iter)) return avio_seek(pb, 0, SEEK_SET); return AVERROR_EOF; } else return ret; }
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; 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 = buffer; st->codec->extradata_size = metadata_size; buffer = NULL; /* get codec params from STREAMINFO header */ avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata); /* 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 = 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) { 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; }
static int ape_read_header(AVFormatContext * s) { AVIOContext *pb = s->pb; APEContext *ape = s->priv_data; AVStream *st; uint32_t tag; int i; int total_blocks, final_size = 0; int64_t pts, file_size; /* Skip any leading junk such as id3v2 tags */ ape->junklength = avio_tell(pb); tag = avio_rl32(pb); if (tag != MKTAG('M', 'A', 'C', ' ')) return AVERROR_INVALIDDATA; ape->fileversion = avio_rl16(pb); if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) { av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10); return AVERROR_PATCHWELCOME; } if (ape->fileversion >= 3980) { ape->padding1 = avio_rl16(pb); ape->descriptorlength = avio_rl32(pb); ape->headerlength = avio_rl32(pb); ape->seektablelength = avio_rl32(pb); ape->wavheaderlength = avio_rl32(pb); ape->audiodatalength = avio_rl32(pb); ape->audiodatalength_high = avio_rl32(pb); ape->wavtaillength = avio_rl32(pb); avio_read(pb, ape->md5, 16); /* Skip any unknown bytes at the end of the descriptor. This is for future compatibility */ if (ape->descriptorlength > 52) avio_skip(pb, ape->descriptorlength - 52); /* Read header data */ ape->compressiontype = avio_rl16(pb); ape->formatflags = avio_rl16(pb); ape->blocksperframe = avio_rl32(pb); ape->finalframeblocks = avio_rl32(pb); ape->totalframes = avio_rl32(pb); ape->bps = avio_rl16(pb); ape->channels = avio_rl16(pb); ape->samplerate = avio_rl32(pb); } else { ape->descriptorlength = 0; ape->headerlength = 32; ape->compressiontype = avio_rl16(pb); ape->formatflags = avio_rl16(pb); ape->channels = avio_rl16(pb); ape->samplerate = avio_rl32(pb); ape->wavheaderlength = avio_rl32(pb); ape->wavtaillength = avio_rl32(pb); ape->totalframes = avio_rl32(pb); ape->finalframeblocks = avio_rl32(pb); if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) { avio_skip(pb, 4); /* Skip the peak level */ ape->headerlength += 4; } if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) { ape->seektablelength = avio_rl32(pb); ape->headerlength += 4; ape->seektablelength *= sizeof(int32_t); } else ape->seektablelength = ape->totalframes * sizeof(int32_t); if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT) ape->bps = 8; else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT) ape->bps = 24; else ape->bps = 16; if (ape->fileversion >= 3950) ape->blocksperframe = 73728 * 4; else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800 && ape->compressiontype >= 4000)) ape->blocksperframe = 73728; else ape->blocksperframe = 9216; /* Skip any stored wav header */ if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER)) avio_skip(pb, ape->wavheaderlength); } if(!ape->totalframes){ av_log(s, AV_LOG_ERROR, "No frames in the file!\n"); return AVERROR(EINVAL); } if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){ av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n", ape->totalframes); return AVERROR_INVALIDDATA; } if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) { av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n", ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); return AVERROR_INVALIDDATA; } ape->frames = av_malloc(ape->totalframes * sizeof(APEFrame)); if(!ape->frames) return AVERROR(ENOMEM); ape->firstframe = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength; ape->currentframe = 0; ape->totalsamples = ape->finalframeblocks; if (ape->totalframes > 1) ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1); if (ape->seektablelength > 0) { ape->seektable = av_malloc(ape->seektablelength); if (!ape->seektable) return AVERROR(ENOMEM); for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) ape->seektable[i] = avio_rl32(pb); }else{ av_log(s, AV_LOG_ERROR, "Missing seektable\n"); return AVERROR_INVALIDDATA; } ape->frames[0].pos = ape->firstframe; ape->frames[0].nblocks = ape->blocksperframe; ape->frames[0].skip = 0; for (i = 1; i < ape->totalframes; i++) { ape->frames[i].pos = ape->seektable[i] + ape->junklength; ape->frames[i].nblocks = ape->blocksperframe; ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; } ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; /* calculate final packet size from total file size, if available */ file_size = avio_size(pb); if (file_size > 0) { final_size = file_size - ape->frames[ape->totalframes - 1].pos - ape->wavtaillength; final_size -= final_size & 3; } if (file_size <= 0 || final_size <= 0) final_size = ape->finalframeblocks * 8; ape->frames[ape->totalframes - 1].size = final_size; for (i = 0; i < ape->totalframes; i++) { if(ape->frames[i].skip){ ape->frames[i].pos -= ape->frames[i].skip; ape->frames[i].size += ape->frames[i].skip; } ape->frames[i].size = (ape->frames[i].size + 3) & ~3; } ape_dumpinfo(s, ape); av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %"PRIu16"\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10, ape->compressiontype); /* now we are ready: build format streams */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_APE; st->codec->codec_tag = MKTAG('A', 'P', 'E', ' '); st->codec->channels = ape->channels; st->codec->sample_rate = ape->samplerate; st->codec->bits_per_coded_sample = ape->bps; st->nb_frames = ape->totalframes; st->start_time = 0; st->duration = total_blocks; avpriv_set_pts_info(st, 64, 1, ape->samplerate); st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE); st->codec->extradata_size = APE_EXTRADATA_SIZE; AV_WL16(st->codec->extradata + 0, ape->fileversion); AV_WL16(st->codec->extradata + 2, ape->compressiontype); AV_WL16(st->codec->extradata + 4, ape->formatflags); pts = 0; for (i = 0; i < ape->totalframes; i++) { ape->frames[i].pts = pts; av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME); pts += ape->blocksperframe; } /* try to read APE tags */ if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, 0, SEEK_SET); } return 0; }
static int roq_read_packet(AVFormatContext *s, AVPacket *pkt) { RoqDemuxContext *roq = s->priv_data; AVIOContext *pb = s->pb; int ret = 0; unsigned int chunk_size; unsigned int chunk_type; unsigned int codebook_size; unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; int packet_read = 0; int64_t codebook_offset; while (!packet_read) { if (avio_feof(s->pb)) return AVERROR(EIO); /* get the next chunk preamble */ if ((ret = avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE)) != RoQ_CHUNK_PREAMBLE_SIZE) return AVERROR(EIO); chunk_type = AV_RL16(&preamble[0]); chunk_size = AV_RL32(&preamble[2]); if(chunk_size > INT_MAX) return AVERROR_INVALIDDATA; chunk_size = ffio_limit(pb, chunk_size); switch (chunk_type) { case RoQ_INFO: if (roq->video_stream_index == -1) { AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 63, 1, roq->frame_rate); roq->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_ROQ; st->codec->codec_tag = 0; /* no fourcc */ if (avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) return AVERROR(EIO); st->codec->width = roq->width = AV_RL16(preamble); st->codec->height = roq->height = AV_RL16(preamble + 2); break; } /* don't care about this chunk anymore */ avio_skip(pb, RoQ_CHUNK_PREAMBLE_SIZE); break; case RoQ_QUAD_CODEBOOK: if (roq->video_stream_index < 0) return AVERROR_INVALIDDATA; /* packet needs to contain both this codebook and next VQ chunk */ codebook_offset = avio_tell(pb) - RoQ_CHUNK_PREAMBLE_SIZE; codebook_size = chunk_size; avio_skip(pb, codebook_size); if (avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) return AVERROR(EIO); chunk_size = AV_RL32(&preamble[2]) + RoQ_CHUNK_PREAMBLE_SIZE * 2 + codebook_size; /* rewind */ avio_seek(pb, codebook_offset, SEEK_SET); /* load up the packet */ ret= av_get_packet(pb, pkt, chunk_size); if (ret != chunk_size) return AVERROR(EIO); pkt->stream_index = roq->video_stream_index; pkt->pts = roq->video_pts++; packet_read = 1; break; case RoQ_SOUND_MONO: case RoQ_SOUND_STEREO: if (roq->audio_stream_index == -1) { AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 32, 1, RoQ_AUDIO_SAMPLE_RATE); roq->audio_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_ROQ_DPCM; st->codec->codec_tag = 0; /* no tag */ if (chunk_type == RoQ_SOUND_STEREO) { st->codec->channels = 2; st->codec->channel_layout = AV_CH_LAYOUT_STEREO; } else { st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; } roq->audio_channels = st->codec->channels; st->codec->sample_rate = RoQ_AUDIO_SAMPLE_RATE; st->codec->bits_per_coded_sample = 16; 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; } case RoQ_QUAD_VQ: if (chunk_type == RoQ_QUAD_VQ) { if (roq->video_stream_index < 0) return AVERROR_INVALIDDATA; } /* load up the packet */ if (av_new_packet(pkt, chunk_size + RoQ_CHUNK_PREAMBLE_SIZE)) return AVERROR(EIO); /* copy over preamble */ memcpy(pkt->data, preamble, RoQ_CHUNK_PREAMBLE_SIZE); if (chunk_type == RoQ_QUAD_VQ) { pkt->stream_index = roq->video_stream_index; pkt->pts = roq->video_pts++; } else { pkt->stream_index = roq->audio_stream_index; pkt->pts = roq->audio_frame_count; roq->audio_frame_count += (chunk_size / roq->audio_channels); } pkt->pos= avio_tell(pb); ret = avio_read(pb, pkt->data + RoQ_CHUNK_PREAMBLE_SIZE, chunk_size); if (ret != chunk_size) ret = AVERROR(EIO); packet_read = 1; break; default: av_log(s, AV_LOG_ERROR, " unknown RoQ chunk (%04X)\n", chunk_type); return AVERROR_INVALIDDATA; } } return ret; }
static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) { EaDemuxContext *ea = s->priv_data; AVIOContext *pb = s->pb; int ret = 0; int packet_read = 0; unsigned int chunk_type, chunk_size; int key = 0; int num_samples = 0; while (!packet_read) { chunk_type = avio_rl32(pb); chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8; switch (chunk_type) { /* audio data */ case ISNh_TAG: /* header chunk also contains data; skip over the header portion*/ avio_skip(pb, 32); chunk_size -= 32; case ISNd_TAG: case SCDl_TAG: case SNDC_TAG: case SDEN_TAG: if (!ea->audio_codec) { avio_skip(pb, chunk_size); break; } else if (ea->audio_codec == CODEC_ID_PCM_S16LE_PLANAR || ea->audio_codec == CODEC_ID_MP3) { num_samples = avio_rl32(pb); avio_skip(pb, 8); chunk_size -= 12; } ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; if (ea->audio_codec == CODEC_ID_ADPCM_EA_R1 || ea->audio_codec == CODEC_ID_ADPCM_EA_R2 || ea->audio_codec == CODEC_ID_ADPCM_EA_R3) { num_samples = ea->audio_codec == CODEC_ID_ADPCM_EA_R3 ? AV_RB32(pkt->data) : AV_RL32(pkt->data); } pkt->stream_index = ea->audio_stream_index; pkt->pts = ea->audio_frame_counter; switch (ea->audio_codec) { case CODEC_ID_ADPCM_EA: /* 2 samples/byte, 1 or 2 samples per frame depending * on stereo; chunk also has 12-byte header */ ea->audio_frame_counter += ((chunk_size - 12) * 2) / ea->num_channels; break; default: if (num_samples > 0) ea->audio_frame_counter += num_samples; else ea->audio_frame_counter += chunk_size / (ea->bytes * ea->num_channels); } packet_read = 1; break; /* ending tag */ case 0: case ISNe_TAG: case SCEl_TAG: case SEND_TAG: case SEEN_TAG: ret = AVERROR(EIO); packet_read = 1; break; case MVIh_TAG: case kVGT_TAG: case pQGT_TAG: case TGQs_TAG: case MADk_TAG: key = AV_PKT_FLAG_KEY; case MVIf_TAG: case fVGT_TAG: case MADm_TAG: case MADe_TAG: avio_seek(pb, -8, SEEK_CUR); // include chunk preamble chunk_size += 8; goto get_video_packet; case mTCD_TAG: avio_skip(pb, 8); // skip ea dct header chunk_size -= 8; goto get_video_packet; case MV0K_TAG: case MPCh_TAG: case pIQT_TAG: key = AV_PKT_FLAG_KEY; case MV0F_TAG: get_video_packet: ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; pkt->stream_index = ea->video_stream_index; pkt->flags |= key; packet_read = 1; break; default: avio_skip(pb, chunk_size); break; } } return ret; }
/* * 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; AVIOContext *pb = s->pb; int i; for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) { unsigned int startpos = avio_tell(pb); int err = 0; blockid = avio_rl32(pb); size = avio_rl32(pb); if (i == 0) ea->big_endian = size > 0x000FFFFF; if (ea->big_endian) size = av_bswap32(size); switch (blockid) { case ISNh_TAG: if (avio_rl32(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 : case SHEN_TAG : blockid = avio_rl32(pb); if (blockid == GSTR_TAG) { avio_skip(pb, 4); } else if ((blockid & 0xFFFF)!=PT00_TAG) { av_log (s, AV_LOG_ERROR, "unknown SCHl headerid\n"); return 0; } err = process_audio_header_elements(s); break; case SEAD_TAG: err = process_audio_header_sead(s); break; case MVIh_TAG : ea->video_codec = CODEC_ID_CMV; break; case kVGT_TAG: ea->video_codec = CODEC_ID_TGV; break; case mTCD_TAG : err = process_video_header_mdec(s); break; case MPCh_TAG: ea->video_codec = CODEC_ID_MPEG2VIDEO; break; case pQGT_TAG: case TGQs_TAG: ea->video_codec = CODEC_ID_TGQ; break; case pIQT_TAG: ea->video_codec = CODEC_ID_TQI; break; case MADk_TAG : ea->video_codec = CODEC_ID_MAD; 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; } avio_seek(pb, startpos + size, SEEK_SET); } avio_seek(pb, 0, SEEK_SET); return 1; }
static int read_header(AVFormatContext *s) { IcoDemuxContext *ico = s->priv_data; AVIOContext *pb = s->pb; int i, codec; avio_skip(pb, 4); ico->nb_images = avio_rl16(pb); ico->images = av_malloc(ico->nb_images * sizeof(IcoImage)); if (!ico->images) return AVERROR(ENOMEM); for (i = 0; i < ico->nb_images; i++) { AVStream *st; int tmp; if (avio_seek(pb, 6 + i * 16, SEEK_SET) < 0) break; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->width = avio_r8(pb); st->codec->height = avio_r8(pb); ico->images[i].nb_pal = avio_r8(pb); if (ico->images[i].nb_pal == 255) ico->images[i].nb_pal = 0; avio_skip(pb, 5); ico->images[i].size = avio_rl32(pb); ico->images[i].offset = avio_rl32(pb); if (avio_seek(pb, ico->images[i].offset, SEEK_SET) < 0) break; codec = avio_rl32(pb); switch (codec) { case MKTAG(0x89, 'P', 'N', 'G'): st->codec->codec_id = AV_CODEC_ID_PNG; st->codec->width = 0; st->codec->height = 0; break; case 40: if (ico->images[i].size < 40) return AVERROR_INVALIDDATA; st->codec->codec_id = AV_CODEC_ID_BMP; tmp = avio_rl32(pb); if (tmp) st->codec->width = tmp; tmp = avio_rl32(pb); if (tmp) st->codec->height = tmp / 2; break; default: avpriv_request_sample(s, "codec %d", codec); return AVERROR_INVALIDDATA; } } return 0; }
int ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) { VocDecContext *voc = s->priv_data; AVCodecParameters *par = st->codecpar; AVIOContext *pb = s->pb; VocType type; int size, tmp_codec=-1; int sample_rate = 0; int channels = 1; int64_t duration; int ret; av_add_index_entry(st, avio_tell(pb), voc->pts, voc->remaining_size, 0, AVINDEX_KEYFRAME); while (!voc->remaining_size) { type = avio_r8(pb); if (type == VOC_TYPE_EOF) return AVERROR_EOF; voc->remaining_size = avio_rl24(pb); if (!voc->remaining_size) { if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) return AVERROR(EIO); voc->remaining_size = avio_size(pb) - avio_tell(pb); } max_size -= 4; switch (type) { case VOC_TYPE_VOICE_DATA: if (!par->sample_rate) { par->sample_rate = 1000000 / (256 - avio_r8(pb)); if (sample_rate) par->sample_rate = sample_rate; avpriv_set_pts_info(st, 64, 1, par->sample_rate); par->channels = channels; par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id); } else avio_skip(pb, 1); tmp_codec = avio_r8(pb); voc->remaining_size -= 2; max_size -= 2; channels = 1; break; case VOC_TYPE_VOICE_DATA_CONT: break; case VOC_TYPE_EXTENDED: sample_rate = avio_rl16(pb); avio_r8(pb); channels = avio_r8(pb) + 1; sample_rate = 256000000 / (channels * (65536 - sample_rate)); voc->remaining_size = 0; max_size -= 4; break; case VOC_TYPE_NEW_VOICE_DATA: if (!par->sample_rate) { par->sample_rate = avio_rl32(pb); avpriv_set_pts_info(st, 64, 1, par->sample_rate); par->bits_per_coded_sample = avio_r8(pb); par->channels = avio_r8(pb); } else avio_skip(pb, 6); tmp_codec = avio_rl16(pb); avio_skip(pb, 4); voc->remaining_size -= 12; max_size -= 12; break; default: avio_skip(pb, voc->remaining_size); max_size -= voc->remaining_size; voc->remaining_size = 0; break; } } if (par->sample_rate <= 0) { av_log(s, AV_LOG_ERROR, "Invalid sample rate %d\n", par->sample_rate); return AVERROR_INVALIDDATA; } if (tmp_codec >= 0) { tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec); if (par->codec_id == AV_CODEC_ID_NONE) par->codec_id = tmp_codec; else if (par->codec_id != tmp_codec) av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n"); if (par->codec_id == AV_CODEC_ID_NONE) { if (s->audio_codec_id == AV_CODEC_ID_NONE) { av_log(s, AV_LOG_ERROR, "unknown codec tag\n"); return AVERROR(EINVAL); } av_log(s, AV_LOG_WARNING, "unknown codec tag\n"); } } par->bit_rate = (int64_t)par->sample_rate * par->channels * par->bits_per_coded_sample; if (max_size <= 0) max_size = 2048; size = FFMIN(voc->remaining_size, max_size); voc->remaining_size -= size; ret = av_get_packet(pb, pkt, size); pkt->dts = pkt->pts = voc->pts; duration = av_get_audio_frame_duration2(st->codecpar, size); if (duration > 0 && voc->pts != AV_NOPTS_VALUE) voc->pts += duration; else voc->pts = AV_NOPTS_VALUE; return ret; }
int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; enum IEC61937DataType data_type; enum AVCodecID codec_id; uint32_t state = 0; int pkt_size_bits, offset, ret; while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) { state = (state << 8) | avio_r8(pb); if (avio_feof(pb)) return AVERROR_EOF; } data_type = avio_rl16(pb); pkt_size_bits = avio_rl16(pb); if (pkt_size_bits % 16) avpriv_request_sample(s, "Packet not ending at a 16-bit boundary"); ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3); if (ret) return ret; pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE; if (avio_read(pb, pkt->data, pkt->size) < pkt->size) { av_free_packet(pkt); return AVERROR_EOF; } ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); ret = spdif_get_offset_and_codec(s, data_type, pkt->data, &offset, &codec_id); if (ret) { av_free_packet(pkt); return ret; } /* skip over the padding to the beginning of the next frame */ avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE); if (!s->nb_streams) { /* first packet, create a stream */ AVStream *st = avformat_new_stream(s, NULL); if (!st) { av_free_packet(pkt); return AVERROR(ENOMEM); } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = codec_id; } else if (codec_id != s->streams[0]->codec->codec_id) { avpriv_report_missing_feature(s, "Codec change in IEC 61937"); return AVERROR_PATCHWELCOME; } if (!s->bit_rate && s->streams[0]->codec->sample_rate) /* stream bitrate matches 16-bit stereo PCM bitrate for currently supported codecs */ s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate; return 0; }
static int 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 (url_feof(pb)) 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 flv_write_header(AVFormatContext *s) { AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; AVCodecContext *audio_enc = NULL, *video_enc = NULL, *data_enc = NULL; int i, metadata_count = 0; double framerate = 0.0; int64_t metadata_size_pos, data_size, metadata_count_pos; AVDictionaryEntry *tag = NULL; for (i = 0; i < s->nb_streams; i++) { AVCodecContext *enc = s->streams[i]->codec; FLVStreamContext *sc; switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: if (s->streams[i]->avg_frame_rate.den && s->streams[i]->avg_frame_rate.num) { framerate = av_q2d(s->streams[i]->avg_frame_rate); } else { framerate = 1 / av_q2d(s->streams[i]->codec->time_base); } video_enc = enc; if (enc->codec_tag == 0) { av_log(s, AV_LOG_ERROR, "Video codec '%s' for stream %d is not compatible with FLV\n", avcodec_get_name(enc->codec_id), i); return AVERROR(EINVAL); } break; case AVMEDIA_TYPE_AUDIO: audio_enc = enc; if (get_audio_flags(s, enc) < 0) return AVERROR_INVALIDDATA; break; case AVMEDIA_TYPE_DATA: if (enc->codec_id != AV_CODEC_ID_TEXT) { av_log(s, AV_LOG_ERROR, "Data codec '%s' for stream %d is not compatible with FLV\n", avcodec_get_name(enc->codec_id), i); return AVERROR_INVALIDDATA; } data_enc = enc; break; default: av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n", av_get_media_type_string(enc->codec_type), i); return AVERROR(EINVAL); } avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ sc = av_mallocz(sizeof(FLVStreamContext)); if (!sc) return AVERROR(ENOMEM); s->streams[i]->priv_data = sc; sc->last_ts = -1; } flv->delay = AV_NOPTS_VALUE; avio_write(pb, "FLV", 3); avio_w8(pb, 1); avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc + FLV_HEADER_FLAG_HASVIDEO * !!video_enc); avio_wb32(pb, 9); avio_wb32(pb, 0); for (i = 0; i < s->nb_streams; i++) if (s->streams[i]->codec->codec_tag == 5) { avio_w8(pb, 8); // message type avio_wb24(pb, 0); // include flags avio_wb24(pb, 0); // time stamp avio_wb32(pb, 0); // reserved avio_wb32(pb, 11); // size flv->reserved = 5; } /* write meta_tag */ avio_w8(pb, 18); // tag type META metadata_size_pos = avio_tell(pb); avio_wb24(pb, 0); // size of data part (sum of all parts below) avio_wb24(pb, 0); // timestamp avio_wb32(pb, 0); // reserved /* now data of data_size size */ /* first event name as a string */ avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, "onMetaData"); // 12 bytes /* mixed array (hash) with size and string/type/data tuples */ avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); metadata_count_pos = avio_tell(pb); metadata_count = 5 * !!video_enc + 5 * !!audio_enc + 1 * !!data_enc + 2; // +2 for duration and file size avio_wb32(pb, metadata_count); put_amf_string(pb, "duration"); flv->duration_offset= avio_tell(pb); // fill in the guessed duration, it'll be corrected later if incorrect put_amf_double(pb, s->duration / AV_TIME_BASE); if (video_enc) { put_amf_string(pb, "width"); put_amf_double(pb, video_enc->width); put_amf_string(pb, "height"); put_amf_double(pb, video_enc->height); put_amf_string(pb, "videodatarate"); put_amf_double(pb, video_enc->bit_rate / 1024.0); put_amf_string(pb, "framerate"); put_amf_double(pb, framerate); put_amf_string(pb, "videocodecid"); put_amf_double(pb, video_enc->codec_tag); } if (audio_enc) { put_amf_string(pb, "audiodatarate"); put_amf_double(pb, audio_enc->bit_rate / 1024.0); put_amf_string(pb, "audiosamplerate"); put_amf_double(pb, audio_enc->sample_rate); put_amf_string(pb, "audiosamplesize"); put_amf_double(pb, audio_enc->codec_id == AV_CODEC_ID_PCM_U8 ? 8 : 16); put_amf_string(pb, "stereo"); put_amf_bool(pb, audio_enc->channels == 2); put_amf_string(pb, "audiocodecid"); put_amf_double(pb, audio_enc->codec_tag); } if (data_enc) { put_amf_string(pb, "datastream"); put_amf_double(pb, 0.0); } while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { if( !strcmp(tag->key, "width") ||!strcmp(tag->key, "height") ||!strcmp(tag->key, "videodatarate") ||!strcmp(tag->key, "framerate") ||!strcmp(tag->key, "videocodecid") ||!strcmp(tag->key, "audiodatarate") ||!strcmp(tag->key, "audiosamplerate") ||!strcmp(tag->key, "audiosamplesize") ||!strcmp(tag->key, "stereo") ||!strcmp(tag->key, "audiocodecid") ||!strcmp(tag->key, "duration") ||!strcmp(tag->key, "onMetaData") ){ av_log(s, AV_LOG_DEBUG, "Ignoring metadata for %s\n", tag->key); continue; } put_amf_string(pb, tag->key); avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, tag->value); metadata_count++; } put_amf_string(pb, "filesize"); flv->filesize_offset = avio_tell(pb); put_amf_double(pb, 0); // delayed write put_amf_string(pb, ""); avio_w8(pb, AMF_END_OF_OBJECT); /* write total size of tag */ data_size = avio_tell(pb) - metadata_size_pos - 10; avio_seek(pb, metadata_count_pos, SEEK_SET); avio_wb32(pb, metadata_count); avio_seek(pb, metadata_size_pos, SEEK_SET); avio_wb24(pb, data_size); avio_skip(pb, data_size + 10 - 3); avio_wb32(pb, data_size + 11); for (i = 0; i < s->nb_streams; i++) { AVCodecContext *enc = s->streams[i]->codec; if (enc->codec_id == AV_CODEC_ID_AAC || enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { int64_t pos; avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ? FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); avio_wb24(pb, 0); // size patched later avio_wb24(pb, 0); // ts avio_w8(pb, 0); // ts ext avio_wb24(pb, 0); // streamid pos = avio_tell(pb); if (enc->codec_id == AV_CODEC_ID_AAC) { avio_w8(pb, get_audio_flags(s, enc)); avio_w8(pb, 0); // AAC sequence header avio_write(pb, enc->extradata, enc->extradata_size); } else { avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags avio_w8(pb, 0); // AVC sequence header avio_wb24(pb, 0); // composition time ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); } data_size = avio_tell(pb) - pos; avio_seek(pb, -data_size - 10, SEEK_CUR); avio_wb24(pb, data_size); avio_skip(pb, data_size + 10 - 3); avio_wb32(pb, data_size + 11); // previous tag size } } 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; AVStream *st; 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 (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) { av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8); return AVERROR_INVALIDDATA; } if (fourcc_tag == std__TAG) { fourxm->fps = av_int2float(AV_RL32(&header[i + 12])); } else if (fourcc_tag == vtrk_TAG) { /* check that there is enough data */ if (size != vtrk_SIZE) { ret= AVERROR_INVALIDDATA; goto fail; } fourxm->width = AV_RL32(&header[i + 36]); fourxm->height = AV_RL32(&header[i + 40]); /* allocate a new AVStream */ st = avformat_new_stream(s, NULL); if (!st){ ret= AVERROR(ENOMEM); goto fail; } avpriv_set_pts_info(st, 60, 1, fourxm->fps); fourxm->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_4XM; st->codec->extradata_size = 4; st->codec->extradata = av_malloc(4); AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16])); st->codec->width = fourxm->width; st->codec->height = fourxm->height; i += 8 + size; } else if (fourcc_tag == strk_TAG) { int current_track; /* check that there is enough data */ if (size != strk_SIZE) { ret= AVERROR_INVALIDDATA; goto fail; } current_track = AV_RL32(&header[i + 8]); if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){ av_log(s, AV_LOG_ERROR, "current_track too large\n"); ret = AVERROR_INVALIDDATA; goto fail; } if (current_track + 1 > fourxm->track_count) { fourxm->tracks = av_realloc_f(fourxm->tracks, sizeof(AudioTrack), current_track + 1); if (!fourxm->tracks) { ret = AVERROR(ENOMEM); goto fail; } memset(&fourxm->tracks[fourxm->track_count], 0, sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count)); fourxm->track_count = current_track + 1; } fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]); fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]); fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]); fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]); fourxm->tracks[current_track].audio_pts = 0; if( fourxm->tracks[current_track].channels <= 0 || fourxm->tracks[current_track].sample_rate <= 0 || fourxm->tracks[current_track].bits < 0){ av_log(s, AV_LOG_ERROR, "audio header invalid\n"); ret = AVERROR_INVALIDDATA; goto fail; } if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){ av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n"); ret = AVERROR_INVALIDDATA; goto fail; } i += 8 + size; /* allocate a new AVStream */ st = avformat_new_stream(s, NULL); if (!st){ ret= AVERROR(ENOMEM); goto fail; } st->id = current_track; avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate); fourxm->tracks[current_track].stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = 0; st->codec->channels = fourxm->tracks[current_track].channels; st->codec->sample_rate = fourxm->tracks[current_track].sample_rate; st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits; 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; if (fourxm->tracks[current_track].adpcm){ st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM; }else if (st->codec->bits_per_coded_sample == 8){ st->codec->codec_id = AV_CODEC_ID_PCM_U8; }else st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; } } /* 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 smjpeg_read_header(AVFormatContext *s) { SMJPEGContext *sc = s->priv_data; AVStream *ast = NULL, *vst = NULL; AVIOContext *pb = s->pb; uint32_t version, htype, hlength, duration; char *comment; avio_skip(pb, 8); // magic version = avio_rb32(pb); if (version) av_log_ask_for_sample(s, "unknown version %d\n", version); duration = avio_rb32(pb); // in msec while (!url_feof(pb)) { htype = avio_rl32(pb); switch (htype) { case SMJPEG_TXT: hlength = avio_rb32(pb); if (!hlength || hlength > 512) return AVERROR_INVALIDDATA; comment = av_malloc(hlength + 1); if (!comment) return AVERROR(ENOMEM); if (avio_read(pb, comment, hlength) != hlength) { av_freep(&comment); av_log(s, AV_LOG_ERROR, "error when reading comment\n"); return AVERROR_INVALIDDATA; } comment[hlength] = 0; av_dict_set(&s->metadata, "comment", comment, AV_DICT_DONT_STRDUP_VAL); break; case SMJPEG_SND: if (ast) { av_log_ask_for_sample(s, "multiple audio streams not supported\n"); return AVERROR_INVALIDDATA; } hlength = avio_rb32(pb); if (hlength < 8) return AVERROR_INVALIDDATA; ast = avformat_new_stream(s, 0); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->sample_rate = avio_rb16(pb); ast->codec->bits_per_coded_sample = avio_r8(pb); ast->codec->channels = avio_r8(pb); ast->codec->codec_tag = avio_rl32(pb); ast->codec->codec_id = ff_codec_get_id(ff_codec_smjpeg_audio_tags, ast->codec->codec_tag); ast->duration = duration; sc->audio_stream_index = ast->index; avpriv_set_pts_info(ast, 32, 1, 1000); avio_skip(pb, hlength - 8); break; case SMJPEG_VID: if (vst) { av_log_ask_for_sample(s, "multiple video streams not supported\n"); return AVERROR_INVALIDDATA; } hlength = avio_rb32(pb); if (hlength < 12) return AVERROR_INVALIDDATA; vst = avformat_new_stream(s, 0); if (!vst) return AVERROR(ENOMEM); vst->nb_frames = avio_rb32(pb); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->width = avio_rb16(pb); vst->codec->height = avio_rb16(pb); vst->codec->codec_tag = avio_rl32(pb); vst->codec->codec_id = ff_codec_get_id(ff_codec_smjpeg_video_tags, vst->codec->codec_tag); vst->duration = duration; sc->video_stream_index = vst->index; avpriv_set_pts_info(vst, 32, 1, 1000); avio_skip(pb, hlength - 12); break; case SMJPEG_HEND: return 0; default: av_log(s, AV_LOG_ERROR, "unknown header %x\n", htype); return AVERROR_INVALIDDATA; } } return AVERROR_EOF; }
/* 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(s->avf, AV_LOG_TRACE, "chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size); switch (chunk_type) { case CHUNK_INIT_AUDIO: av_log(s->avf, AV_LOG_TRACE, "initialize audio\n"); break; case CHUNK_AUDIO_ONLY: av_log(s->avf, AV_LOG_TRACE, "audio only\n"); break; case CHUNK_INIT_VIDEO: av_log(s->avf, AV_LOG_TRACE, "initialize video\n"); break; case CHUNK_VIDEO: av_log(s->avf, AV_LOG_TRACE, "video (and audio)\n"); break; case CHUNK_SHUTDOWN: av_log(s->avf, AV_LOG_TRACE, "shutdown\n"); break; case CHUNK_END: av_log(s->avf, AV_LOG_TRACE, "end\n"); break; default: av_log(s->avf, 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(s->avf, AV_LOG_TRACE, "chunk_size countdown just went negative\n"); chunk_type = CHUNK_BAD; break; } av_log(s->avf, 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(s->avf, AV_LOG_TRACE, "end of stream\n"); avio_skip(pb, opcode_size); break; case OPCODE_END_OF_CHUNK: av_log(s->avf, AV_LOG_TRACE, "end of chunk\n"); avio_skip(pb, opcode_size); break; case OPCODE_CREATE_TIMER: av_log(s->avf, AV_LOG_TRACE, "create timer\n"); if ((opcode_version > 0) || (opcode_size != 6)) { av_log(s->avf, 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(s->avf, 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(s->avf, AV_LOG_TRACE, "initialize audio buffers\n"); if (opcode_version > 1 || opcode_size > 10 || opcode_size < 6) { av_log(s->avf, 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(s->avf, 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(s->avf, AV_LOG_TRACE, "start/stop audio\n"); avio_skip(pb, opcode_size); break; case OPCODE_INIT_VIDEO_BUFFERS: av_log(s->avf, 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(s->avf, 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(s->avf, 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(s->avf, AV_LOG_TRACE, "unknown (but documented) opcode %02X\n", opcode_type); avio_skip(pb, opcode_size); break; case OPCODE_SEND_BUFFER: av_log(s->avf, AV_LOG_TRACE, "send buffer\n"); avio_skip(pb, opcode_size); break; case OPCODE_AUDIO_FRAME: av_log(s->avf, 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(s->avf, AV_LOG_TRACE, "silence frame\n"); avio_skip(pb, opcode_size); break; case OPCODE_INIT_VIDEO_MODE: av_log(s->avf, AV_LOG_TRACE, "initialize video mode\n"); avio_skip(pb, opcode_size); break; case OPCODE_CREATE_GRADIENT: av_log(s->avf, AV_LOG_TRACE, "create gradient\n"); avio_skip(pb, opcode_size); break; case OPCODE_SET_PALETTE: av_log(s->avf, 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(s->avf, 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(s->avf, 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(s->avf, AV_LOG_TRACE, "set palette compressed\n"); avio_skip(pb, opcode_size); break; case OPCODE_SET_DECODING_MAP: av_log(s->avf, 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(s->avf, 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(s->avf, 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 wsvqa_read_packet(AVFormatContext *s, AVPacket *pkt) { WsVqaDemuxContext *wsvqa = s->priv_data; AVIOContext *pb = s->pb; int ret = -1; uint8_t preamble[VQA_PREAMBLE_SIZE]; uint32_t chunk_type; uint32_t chunk_size; int skip_byte; while (avio_read(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) { chunk_type = AV_RB32(&preamble[0]); chunk_size = AV_RB32(&preamble[4]); skip_byte = chunk_size & 0x01; if ((chunk_type == SND0_TAG) || (chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) { ret= av_get_packet(pb, pkt, chunk_size); if (ret<0) return AVERROR(EIO); switch (chunk_type) { case SND0_TAG: case SND1_TAG: case SND2_TAG: if (wsvqa->audio_stream_index == -1) { AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); wsvqa->audio_stream_index = st->index; if (!wsvqa->sample_rate) wsvqa->sample_rate = 22050; if (!wsvqa->channels) wsvqa->channels = 1; if (!wsvqa->bps) wsvqa->bps = 8; st->codecpar->sample_rate = wsvqa->sample_rate; st->codecpar->bits_per_coded_sample = wsvqa->bps; st->codecpar->channels = wsvqa->channels; st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); switch (chunk_type) { case SND0_TAG: if (wsvqa->bps == 16) st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; else st->codecpar->codec_id = AV_CODEC_ID_PCM_U8; break; case SND1_TAG: st->codecpar->codec_id = AV_CODEC_ID_WESTWOOD_SND1; break; case SND2_TAG: st->codecpar->codec_id = AV_CODEC_ID_ADPCM_IMA_WS; if (ff_alloc_extradata(st->codecpar, 2)) return AVERROR(ENOMEM); AV_WL16(st->codecpar->extradata, wsvqa->version); break; } } pkt->stream_index = wsvqa->audio_stream_index; switch (chunk_type) { case SND1_TAG: /* unpacked size is stored in header */ if(pkt->data) pkt->duration = AV_RL16(pkt->data) / wsvqa->channels; break; case SND2_TAG: /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ pkt->duration = (chunk_size * 2) / wsvqa->channels; break; } break; case VQFR_TAG: pkt->stream_index = wsvqa->video_stream_index; pkt->duration = 1; break; } /* stay on 16-bit alignment */ if (skip_byte) avio_skip(pb, 1); return ret; } else { switch(chunk_type){ case CMDS_TAG: break; default: av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type); } avio_skip(pb, chunk_size + skip_byte); } } return ret; }
static int nuv_header(AVFormatContext *s) { NUVContext *ctx = s->priv_data; AVIOContext *pb = s->pb; char id_string[12]; double aspect, fps; int is_mythtv, width, height, v_packs, a_packs, ret; AVStream *vst = NULL, *ast = NULL; avio_read(pb, id_string, 12); is_mythtv = !memcmp(id_string, "MythTVVideo", 12); avio_skip(pb, 5); // version string avio_skip(pb, 3); // padding width = avio_rl32(pb); height = avio_rl32(pb); avio_rl32(pb); // unused, "desiredwidth" avio_rl32(pb); // unused, "desiredheight" avio_r8(pb); // 'P' == progressive, 'I' == interlaced avio_skip(pb, 3); // padding aspect = av_int2double(avio_rl64(pb)); if (aspect > 0.9999 && aspect < 1.0001) aspect = 4.0 / 3.0; fps = av_int2double(avio_rl64(pb)); // number of packets per stream type, -1 means unknown, e.g. streaming v_packs = avio_rl32(pb); a_packs = avio_rl32(pb); avio_rl32(pb); // text avio_rl32(pb); // keyframe distance (?) if (v_packs) { vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); ctx->v_id = vst->index; vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_NUV; vst->codec->width = width; vst->codec->height = height; vst->codec->bits_per_coded_sample = 10; vst->sample_aspect_ratio = av_d2q(aspect * height / width, 10000); #if FF_API_R_FRAME_RATE vst->r_frame_rate = #endif vst->avg_frame_rate = av_d2q(fps, 60000); avpriv_set_pts_info(vst, 32, 1, 1000); } else ctx->v_id = -1; if (a_packs) { ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ctx->a_id = ast->index; ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = AV_CODEC_ID_PCM_S16LE; ast->codec->channels = 2; ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; ast->codec->sample_rate = 44100; ast->codec->bit_rate = 2 * 2 * 44100 * 8; ast->codec->block_align = 2 * 2; ast->codec->bits_per_coded_sample = 16; avpriv_set_pts_info(ast, 32, 1, 1000); } else ctx->a_id = -1; if ((ret = get_codec_data(pb, vst, ast, is_mythtv)) < 0) return ret; ctx->rtjpg_video = vst && vst->codec->codec_id == AV_CODEC_ID_NUV; return 0; }
static int read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; C93DemuxContext *c93 = s->priv_data; C93BlockRecord *br = &c93->block_records[c93->current_block]; int datasize; int ret, i; if (c93->next_pkt_is_audio) { c93->current_frame++; c93->next_pkt_is_audio = 0; datasize = avio_rl16(pb); if (datasize > 42) { if (!c93->audio) { c93->audio = avformat_new_stream(s, NULL); if (!c93->audio) return AVERROR(ENOMEM); c93->audio->codec->codec_type = AVMEDIA_TYPE_AUDIO; } avio_skip(pb, 26); /* VOC header */ ret = voc_get_packet(s, pkt, c93->audio, datasize - 26); if (ret > 0) { pkt->stream_index = 1; pkt->flags |= AV_PKT_FLAG_KEY; return ret; } } } if (c93->current_frame >= br->frames) { if (c93->current_block >= 511 || !br[1].length) return AVERROR(EIO); br++; c93->current_block++; c93->current_frame = 0; } if (c93->current_frame == 0) { avio_seek(pb, br->index * 2048, SEEK_SET); for (i = 0; i < 32; i++) { c93->frame_offsets[i] = avio_rl32(pb); } } avio_seek(pb,br->index * 2048 + c93->frame_offsets[c93->current_frame], SEEK_SET); datasize = avio_rl16(pb); /* video frame size */ ret = av_new_packet(pkt, datasize + 768 + 1); if (ret < 0) return ret; pkt->data[0] = 0; pkt->size = datasize + 1; ret = avio_read(pb, pkt->data + 1, datasize); if (ret < datasize) { ret = AVERROR(EIO); goto fail; } datasize = avio_rl16(pb); /* palette size */ if (datasize) { if (datasize != 768) { av_log(s, AV_LOG_ERROR, "invalid palette size %u\n", datasize); ret = AVERROR_INVALIDDATA; goto fail; } pkt->data[0] |= C93_HAS_PALETTE; ret = avio_read(pb, pkt->data + pkt->size, datasize); if (ret < datasize) { ret = AVERROR(EIO); goto fail; } pkt->size += 768; } pkt->stream_index = 0; c93->next_pkt_is_audio = 1; /* only the first frame is guaranteed to not reference previous frames */ if (c93->current_block == 0 && c93->current_frame == 0) { pkt->flags |= AV_PKT_FLAG_KEY; pkt->data[0] |= C93_FIRST_FRAME; } return 0; fail: av_free_packet(pkt); return ret; }
static int nuv_packet(AVFormatContext *s, AVPacket *pkt) { NUVContext *ctx = s->priv_data; AVIOContext *pb = s->pb; uint8_t hdr[HDRSIZE]; nuv_frametype frametype; int ret, size; while (!avio_feof(pb)) { int copyhdrsize = ctx->rtjpg_video ? HDRSIZE : 0; uint64_t pos = avio_tell(pb); ret = avio_read(pb, hdr, HDRSIZE); if (ret < HDRSIZE) return ret < 0 ? ret : AVERROR(EIO); frametype = hdr[0]; size = PKTSIZE(AV_RL32(&hdr[8])); switch (frametype) { case NUV_EXTRADATA: if (!ctx->rtjpg_video) { avio_skip(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"); avio_skip(pb, size); break; } ret = av_new_packet(pkt, copyhdrsize + size); if (ret < 0) return ret; pkt->pos = pos; pkt->flags |= hdr[2] == 0 ? AV_PKT_FLAG_KEY : 0; pkt->pts = AV_RL32(&hdr[4]); pkt->stream_index = ctx->v_id; memcpy(pkt->data, hdr, copyhdrsize); ret = avio_read(pb, pkt->data + copyhdrsize, size); if (ret < 0) { av_free_packet(pkt); return ret; } if (ret < size) av_shrink_packet(pkt, copyhdrsize + ret); return 0; case NUV_AUDIO: if (ctx->a_id < 0) { av_log(s, AV_LOG_ERROR, "Audio packet in file without audio stream!\n"); avio_skip(pb, size); break; } ret = av_get_packet(pb, pkt, size); pkt->flags |= AV_PKT_FLAG_KEY; pkt->pos = pos; pkt->pts = AV_RL32(&hdr[4]); pkt->stream_index = ctx->a_id; if (ret < 0) return ret; return 0; case NUV_SEEKP: // contains no data, size value is invalid break; default: avio_skip(pb, size); break; } } return AVERROR(EIO); }
int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) { const CodecMime *mime = ff_id3v2_mime_tags; enum AVCodecID id = AV_CODEC_ID_NONE; AVBufferRef *data = NULL; uint8_t mimetype[64], *desc = NULL; AVIOContext *pb = NULL; AVStream *st; int type, width, height; int len, ret = 0; pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL); if (!pb) return AVERROR(ENOMEM); /* read the picture type */ type = avio_rb32(pb); if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) { av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type); if (s->error_recognition & AV_EF_EXPLODE) { RETURN_ERROR(AVERROR_INVALIDDATA); } type = 0; } /* picture mimetype */ len = avio_rb32(pb); if (len <= 0 || avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) { av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached " "picture.\n"); if (s->error_recognition & AV_EF_EXPLODE) ret = AVERROR_INVALIDDATA; goto fail; } av_assert0(len < sizeof(mimetype)); mimetype[len] = 0; while (mime->id != AV_CODEC_ID_NONE) { if (!strncmp(mime->str, mimetype, sizeof(mimetype))) { id = mime->id; break; } mime++; } if (id == AV_CODEC_ID_NONE) { av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n", mimetype); if (s->error_recognition & AV_EF_EXPLODE) ret = AVERROR_INVALIDDATA; goto fail; } /* picture description */ len = avio_rb32(pb); if (len > 0) { if (!(desc = av_malloc(len + 1))) { RETURN_ERROR(AVERROR(ENOMEM)); } if (avio_read(pb, desc, len) != len) { av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n"); if (s->error_recognition & AV_EF_EXPLODE) ret = AVERROR(EIO); goto fail; } desc[len] = 0; } /* picture metadata */ width = avio_rb32(pb); height = avio_rb32(pb); avio_skip(pb, 8); /* picture data */ len = avio_rb32(pb); if (len <= 0) { av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len); if (s->error_recognition & AV_EF_EXPLODE) ret = AVERROR_INVALIDDATA; goto fail; } if (!(data = av_buffer_alloc(len))) { RETURN_ERROR(AVERROR(ENOMEM)); } if (avio_read(pb, data->data, len) != len) { av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n"); if (s->error_recognition & AV_EF_EXPLODE) ret = AVERROR(EIO); goto fail; } st = avformat_new_stream(s, NULL); if (!st) { RETURN_ERROR(AVERROR(ENOMEM)); } av_init_packet(&st->attached_pic); st->attached_pic.buf = data; st->attached_pic.data = data->data; st->attached_pic.size = len; st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; st->disposition |= AV_DISPOSITION_ATTACHED_PIC; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = id; st->codec->width = width; st->codec->height = height; av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0); if (desc) av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL); av_freep(&pb); return 0; fail: av_buffer_unref(&data); av_freep(&desc); av_freep(&pb); return ret; }
/** * @brief read until we found all data needed for decoding * @param vst video stream of which to change parameters * @param ast video stream of which to change parameters * @param myth set if this is a MythTVVideo format file * @return 0 or AVERROR code */ static int get_codec_data(AVIOContext *pb, AVStream *vst, AVStream *ast, int myth) { nuv_frametype frametype; if (!vst && !myth) return 1; // no codec data needed while (!avio_feof(pb)) { int size, subtype; frametype = avio_r8(pb); switch (frametype) { case NUV_EXTRADATA: subtype = avio_r8(pb); avio_skip(pb, 6); size = PKTSIZE(avio_rl32(pb)); if (vst && subtype == 'R') { if (vst->codec->extradata) { av_freep(&vst->codec->extradata); vst->codec->extradata_size = 0; } if (ff_get_extradata(vst->codec, pb, size) < 0) return AVERROR(ENOMEM); size = 0; if (!myth) return 0; } break; case NUV_MYTHEXT: avio_skip(pb, 7); size = PKTSIZE(avio_rl32(pb)); if (size != 128 * 4) break; avio_rl32(pb); // version if (vst) { vst->codec->codec_tag = avio_rl32(pb); vst->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, vst->codec->codec_tag); if (vst->codec->codec_tag == MKTAG('R', 'J', 'P', 'G')) vst->codec->codec_id = AV_CODEC_ID_NUV; } else avio_skip(pb, 4); if (ast) { int id; ast->codec->codec_tag = avio_rl32(pb); ast->codec->sample_rate = avio_rl32(pb); ast->codec->bits_per_coded_sample = avio_rl32(pb); ast->codec->channels = avio_rl32(pb); ast->codec->channel_layout = 0; id = ff_wav_codec_get_id(ast->codec->codec_tag, ast->codec->bits_per_coded_sample); if (id == AV_CODEC_ID_NONE) { id = ff_codec_get_id(nuv_audio_tags, ast->codec->codec_tag); if (id == AV_CODEC_ID_PCM_S16LE) id = ff_get_pcm_codec_id(ast->codec->bits_per_coded_sample, 0, 0, ~1); } ast->codec->codec_id = id; ast->need_parsing = AVSTREAM_PARSE_FULL; } else avio_skip(pb, 4 * 4); size -= 6 * 4; avio_skip(pb, size); return 0; case NUV_SEEKP: size = 11; break; default: avio_skip(pb, 7); size = PKTSIZE(avio_rl32(pb)); break; } avio_skip(pb, size); } return 0; }
static int tta_read_header(AVFormatContext *s) { TTAContext *c = s->priv_data; AVStream *st; int i, channels, bps, samplerate; uint64_t framepos, start_offset; uint32_t nb_samples, crc; ff_id3v1_read(s); start_offset = avio_tell(s->pb); ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX); if (avio_rl32(s->pb) != AV_RL32("TTA1")) return AVERROR_INVALIDDATA; avio_skip(s->pb, 2); // FIXME: flags channels = avio_rl16(s->pb); bps = avio_rl16(s->pb); samplerate = avio_rl32(s->pb); if(samplerate <= 0 || samplerate > 1000000){ av_log(s, AV_LOG_ERROR, "nonsense samplerate\n"); return AVERROR_INVALIDDATA; } nb_samples = avio_rl32(s->pb); if (!nb_samples) { av_log(s, AV_LOG_ERROR, "invalid number of samples\n"); return AVERROR_INVALIDDATA; } crc = ffio_get_checksum(s->pb) ^ UINT32_MAX; if (crc != avio_rl32(s->pb)) { av_log(s, AV_LOG_ERROR, "Header CRC error\n"); return AVERROR_INVALIDDATA; } c->frame_size = samplerate * 256 / 245; c->last_frame_size = nb_samples % c->frame_size; if (!c->last_frame_size) c->last_frame_size = c->frame_size; c->totalframes = nb_samples / c->frame_size + (c->last_frame_size < c->frame_size); c->currentframe = 0; if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){ av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes); return AVERROR_INVALIDDATA; } st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, samplerate); st->start_time = 0; st->duration = nb_samples; framepos = avio_tell(s->pb) + 4*c->totalframes + 4; if (ff_alloc_extradata(st->codec, avio_tell(s->pb) - start_offset)) return AVERROR(ENOMEM); avio_seek(s->pb, start_offset, SEEK_SET); avio_read(s->pb, st->codec->extradata, st->codec->extradata_size); ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX); for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); av_add_index_entry(st, framepos, i * c->frame_size, size, 0, AVINDEX_KEYFRAME); framepos += size; } crc = ffio_get_checksum(s->pb) ^ UINT32_MAX; if (crc != avio_rl32(s->pb)) { av_log(s, AV_LOG_ERROR, "Seek table CRC error\n"); return AVERROR_INVALIDDATA; } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TTA; st->codec->channels = channels; st->codec->sample_rate = samplerate; st->codec->bits_per_coded_sample = bps; if (s->pb->seekable) { int64_t pos = avio_tell(s->pb); ff_ape_parse_tag(s); avio_seek(s->pb, pos, SEEK_SET); } return 0; }
static int wc3_read_header(AVFormatContext *s) { Wc3DemuxContext *wc3 = s->priv_data; AVIOContext *pb = s->pb; unsigned int fourcc_tag; unsigned int size; AVStream *st; int ret = 0; char *buffer; /* default context members */ wc3->width = WC3_DEFAULT_WIDTH; wc3->height = WC3_DEFAULT_HEIGHT; wc3->pts = 0; wc3->video_stream_index = wc3->audio_stream_index = 0; av_init_packet(&wc3->vpkt); wc3->vpkt.data = NULL; wc3->vpkt.size = 0; /* skip the first 3 32-bit numbers */ avio_skip(pb, 12); /* traverse through the chunks and load the header information before * the first BRCH tag */ fourcc_tag = avio_rl32(pb); size = (avio_rb32(pb) + 1) & (~1); do { switch (fourcc_tag) { case SOND_TAG: case INDX_TAG: /* SOND unknown, INDX unnecessary; ignore both */ avio_skip(pb, size); break; case PC__TAG: /* number of palettes, unneeded */ avio_skip(pb, 12); break; case BNAM_TAG: /* load up the name */ buffer = av_malloc(size+1); if (!buffer) return AVERROR(ENOMEM); if ((ret = avio_read(pb, buffer, size)) != size) return AVERROR(EIO); buffer[size] = 0; av_dict_set(&s->metadata, "title", buffer, AV_DICT_DONT_STRDUP_VAL); break; case SIZE_TAG: /* video resolution override */ wc3->width = avio_rl32(pb); wc3->height = avio_rl32(pb); break; case PALT_TAG: /* one of several palettes */ avio_seek(pb, -8, SEEK_CUR); av_append_packet(pb, &wc3->vpkt, 8 + PALETTE_SIZE); break; default: av_log(s, AV_LOG_ERROR, "unrecognized WC3 chunk: %s\n", av_fourcc2str(fourcc_tag)); return AVERROR_INVALIDDATA; } fourcc_tag = avio_rl32(pb); /* chunk sizes are 16-bit aligned */ size = (avio_rb32(pb) + 1) & (~1); if (avio_feof(pb)) return AVERROR(EIO); } while (fourcc_tag != BRCH_TAG); /* initialize the decoder streams */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 33, 1, WC3_FRAME_FPS); wc3->video_stream_index = st->index; st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = AV_CODEC_ID_XAN_WC3; st->codecpar->codec_tag = 0; /* no fourcc */ st->codecpar->width = wc3->width; st->codecpar->height = wc3->height; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 33, 1, WC3_FRAME_FPS); wc3->audio_stream_index = st->index; st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; st->codecpar->codec_tag = 1; st->codecpar->channels = WC3_AUDIO_CHANNELS; st->codecpar->channel_layout = AV_CH_LAYOUT_MONO; st->codecpar->bits_per_coded_sample = WC3_AUDIO_BITS; st->codecpar->sample_rate = WC3_SAMPLE_RATE; st->codecpar->bit_rate = st->codecpar->channels * st->codecpar->sample_rate * st->codecpar->bits_per_coded_sample; st->codecpar->block_align = WC3_AUDIO_BITS * WC3_AUDIO_CHANNELS; return 0; }