void ff_read_chan_chunk(AVFormatContext *s, int64_t size, AVCodecContext *codec) { uint32_t layout_tag; AVIOContext *pb = s->pb; const CafChannelLayout *caf_layout = caf_channel_layout; if (size != 12) { // Channel descriptions not implemented av_log_ask_for_sample(s, "Unimplemented channel layout.\n"); avio_skip(pb, size); return; } layout_tag = avio_rb32(pb); if (layout_tag == 0x10000) { //< kCAFChannelLayoutTag_UseChannelBitmap codec->channel_layout = avio_rb32(pb); avio_skip(pb, 4); return; } while (caf_layout->channel_layout) { if (layout_tag == caf_layout->layout_tag) { codec->channel_layout = caf_layout->channel_layout; break; } caf_layout++; } if (!codec->channel_layout) av_log(s, AV_LOG_WARNING, "Unknown channel layout.\n"); avio_skip(pb, 8); }
void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec) { uint32_t layout_tag; AVIOContext *pb = s->pb; const MovChannelLayout *layouts = mov_channel_layout; layout_tag = avio_rb32(pb); size -= 4; if (layout_tag == 0) { // kCAFChannelLayoutTag_UseChannelDescriptions // Channel descriptions not implemented av_log_ask_for_sample(s, "Unimplemented container channel layout.\n"); avio_skip(pb, size); return; } if (layout_tag == 0x10000) { // kCAFChannelLayoutTag_UseChannelBitmap codec->channel_layout = avio_rb32(pb); size -= 4; avio_skip(pb, size); return; } while (layouts->channel_layout) { if (layout_tag == layouts->layout_tag) { codec->channel_layout = layouts->channel_layout; break; } layouts++; } if (!codec->channel_layout) av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n"); avio_skip(pb, size); }
/* au input */ static int au_read_header(AVFormatContext *s) { int size, bps, data_size = 0; unsigned int tag; AVIOContext *pb = s->pb; unsigned int id, channels, rate; enum AVCodecID codec; AVStream *st; /* check ".snd" header */ tag = avio_rl32(pb); if (tag != MKTAG('.', 's', 'n', 'd')) return AVERROR_INVALIDDATA; size = avio_rb32(pb); /* header size */ data_size = avio_rb32(pb); /* data size in bytes */ if (data_size < 0 && data_size != AU_UNKNOWN_SIZE) { av_log(s, AV_LOG_ERROR, "Invalid negative data size '%d' found\n", data_size); return AVERROR_INVALIDDATA; } id = avio_rb32(pb); rate = avio_rb32(pb); channels = avio_rb32(pb); codec = ff_codec_get_id(codec_au_tags, id); if (!(bps = av_get_bits_per_sample(codec))) { av_log_ask_for_sample(s, "could not determine bits per sample\n"); return AVERROR_PATCHWELCOME; } if (channels == 0 || channels > 64) { av_log(s, AV_LOG_ERROR, "Invalid number of channels %d\n", channels); return AVERROR_INVALIDDATA; } if (size >= 24) { /* skip unused data */ avio_skip(pb, size - 24); } /* now we are ready: build format streams */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = id; st->codec->codec_id = codec; st->codec->channels = channels; st->codec->sample_rate = rate; st->codec->block_align = FFMAX(bps * st->codec->channels / 8, 1); if (data_size != AU_UNKNOWN_SIZE) st->duration = (((int64_t)data_size)<<3) / (st->codec->channels * (int64_t)bps); avpriv_set_pts_info(st, 64, 1, rate); return 0; }
static int wsaud_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; AVStream *st; unsigned char header[AUD_HEADER_SIZE]; int sample_rate, channels, codec; if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE) return AVERROR(EIO); sample_rate = AV_RL16(&header[0]); channels = (header[10] & 0x1) + 1; codec = header[11]; /* initialize the audio decoder stream */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); switch (codec) { case 1: if (channels != 1) { av_log_ask_for_sample(s, "Stereo WS-SND1 is not supported.\n"); return AVERROR_PATCHWELCOME; } st->codec->codec_id = CODEC_ID_WESTWOOD_SND1; break; case 99: st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; st->codec->bits_per_coded_sample = 4; st->codec->bit_rate = channels * sample_rate * 4; break; default: av_log_ask_for_sample(s, "Unknown codec: %d\n", codec); return AVERROR_PATCHWELCOME; } avpriv_set_pts_info(st, 64, 1, sample_rate); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->channels = channels; st->codec->sample_rate = sample_rate; return 0; }
static av_cold int ws_snd_decode_init(AVCodecContext * avctx) { // WSSNDContext *c = avctx->priv_data; if (avctx->channels != 1) { av_log_ask_for_sample(avctx, "unsupported number of channels\n"); return AVERROR(EINVAL); } avctx->sample_fmt = AV_SAMPLE_FMT_U8; return 0; }
int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize, int *header_size, int *coeff) { int offset, cutoff; if (bufsize < 24) return AVERROR_INVALIDDATA; if (AV_RB16(buf) != 0x8000) return AVERROR_INVALIDDATA; offset = AV_RB16(buf + 2) + 4; if (offset < 6) { av_log(avctx, AV_LOG_ERROR, "offset is prior data\n"); return AVERROR_INVALIDDATA; } /* if copyright string is within the provided data, validate it */ if (bufsize >= offset && memcmp(buf + offset - 6, "(c)CRI", 6)) return AVERROR_INVALIDDATA; /* check for encoding=3 block_size=18, sample_size=4 */ if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) { av_log_ask_for_sample(avctx, "unsupported ADX format\n"); return AVERROR_PATCHWELCOME; } /* channels */ avctx->channels = buf[7]; if (avctx->channels <= 0 || avctx->channels > 2) return AVERROR_INVALIDDATA; /* sample rate */ avctx->sample_rate = AV_RB32(buf + 8); if (avctx->sample_rate < 1 || avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8)) return AVERROR_INVALIDDATA; /* bit rate */ avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES; /* LPC coefficients */ if (coeff) { cutoff = AV_RB16(buf + 16); ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff); } *header_size = offset; return 0; }
/* au input */ static int au_read_header(AVFormatContext *s) { int size; unsigned int tag; AVIOContext *pb = s->pb; unsigned int id, channels, rate; enum AVCodecID codec; AVStream *st; /* check ".snd" header */ tag = avio_rl32(pb); if (tag != MKTAG('.', 's', 'n', 'd')) return -1; size = avio_rb32(pb); /* header size */ avio_rb32(pb); /* data size */ id = avio_rb32(pb); rate = avio_rb32(pb); channels = avio_rb32(pb); codec = ff_codec_get_id(codec_au_tags, id); if (!av_get_bits_per_sample(codec)) { av_log_ask_for_sample(s, "could not determine bits per sample\n"); return AVERROR_INVALIDDATA; } if (channels == 0 || channels > 64) { av_log(s, AV_LOG_ERROR, "Invalid number of channels %d\n", channels); return AVERROR_INVALIDDATA; } if (size >= 24) { /* skip unused data */ avio_skip(pb, size - 24); } /* now we are ready: build format streams */ st = avformat_new_stream(s, NULL); if (!st) return -1; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = id; st->codec->codec_id = codec; st->codec->channels = channels; st->codec->sample_rate = rate; avpriv_set_pts_info(st, 64, 1, rate); return 0; }
static av_cold int ws_snd_decode_init(AVCodecContext *avctx) { WSSndContext *s = (WSSndContext *)avctx->priv_data; if (avctx->channels != 1) { av_log_ask_for_sample(avctx, "unsupported number of channels\n"); return AVERROR(EINVAL); } avctx->sample_fmt = AV_SAMPLE_FMT_U8; avcodec_get_frame_defaults(&s->frame); avctx->coded_frame = &s->frame; return 0; }
static av_cold int zero12v_decode_init(AVCodecContext *avctx) { avctx->pix_fmt = PIX_FMT_YUV422P16; avctx->bits_per_raw_sample = 10; avctx->coded_frame = avcodec_alloc_frame(); if (!avctx->coded_frame) return AVERROR(ENOMEM); if (avctx->codec_tag == MKTAG('a', '1', '2', 'v')) av_log_ask_for_sample(avctx, "Samples with actual transparency needed\n"); avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; return 0; }
/* au input */ static int au_read_header(AVFormatContext *s, AVFormatParameters *ap) { int size; unsigned int tag; ByteIOContext *pb = s->pb; unsigned int id, channels, rate; enum CodecID codec; AVStream *st; /* check ".snd" header */ tag = get_le32(pb); if (tag != MKTAG('.', 's', 'n', 'd')) return -1; size = get_be32(pb); /* header size */ get_be32(pb); /* data size */ id = get_be32(pb); rate = get_be32(pb); channels = get_be32(pb); codec = ff_codec_get_id(codec_au_tags, id); if (!av_get_bits_per_sample(codec)) { av_log_ask_for_sample(s, "could not determine bits per sample\n"); return AVERROR_INVALIDDATA; } if (size >= 24) { /* skip unused data */ url_fseek(pb, size - 24, SEEK_CUR); } /* now we are ready: build format streams */ st = av_new_stream(s, 0); if (!st) return -1; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = id; st->codec->codec_id = codec; st->codec->channels = channels; st->codec->sample_rate = rate; av_set_pts_info(st, 64, 1, rate); return 0; }
static av_cold int truespeech_decode_init(AVCodecContext * avctx) { TSContext *c = avctx->priv_data; if (avctx->channels != 1) { av_log_ask_for_sample(avctx, "Unsupported channel count: %d\n", avctx->channels); return AVERROR(EINVAL); } avctx->sample_fmt = AV_SAMPLE_FMT_S16; dsputil_init(&c->dsp, avctx); avcodec_get_frame_defaults(&c->frame); avctx->coded_frame = &c->frame; return 0; }
static int rso_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; int id, rate, bps; unsigned int size; enum AVCodecID codec; AVStream *st; id = avio_rb16(pb); size = avio_rb16(pb); rate = avio_rb16(pb); avio_rb16(pb); /* play mode ? (0x0000 = don't loop) */ codec = ff_codec_get_id(ff_codec_rso_tags, id); if (codec == AV_CODEC_ID_ADPCM_IMA_WAV) { av_log(s, AV_LOG_ERROR, "ADPCM in RSO not implemented\n"); return AVERROR_PATCHWELCOME; } bps = av_get_bits_per_sample(codec); if (!bps) { av_log_ask_for_sample(s, "could not determine bits per sample\n"); return AVERROR_INVALIDDATA; } /* now we are ready: build format streams */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->duration = (size * 8) / bps; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = id; st->codec->codec_id = codec; st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; st->codec->sample_rate = rate; avpriv_set_pts_info(st, 64, 1, rate); return 0; }
static int pmp_packet(AVFormatContext *s, AVPacket *pkt) { PMPContext *pmp = s->priv_data; AVIOContext *pb = s->pb; int ret = 0; int i; if (url_feof(pb)) return AVERROR_EOF; if (pmp->cur_stream == 0) { int num_packets; pmp->audio_packets = avio_r8(pb); if (!pmp->audio_packets) { av_log_ask_for_sample(s, "0 audio packets\n"); return AVERROR_PATCHWELCOME; } num_packets = (pmp->num_streams - 1) * pmp->audio_packets + 1; avio_skip(pb, 8); pmp->current_packet = 0; av_fast_malloc(&pmp->packet_sizes, &pmp->packet_sizes_alloc, num_packets * sizeof(*pmp->packet_sizes)); if (!pmp->packet_sizes_alloc) { av_log(s, AV_LOG_ERROR, "Cannot (re)allocate packet buffer\n"); return AVERROR(ENOMEM); } for (i = 0; i < num_packets; i++) pmp->packet_sizes[i] = avio_rl32(pb); } ret = av_get_packet(pb, pkt, pmp->packet_sizes[pmp->current_packet]); if (ret >= 0) { ret = 0; // FIXME: this is a hack that should be removed once // compute_pkt_fields() can handle timestamps properly if (pmp->cur_stream == 0) pkt->dts = s->streams[0]->cur_dts++; pkt->stream_index = pmp->cur_stream; } if (pmp->current_packet % pmp->audio_packets == 0) pmp->cur_stream = (pmp->cur_stream + 1) % pmp->num_streams; pmp->current_packet++; return ret; }
static int read_header(AVFormatContext *s, AVFormatParameters *ap) { FilmstripDemuxContext *film = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; if (!s->pb->seekable) return AVERROR(EIO); avio_seek(pb, avio_size(pb) - 36, SEEK_SET); if (avio_rb32(pb) != RAND_TAG) { av_log(s, AV_LOG_ERROR, "magic number not found"); return AVERROR_INVALIDDATA; } st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->nb_frames = avio_rb32(pb); if (avio_rb16(pb) != 0) { av_log_ask_for_sample(s, "unsupported packing method\n"); return AVERROR_INVALIDDATA; } avio_skip(pb, 2); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_RAWVIDEO; st->codec->pix_fmt = PIX_FMT_RGBA; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = avio_rb16(pb); st->codec->height = avio_rb16(pb); film->leading = avio_rb16(pb); av_set_pts_info(st, 64, 1, avio_rb16(pb)); avio_seek(pb, 0, SEEK_SET); return 0; }
static int read_header(AVFormatContext *s, AVFormatParameters *ap) { AnmDemuxContext *anm = s->priv_data; ByteIOContext *pb = s->pb; AVStream *st; int i, ret; url_fskip(pb, 4); /* magic number */ if (get_le16(pb) != MAX_PAGES) { av_log_ask_for_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES) "\n"); return AVERROR_INVALIDDATA; } anm->nb_pages = get_le16(pb); anm->nb_records = get_le32(pb); url_fskip(pb, 2); /* max records per page */ anm->page_table_offset = get_le16(pb); if (get_le32(pb) != ANIM_TAG) return AVERROR_INVALIDDATA; /* video stream */ st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_ANM; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = get_le16(pb); st->codec->height = get_le16(pb); if (get_byte(pb) != 0) goto invalid; url_fskip(pb, 1); /* frame rate multiplier info */ /* ignore last delta record (used for looping) */ if (get_byte(pb)) /* has_last_delta */ anm->nb_records = FFMAX(anm->nb_records - 1, 0); url_fskip(pb, 1); /* last_delta_valid */ if (get_byte(pb) != 0) goto invalid; if (get_byte(pb) != 1) goto invalid; url_fskip(pb, 1); /* other recs per frame */ if (get_byte(pb) != 1) goto invalid; url_fskip(pb, 32); /* record_types */ st->nb_frames = get_le32(pb); av_set_pts_info(st, 64, 1, get_le16(pb)); url_fskip(pb, 58); /* color cycling and palette data */ st->codec->extradata_size = 16*8 + 4*256; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { ret = AVERROR(ENOMEM); goto close_and_return; } ret = get_buffer(pb, st->codec->extradata, st->codec->extradata_size); if (ret < 0) goto close_and_return; /* read page table */ ret = url_fseek(pb, anm->page_table_offset, SEEK_SET); if (ret < 0) goto close_and_return; for (i = 0; i < MAX_PAGES; i++) { Page *p = &anm->pt[i]; p->base_record = get_le16(pb); p->nb_records = get_le16(pb); p->size = get_le16(pb); } /* find page of first frame */ anm->page = find_record(anm, 0); if (anm->page < 0) { ret = anm->page; goto close_and_return; } anm->record = -1; return 0; invalid: av_log_ask_for_sample(s, NULL); ret = AVERROR_INVALIDDATA; close_and_return: av_close_input_stream(s); return ret; }
static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, uint8_t block_type, AVFormatContext *s) { uint8_t * vidbuf_start = NULL; int vidbuf_nbytes = 0; int code; int bytes_copied = 0; int position, duration, npixels; unsigned int vidbuf_capacity; int ret = 0; AVStream *st; if (vid->video_index < 0) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); vid->video_index = st->index; if (vid->audio_index < 0) { av_log_ask_for_sample(s, "No audio packet before first video " "packet. Using default video time base.\n"); } avpriv_set_pts_info(st, 64, 185, vid->sample_rate); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_BETHSOFTVID; st->codec->width = vid->width; st->codec->height = vid->height; } st = s->streams[vid->video_index]; npixels = st->codec->width * st->codec->height; vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); // save the file position for the packet, include block type position = avio_tell(pb) - 1; vidbuf_start[vidbuf_nbytes++] = block_type; // get the current packet duration duration = vid->bethsoft_global_delay + avio_rl16(pb); // set the y offset if it exists (decoder header data should be in data section) if(block_type == VIDEO_YOFF_P_FRAME){ if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) { ret = AVERROR(EIO); goto fail; } vidbuf_nbytes += 2; } do{ vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); code = avio_r8(pb); vidbuf_start[vidbuf_nbytes++] = code; if(code >= 0x80){ // rle sequence if(block_type == VIDEO_I_FRAME) vidbuf_start[vidbuf_nbytes++] = avio_r8(pb); } else if(code){ // plain sequence if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) { ret = AVERROR(EIO); goto fail; } vidbuf_nbytes += code; } bytes_copied += code & 0x7F; if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied // may contain a 0 byte even if read all pixels if(avio_r8(pb)) avio_seek(pb, -1, SEEK_CUR); break; } if (bytes_copied > npixels) { ret = AVERROR_INVALIDDATA; goto fail; } } while(code); // copy data into packet if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0) goto fail; memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); av_free(vidbuf_start); pkt->pos = position; pkt->stream_index = vid->video_index; pkt->duration = duration; if (block_type == VIDEO_I_FRAME) pkt->flags |= AV_PKT_FLAG_KEY; /* if there is a new palette available, add it to packet side data */ if (vid->palette) { uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, BVID_PALETTE_SIZE); memcpy(pdata, vid->palette, BVID_PALETTE_SIZE); av_freep(&vid->palette); } vid->nframes--; // used to check if all the frames were read return 0; fail: av_free(vidbuf_start); return ret; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { PicContext *s = avctx->priv_data; uint32_t *palette; int bits_per_plane, bpp, etype, esize, npal, pos_after_pal; int i, x, y, plane, tmp; bytestream2_init(&s->g, avpkt->data, avpkt->size); if (bytestream2_get_bytes_left(&s->g) < 11) return AVERROR_INVALIDDATA; if (bytestream2_get_le16u(&s->g) != 0x1234) return AVERROR_INVALIDDATA; s->width = bytestream2_get_le16u(&s->g); s->height = bytestream2_get_le16u(&s->g); bytestream2_skip(&s->g, 4); tmp = bytestream2_get_byteu(&s->g); bits_per_plane = tmp & 0xF; s->nb_planes = (tmp >> 4) + 1; bpp = bits_per_plane * s->nb_planes; if (bits_per_plane > 8 || bpp < 1 || bpp > 32) { av_log_ask_for_sample(s, "unsupported bit depth\n"); return AVERROR_INVALIDDATA; } if (bytestream2_peek_byte(&s->g) == 0xFF) { bytestream2_skip(&s->g, 2); etype = bytestream2_get_le16(&s->g); esize = bytestream2_get_le16(&s->g); if (bytestream2_get_bytes_left(&s->g) < esize) return AVERROR_INVALIDDATA; } else { etype = -1; esize = 0; } avctx->pix_fmt = PIX_FMT_PAL8; if (s->width != avctx->width && s->height != avctx->height) { if (av_image_check_size(s->width, s->height, 0, avctx) < 0) return -1; avcodec_set_dimensions(avctx, s->width, s->height); if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); } if (avctx->get_buffer(avctx, &s->frame) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } memset(s->frame.data[0], 0, s->height * s->frame.linesize[0]); s->frame.pict_type = AV_PICTURE_TYPE_I; s->frame.palette_has_changed = 1; pos_after_pal = bytestream2_tell(&s->g) + esize; palette = (uint32_t*)s->frame.data[1]; if (etype == 1 && esize > 1 && bytestream2_peek_byte(&s->g) < 6) { int idx = bytestream2_get_byte(&s->g); npal = 4; for (i = 0; i < npal; i++) palette[i] = ff_cga_palette[ cga_mode45_index[idx][i] ]; } else if (etype == 2) { npal = FFMIN(esize, 16); for (i = 0; i < npal; i++) { int pal_idx = bytestream2_get_byte(&s->g); palette[i] = ff_cga_palette[FFMIN(pal_idx, 16)]; } } else if (etype == 3) { npal = FFMIN(esize, 16); for (i = 0; i < npal; i++) { int pal_idx = bytestream2_get_byte(&s->g); palette[i] = ff_ega_palette[FFMIN(pal_idx, 63)]; } } else if (etype == 4 || etype == 5) { npal = FFMIN(esize / 3, 256); for (i = 0; i < npal; i++) palette[i] = bytestream2_get_be24(&s->g) << 2; } else { if (bpp == 1) { npal = 2; palette[0] = 0x000000; palette[1] = 0xFFFFFF; } else if (bpp == 2) { npal = 4; for (i = 0; i < npal; i++) palette[i] = ff_cga_palette[ cga_mode45_index[0][i] ]; } else { npal = 16; memcpy(palette, ff_cga_palette, npal * 4); } } // fill remaining palette entries memset(palette + npal, 0, AVPALETTE_SIZE - npal * 4); // skip remaining palette bytes bytestream2_seek(&s->g, pos_after_pal, SEEK_SET); x = 0; y = s->height - 1; plane = 0; if (bytestream2_get_le16(&s->g)) { while (bytestream2_get_bytes_left(&s->g) >= 6) { int stop_size, marker, t1, t2; t1 = bytestream2_get_bytes_left(&s->g); t2 = bytestream2_get_le16(&s->g); stop_size = t1 - FFMIN(t1, t2); // ignore uncompressed block size bytestream2_skip(&s->g, 2); marker = bytestream2_get_byte(&s->g); while (plane < s->nb_planes && bytestream2_get_bytes_left(&s->g) > stop_size) { int run = 1; int val = bytestream2_get_byte(&s->g); if (val == marker) { run = bytestream2_get_byte(&s->g); if (run == 0) run = bytestream2_get_le16(&s->g); val = bytestream2_get_byte(&s->g); } if (!bytestream2_get_bytes_left(&s->g)) break; if (bits_per_plane == 8) { picmemset_8bpp(s, val, run, &x, &y); if (y < 0) break; } else { picmemset(s, val, run, &x, &y, &plane, bits_per_plane); } } } } else { av_log_ask_for_sample(s, "uncompressed image\n"); return avpkt->size; } *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; return avpkt->size; }
static int cdxl_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt) { CDXLVideoContext *c = avctx->priv_data; AVFrame * const p = &c->frame; int ret, w, h, encoding, aligned_width, buf_size = pkt->size; const uint8_t *buf = pkt->data; if (buf_size < 32) return AVERROR_INVALIDDATA; encoding = buf[1] & 7; c->format = buf[1] & 0xE0; w = AV_RB16(&buf[14]); h = AV_RB16(&buf[16]); c->bpp = buf[19]; c->palette_size = AV_RB16(&buf[20]); c->palette = buf + 32; c->video = c->palette + c->palette_size; c->video_size = buf_size - c->palette_size - 32; if (c->palette_size > 512) return AVERROR_INVALIDDATA; if (buf_size < c->palette_size + 32) return AVERROR_INVALIDDATA; if (c->bpp < 1) return AVERROR_INVALIDDATA; if (c->format != BIT_PLANAR && c->format != BIT_LINE) { av_log_ask_for_sample(avctx, "unsupported pixel format: 0x%0x\n", c->format); return AVERROR_PATCHWELCOME; } if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) return ret; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); aligned_width = FFALIGN(c->avctx->width, 16); c->padded_bits = aligned_width - c->avctx->width; if (c->video_size < aligned_width * avctx->height * c->bpp / 8) return AVERROR_INVALIDDATA; if (!encoding && c->palette_size && c->bpp <= 8) { avctx->pix_fmt = PIX_FMT_PAL8; } else if (encoding == 1 && (c->bpp == 6 || c->bpp == 8)) { if (c->palette_size != (1 << (c->bpp - 1))) return AVERROR_INVALIDDATA; avctx->pix_fmt = PIX_FMT_BGR24; } else { av_log_ask_for_sample(avctx, "unsupported encoding %d and bpp %d\n", encoding, c->bpp); return AVERROR_PATCHWELCOME; } if (p->data[0]) avctx->release_buffer(avctx, p); p->reference = 0; if ((ret = avctx->get_buffer(avctx, p)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } p->pict_type = AV_PICTURE_TYPE_I; if (encoding) { av_fast_padded_malloc(&c->new_video, &c->new_video_size, h * w + FF_INPUT_BUFFER_PADDING_SIZE); if (!c->new_video) return AVERROR(ENOMEM); if (c->bpp == 8) cdxl_decode_ham8(c); else cdxl_decode_ham6(c); } else { cdxl_decode_rgb(c); } *data_size = sizeof(AVFrame); *(AVFrame*)data = c->frame; return buf_size; }
static int sunrast_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; const uint8_t *buf_end = avpkt->data + avpkt->size; SUNRASTContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = &s->picture; unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen; uint8_t *ptr; const uint8_t *bufstart = buf; if (avpkt->size < 32) return AVERROR_INVALIDDATA; if (AV_RB32(buf) != RAS_MAGIC) { av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n"); return -1; } w = AV_RB32(buf + 4); h = AV_RB32(buf + 8); depth = AV_RB32(buf + 12); type = AV_RB32(buf + 20); maptype = AV_RB32(buf + 24); maplength = AV_RB32(buf + 28); buf += 32; if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF || type == RT_EXPERIMENTAL) { av_log_ask_for_sample(avctx, "unsupported (compression) type\n"); return AVERROR_PATCHWELCOME; } if (type > RT_FORMAT_IFF) { av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); return -1; } if (av_image_check_size(w, h, 0, avctx)) { av_log(avctx, AV_LOG_ERROR, "invalid image size\n"); return -1; } if (maptype & ~1) { av_log(avctx, AV_LOG_ERROR, "invalid colormap type\n"); return -1; } switch (depth) { case 1: avctx->pix_fmt = PIX_FMT_MONOWHITE; break; case 8: avctx->pix_fmt = PIX_FMT_PAL8; break; case 24: avctx->pix_fmt = (type == RT_FORMAT_RGB) ? PIX_FMT_RGB24 : PIX_FMT_BGR24; break; default: av_log(avctx, AV_LOG_ERROR, "invalid depth\n"); return -1; } if (p->data[0]) avctx->release_buffer(avctx, p); if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); if (avctx->get_buffer(avctx, p) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } p->pict_type = AV_PICTURE_TYPE_I; if (buf_end - buf < maplength) return AVERROR_INVALIDDATA; if (depth != 8 && maplength) { av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n"); } else if (depth == 8) { unsigned int len = maplength / 3; if (!maplength) { av_log(avctx, AV_LOG_ERROR, "colormap expected\n"); return -1; } if (maplength % 3 || maplength > 768) { av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); return -1; } ptr = p->data[1]; for (x = 0; x < len; x++, ptr += 4) *(uint32_t *)ptr = (buf[x] << 16) + (buf[len + x] << 8) + buf[len + len + x]; } buf += maplength; ptr = p->data[0]; stride = p->linesize[0]; /* scanlines are aligned on 16 bit boundaries */ len = (depth * w + 7) >> 3; alen = len + (len & 1); if (type == RT_BYTE_ENCODED) { int value, run; uint8_t *end = ptr + h * stride; x = 0; while (ptr != end && buf < buf_end) { run = 1; if (buf_end - buf < 1) return AVERROR_INVALIDDATA; if ((value = *buf++) == 0x80) { run = *buf++ + 1; if (run != 1) value = *buf++; } while (run--) { if (x < len) ptr[x] = value; if (++x >= alen) { x = 0; ptr += stride; if (ptr == end) break; } } } } else { for (y = 0; y < h; y++) { if (buf_end - buf < len) break; memcpy(ptr, buf, len); ptr += stride; buf += alen; } } *picture = s->picture; *data_size = sizeof(AVFrame); return buf - bufstart; }
static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; enum IEC61937DataType data_type; enum CodecID codec_id; uint32_t state = 0; int pkt_size_bits, offset, ret; while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) { state = (state << 8) | avio_r8(pb); if (url_feof(pb)) return AVERROR_EOF; } data_type = avio_rl16(pb); pkt_size_bits = avio_rl16(pb); if (pkt_size_bits % 16) av_log_ask_for_sample(s, "Packet does not end to a 16-bit boundary."); ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3); if (ret) return ret; pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE; if (avio_read(pb, pkt->data, pkt->size) < pkt->size) { av_free_packet(pkt); return AVERROR_EOF; } ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); ret = spdif_get_offset_and_codec(s, data_type, 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 = av_new_stream(s, 0); if (!st) { av_free_packet(pkt); return AVERROR(ENOMEM); } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = codec_id; } else if (codec_id != s->streams[0]->codec->codec_id) { av_log_missing_feature(s, "codec change in IEC 61937", 0); return AVERROR_PATCHWELCOME; } if (!s->bit_rate && s->streams[0]->codec->sample_rate) /* stream bitrate matches 16-bit stereo PCM bitrate for currently supported codecs */ s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate; return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { PicContext *s = avctx->priv_data; int buf_size = avpkt->size; const uint8_t *buf = avpkt->data; const uint8_t *buf_end = avpkt->data + buf_size; uint32_t *palette; int bits_per_plane, bpp, etype, esize, npal; int i, x, y, plane; if (buf_size < 11) return AVERROR_INVALIDDATA; if (bytestream_get_le16(&buf) != 0x1234) return AVERROR_INVALIDDATA; s->width = bytestream_get_le16(&buf); s->height = bytestream_get_le16(&buf); buf += 4; bits_per_plane = *buf & 0xF; s->nb_planes = (*buf++ >> 4) + 1; bpp = s->nb_planes ? bits_per_plane*s->nb_planes : bits_per_plane; if (bits_per_plane > 8 || bpp < 1 || bpp > 32) { av_log_ask_for_sample(s, "unsupported bit depth\n"); return AVERROR_INVALIDDATA; } if (*buf == 0xFF) { buf += 2; etype = bytestream_get_le16(&buf); esize = bytestream_get_le16(&buf); if (buf_end - buf < esize) return AVERROR_INVALIDDATA; } else { etype = -1; esize = 0; } avctx->pix_fmt = PIX_FMT_PAL8; if (s->width != avctx->width && s->height != avctx->height) { if (av_image_check_size(s->width, s->height, 0, avctx) < 0) return -1; avcodec_set_dimensions(avctx, s->width, s->height); if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); } if (avctx->get_buffer(avctx, &s->frame) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } memset(s->frame.data[0], 0, s->height * s->frame.linesize[0]); s->frame.pict_type = FF_I_TYPE; s->frame.palette_has_changed = 1; palette = (uint32_t*)s->frame.data[1]; if (etype == 1 && esize > 1 && *buf < 6) { int idx = *buf; npal = 4; for (i = 0; i < npal; i++) palette[i] = ff_cga_palette[ cga_mode45_index[idx][i] ]; } else if (etype == 2) { npal = FFMIN(esize, 16); for (i = 0; i < npal; i++) palette[i] = ff_cga_palette[ FFMIN(buf[i], 16)]; } else if (etype == 3) { npal = FFMIN(esize, 16); for (i = 0; i < npal; i++) palette[i] = ff_ega_palette[ FFMIN(buf[i], 63)]; } else if (etype == 4 || etype == 5) { npal = FFMIN(esize / 3, 256); for (i = 0; i < npal; i++) palette[i] = AV_RB24(buf + i*3) << 2; } else { if (bpp == 1) { npal = 2; palette[0] = 0x000000; palette[1] = 0xFFFFFF; } else if (bpp == 2) { npal = 4; for (i = 0; i < npal; i++) palette[i] = ff_cga_palette[ cga_mode45_index[0][i] ]; } else { npal = 16; memcpy(palette, ff_cga_palette, npal * 4); } } // fill remaining palette entries memset(palette + npal, 0, AVPALETTE_SIZE - npal * 4); buf += esize; x = 0; y = s->height - 1; plane = 0; if (bytestream_get_le16(&buf)) { while (buf_end - buf >= 6) { const uint8_t *buf_pend = buf + FFMIN(AV_RL16(buf), buf_end - buf); //ignore uncompressed block size reported at buf[2] int marker = buf[4]; buf += 5; while (plane < s->nb_planes && buf_pend - buf >= 1) { int run = 1; int val = *buf++; if (val == marker) { run = *buf++; if (run == 0) run = bytestream_get_le16(&buf); val = *buf++; } if (buf > buf_end) break; if (bits_per_plane == 8) { picmemset_8bpp(s, val, run, &x, &y); if (y < 0) break; } else { picmemset(s, val, run, &x, &y, &plane, bits_per_plane); } } } } else { av_log_ask_for_sample(s, "uncompressed image\n"); return buf_size; } *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; return buf_size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { int y=0; int width= avctx->width; AVFrame *pic= avctx->coded_frame; const uint32_t *src= (const uint32_t *)avpkt->data; uint16_t *ydst, *udst, *vdst, *yend; if(pic->data[0]) avctx->release_buffer(avctx, pic); if(avpkt->size < avctx->width * avctx->height * 8 / 3){ av_log(avctx, AV_LOG_ERROR, "Packet too small\n"); return -1; } if(avpkt->size > avctx->width * avctx->height * 8 / 3){ av_log_ask_for_sample(avctx, "Probably padded data\n"); } pic->reference= 0; if(avctx->get_buffer(avctx, pic) < 0) return -1; ydst= (uint16_t *)pic->data[0]; udst= (uint16_t *)pic->data[1]; vdst= (uint16_t *)pic->data[2]; yend= ydst + width; pic->pict_type= AV_PICTURE_TYPE_I; pic->key_frame= 1; for(;;){ uint32_t v= av_be2ne32(*src++); *udst++= (v>>16) & 0xFFC0; *ydst++= (v>>6 ) & 0xFFC0; *vdst++= (v<<4 ) & 0xFFC0; v= av_be2ne32(*src++); *ydst++= (v>>16) & 0xFFC0; if(ydst >= yend){ ydst+= pic->linesize[0]/2 - width; udst+= pic->linesize[1]/2 - width/2; vdst+= pic->linesize[2]/2 - width/2; yend= ydst + width; if(++y >= avctx->height) break; } *udst++= (v>>6 ) & 0xFFC0; *ydst++= (v<<4 ) & 0xFFC0; v= av_be2ne32(*src++); *vdst++= (v>>16) & 0xFFC0; *ydst++= (v>>6 ) & 0xFFC0; if(ydst >= yend){ ydst+= pic->linesize[0]/2 - width; udst+= pic->linesize[1]/2 - width/2; vdst+= pic->linesize[2]/2 - width/2; yend= ydst + width; if(++y >= avctx->height) break; } *udst++= (v<<4 ) & 0xFFC0; v= av_be2ne32(*src++); *ydst++= (v>>16) & 0xFFC0; *vdst++= (v>>6 ) & 0xFFC0; *ydst++= (v<<4 ) & 0xFFC0; if(ydst >= yend){ ydst+= pic->linesize[0]/2 - width; udst+= pic->linesize[1]/2 - width/2; vdst+= pic->linesize[2]/2 - width/2; yend= ydst + width; if(++y >= avctx->height) break; } } *data_size=sizeof(AVFrame); *(AVFrame*)data= *avctx->coded_frame; return avpkt->size; }
/** * Execute ANSI escape code * @param <0 error */ static int execute_code(AVCodecContext * avctx, int c) { AnsiContext *s = avctx->priv_data; int ret, i, width, height; switch(c) { case 'A': //Cursor Up s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0); break; case 'B': //Cursor Down s->y = FFMIN(s->y + (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), avctx->height - s->font_height); break; case 'C': //Cursor Right s->x = FFMIN(s->x + (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), avctx->width - FONT_WIDTH); break; case 'D': //Cursor Left s->x = FFMAX(s->x - (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), 0); break; case 'H': //Cursor Position case 'f': //Horizontal and Vertical Position s->y = s->nb_args > 0 ? av_clip((s->args[0] - 1)*s->font_height, 0, avctx->height - s->font_height) : 0; s->x = s->nb_args > 1 ? av_clip((s->args[1] - 1)*FONT_WIDTH, 0, avctx->width - FONT_WIDTH) : 0; break; case 'h': //set creen mode case 'l': //reset screen mode if (s->nb_args < 2) s->args[0] = DEFAULT_SCREEN_MODE; switch(s->args[0]) { case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows) s->font = ff_cga_font; s->font_height = 8; width = 40<<3; height = 25<<3; break; case 2: case 3: //640x400 (25 rows) s->font = ff_vga16_font; s->font_height = 16; width = 80<<3; height = 25<<4; break; case 6: case 14: //640x200 (25 rows) s->font = ff_cga_font; s->font_height = 8; width = 80<<3; height = 25<<3; break; case 7: //set line wrapping break; case 15: case 16: //640x350 (43 rows) s->font = ff_cga_font; s->font_height = 8; width = 80<<3; height = 43<<3; break; case 17: case 18: //640x480 (60 rows) s->font = ff_cga_font; s->font_height = 8; width = 80<<3; height = 60<<4; break; default: av_log_ask_for_sample(avctx, "unsupported screen mode\n"); } if (width != avctx->width || height != avctx->height) { if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); avcodec_set_dimensions(avctx, width, height); ret = avctx->get_buffer(avctx, &s->frame); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } s->frame.pict_type = FF_I_TYPE; s->frame.palette_has_changed = 1; memcpy(s->frame.data[1], ff_cga_palette, 16 * 4); erase_screen(avctx); } else if (c == 'l') { erase_screen(avctx); } break; case 'J': //Erase in Page switch (s->args[0]) { case 0: erase_line(avctx, s->x, avctx->width - s->x); if (s->y < avctx->height - s->font_height) memset(s->frame.data[0] + (s->y + s->font_height)*s->frame.linesize[0], DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame.linesize[0]); break; case 1: erase_line(avctx, 0, s->x); if (s->y > 0) memset(s->frame.data[0], DEFAULT_BG_COLOR, s->y * s->frame.linesize[0]); break; case 2: erase_screen(avctx); } break; case 'K': //Erase in Line switch(s->args[0]) { case 0: erase_line(avctx, s->x, avctx->width - s->x); break; case 1: erase_line(avctx, 0, s->x); break; case 2: erase_line(avctx, 0, avctx->width); } break; case 'm': //Select Graphics Rendition if (s->nb_args == 0) { s->nb_args = 1; s->args[0] = 0; } for (i = 0; i < FFMIN(s->nb_args, MAX_NB_ARGS); i++) { int m = s->args[i]; if (m == 0) { s->attributes = 0; s->fg = DEFAULT_FG_COLOR; s->bg = DEFAULT_BG_COLOR; } else if (m == 1 || m == 2 || m == 4 || m == 5 || m == 7 || m == 8) { s->attributes |= 1 << (m - 1); } else if (m >= 30 && m <= 38) { s->fg = ansi_to_cga[m - 30]; } else if (m == 39) { s->fg = ansi_to_cga[DEFAULT_FG_COLOR]; } else if (m >= 40 && m <= 47) { s->bg = ansi_to_cga[m - 40]; } else if (m == 49) { s->fg = ansi_to_cga[DEFAULT_BG_COLOR]; } else { av_log_ask_for_sample(avctx, "unsupported rendition parameter\n"); } } break; case 'n': //Device Status Report case 'R': //report current line and column /* ignore */ break; case 's': //Save Cursor Position s->sx = s->x; s->sy = s->y; break; case 'u': //Restore Cursor Position s->x = av_clip(s->sx, 0, avctx->width - FONT_WIDTH); s->y = av_clip(s->sy, 0, avctx->height - s->font_height); break; default: av_log_ask_for_sample(avctx, "unsupported escape code\n"); break; } return 0; }
static int smjpeg_read_header(AVFormatContext *s) { SMJPEGContext *sc = s->priv_data; AVStream *ast = NULL, *vst = NULL; AVIOContext *pb = s->pb; uint32_t version, htype, hlength, duration; char *comment; avio_skip(pb, 8); // magic version = avio_rb32(pb); if (version) av_log_ask_for_sample(s, "unknown version %d\n", version); duration = avio_rb32(pb); // in msec while (!pb->eof_reached) { htype = avio_rl32(pb); switch (htype) { case SMJPEG_TXT: hlength = avio_rb32(pb); if (!hlength || hlength > 512) return AVERROR_INVALIDDATA; comment = av_malloc(hlength + 1); if (!comment) return AVERROR(ENOMEM); if (avio_read(pb, comment, hlength) != hlength) { av_freep(&comment); av_log(s, AV_LOG_ERROR, "error when reading comment\n"); return AVERROR_INVALIDDATA; } comment[hlength] = 0; av_dict_set(&s->metadata, "comment", comment, AV_DICT_DONT_STRDUP_VAL); break; case SMJPEG_SND: if (ast) { av_log_ask_for_sample(s, "multiple audio streams not supported\n"); return AVERROR_INVALIDDATA; } hlength = avio_rb32(pb); if (hlength < 8) return AVERROR_INVALIDDATA; ast = avformat_new_stream(s, 0); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->sample_rate = avio_rb16(pb); ast->codec->bits_per_coded_sample = avio_r8(pb); ast->codec->channels = avio_r8(pb); ast->codec->codec_tag = avio_rl32(pb); ast->codec->codec_id = ff_codec_get_id(ff_codec_smjpeg_audio_tags, ast->codec->codec_tag); ast->duration = duration; sc->audio_stream_index = ast->index; avpriv_set_pts_info(ast, 32, 1, 1000); avio_skip(pb, hlength - 8); break; case SMJPEG_VID: if (vst) { av_log_ask_for_sample(s, "multiple video streams not supported\n"); return AVERROR_INVALIDDATA; } hlength = avio_rb32(pb); if (hlength < 12) return AVERROR_INVALIDDATA; avio_skip(pb, 4); // number of frames vst = avformat_new_stream(s, 0); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->width = avio_rb16(pb); vst->codec->height = avio_rb16(pb); vst->codec->codec_tag = avio_rl32(pb); vst->codec->codec_id = ff_codec_get_id(ff_codec_smjpeg_video_tags, vst->codec->codec_tag); vst->duration = duration; sc->video_stream_index = vst->index; avpriv_set_pts_info(vst, 32, 1, 1000); avio_skip(pb, hlength - 12); break; case SMJPEG_HEND: return 0; default: av_log(s, AV_LOG_ERROR, "unknown header %x\n", htype); return AVERROR_INVALIDDATA; } } return AVERROR_EOF; }
/* Returns the number of bytes consumed from the bytestream. Returns -1 if * there was an error while decoding the header */ static int truemotion1_decode_header(TrueMotion1Context *s) { int i; int width_shift = 0; int new_pix_fmt; struct frame_header header; uint8_t header_buffer[128]; /* logical maximum size of the header */ const uint8_t *sel_vector_table; header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f; if (s->buf[0] < 0x10) { av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]); return -1; } /* unscramble the header bytes with a XOR operation */ memset(header_buffer, 0, 128); for (i = 1; i < header.header_size; i++) header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1]; header.compression = header_buffer[0]; header.deltaset = header_buffer[1]; header.vectable = header_buffer[2]; header.ysize = AV_RL16(&header_buffer[3]); header.xsize = AV_RL16(&header_buffer[5]); header.checksum = AV_RL16(&header_buffer[7]); header.version = header_buffer[9]; header.header_type = header_buffer[10]; header.flags = header_buffer[11]; header.control = header_buffer[12]; /* Version 2 */ if (header.version >= 2) { if (header.header_type > 3) { av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type); return -1; } else if ((header.header_type == 2) || (header.header_type == 3)) { s->flags = header.flags; if (!(s->flags & FLAG_INTERFRAME)) s->flags |= FLAG_KEYFRAME; } else s->flags = FLAG_KEYFRAME; } else /* Version 1 */ s->flags = FLAG_KEYFRAME; if (s->flags & FLAG_SPRITE) { av_log_ask_for_sample(s->avctx, "SPRITE frame found.\n"); /* FIXME header.width, height, xoffset and yoffset aren't initialized */ #if 0 s->w = header.width; s->h = header.height; s->x = header.xoffset; s->y = header.yoffset; #else return -1; #endif } else { s->w = header.xsize; s->h = header.ysize; if (header.header_type < 2) { if ((s->w < 213) && (s->h >= 176)) { s->flags |= FLAG_INTERPOLATED; av_log_ask_for_sample(s->avctx, "INTERPOLATION selected.\n"); } } } if (header.compression >= 17) { av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression); return -1; } if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable)) select_delta_tables(s, header.deltaset); if ((header.compression & 1) && header.header_type) sel_vector_table = pc_tbl2; else { if (header.vectable > 0 && header.vectable < 4) sel_vector_table = tables[header.vectable - 1]; else { av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable); return -1; } } if (compression_types[header.compression].algorithm == ALGO_RGB24H) { new_pix_fmt = PIX_FMT_RGB32; width_shift = 1; } else new_pix_fmt = PIX_FMT_RGB555; // RGB565 is supported as well s->w >>= width_shift; if (av_image_check_size(s->w, s->h, 0, s->avctx) < 0) return -1; if (s->w != s->avctx->width || s->h != s->avctx->height || new_pix_fmt != s->avctx->pix_fmt) { if (s->frame.data[0]) s->avctx->release_buffer(s->avctx, &s->frame); s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 }; s->avctx->pix_fmt = new_pix_fmt; avcodec_set_dimensions(s->avctx, s->w, s->h); av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int)); } /* There is 1 change bit per 4 pixels, so each change byte represents * 32 pixels; divide width by 4 to obtain the number of change bits and * then round up to the nearest byte. */ s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3; if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable)) { if (compression_types[header.compression].algorithm == ALGO_RGB24H) gen_vector_table24(s, sel_vector_table); else if (s->avctx->pix_fmt == PIX_FMT_RGB555) gen_vector_table15(s, sel_vector_table); else gen_vector_table16(s, sel_vector_table); } /* set up pointers to the other key data chunks */ s->mb_change_bits = s->buf + header.header_size; if (s->flags & FLAG_KEYFRAME) { /* no change bits specified for a keyframe; only index bytes */ s->index_stream = s->mb_change_bits; } else { /* one change bit per 4x4 block */ s->index_stream = s->mb_change_bits + (s->mb_change_bits_row_size * (s->avctx->height >> 2)); } s->index_stream_size = s->size - (s->index_stream - s->buf); s->last_deltaset = header.deltaset; s->last_vectable = header.vectable; s->compression = header.compression; s->block_width = compression_types[header.compression].block_width; s->block_height = compression_types[header.compression].block_height; s->block_type = compression_types[header.compression].block_type; if (s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n", s->last_deltaset, s->last_vectable, s->compression, s->block_width, s->block_height, s->block_type, s->flags & FLAG_KEYFRAME ? " KEY" : "", s->flags & FLAG_INTERFRAME ? " INTER" : "", s->flags & FLAG_SPRITE ? " SPRITE" : "", s->flags & FLAG_INTERPOLATED ? " INTERPOL" : ""); return header.header_size; }
static int read_header(AVFormatContext *s) { BRSTMDemuxContext *b = s->priv_data; int bom, major, minor, codec, chunk; int64_t pos, h1offset, toffset; uint32_t size, start, asize; AVStream *st; int ret = AVERROR_EOF; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; avio_skip(s->pb, 4); bom = avio_rb16(s->pb); if (bom != 0xFEFF && bom != 0xFFFE) { av_log(s, AV_LOG_ERROR, "invalid byte order: %X\n", bom); return AVERROR_INVALIDDATA; } if (bom == 0xFFFE) { av_log_ask_for_sample(s, "unsupported byte order"); return AVERROR_PATCHWELCOME; } major = avio_r8(s->pb); minor = avio_r8(s->pb); avio_skip(s->pb, 4); // size of file size = avio_rb16(s->pb); if (size < 14) return AVERROR_INVALIDDATA; avio_skip(s->pb, size - 14); pos = avio_tell(s->pb); if (avio_rl32(s->pb) != MKTAG('H','E','A','D')) return AVERROR_INVALIDDATA; size = avio_rb32(s->pb); if (size < 256) return AVERROR_INVALIDDATA; avio_skip(s->pb, 4); // unknown h1offset = avio_rb32(s->pb); if (h1offset > size) return AVERROR_INVALIDDATA; avio_skip(s->pb, 12); toffset = avio_rb32(s->pb) + 16LL; if (toffset > size) return AVERROR_INVALIDDATA; avio_skip(s->pb, pos + h1offset + 8 - avio_tell(s->pb)); codec = avio_r8(s->pb); switch (codec) { case 0: codec = AV_CODEC_ID_PCM_S8_PLANAR; break; case 1: codec = AV_CODEC_ID_PCM_S16BE_PLANAR; break; case 2: codec = AV_CODEC_ID_ADPCM_THP; break; default: av_log_ask_for_sample(s, "unsupported codec: %d", codec); return AVERROR_PATCHWELCOME; } avio_skip(s->pb, 1); // loop flag st->codec->codec_id = codec; st->codec->channels = avio_r8(s->pb); if (!st->codec->channels) return AVERROR_INVALIDDATA; avio_skip(s->pb, 1); // padding st->codec->sample_rate = avio_rb16(s->pb); if (!st->codec->sample_rate) return AVERROR_INVALIDDATA; avio_skip(s->pb, 2); // padding avio_skip(s->pb, 4); // loop start sample st->start_time = 0; st->duration = avio_rb32(s->pb); avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); start = avio_rb32(s->pb); b->current_block = 0; b->block_count = avio_rb32(s->pb); if (b->block_count > UINT16_MAX) { av_log(s, AV_LOG_WARNING, "too many blocks: %u\n", b->block_count); return AVERROR_INVALIDDATA; } b->block_size = avio_rb32(s->pb); if (b->block_size > UINT16_MAX / st->codec->channels) return AVERROR_INVALIDDATA; b->block_size *= st->codec->channels; b->samples_per_block = avio_rb32(s->pb); b->last_block_used_bytes = avio_rb32(s->pb); if (b->last_block_used_bytes > UINT16_MAX / st->codec->channels) return AVERROR_INVALIDDATA; b->last_block_used_bytes *= st->codec->channels; avio_skip(s->pb, 4); // last block samples avio_skip(s->pb, 4); // last block size if (codec == AV_CODEC_ID_ADPCM_THP) { int ch; avio_skip(s->pb, pos + toffset - avio_tell(s->pb)); toffset = avio_rb32(s->pb) + 16LL; if (toffset > size) return AVERROR_INVALIDDATA; avio_skip(s->pb, pos + toffset - avio_tell(s->pb)); b->table = av_mallocz(32 * st->codec->channels); if (!b->table) return AVERROR(ENOMEM); for (ch = 0; ch < st->codec->channels; ch++) { if (avio_read(s->pb, b->table + ch * 32, 32) != 32) { ret = AVERROR_INVALIDDATA; goto fail; } avio_skip(s->pb, 24); } } if (size < (avio_tell(s->pb) - pos)) { ret = AVERROR_INVALIDDATA; goto fail; } avio_skip(s->pb, size - (avio_tell(s->pb) - pos)); while (!url_feof(s->pb)) { chunk = avio_rl32(s->pb); size = avio_rb32(s->pb); if (size < 8) { ret = AVERROR_INVALIDDATA; goto fail; } size -= 8; switch (chunk) { case MKTAG('A','D','P','C'): if (codec != AV_CODEC_ID_ADPCM_THP) goto skip; asize = b->block_count * st->codec->channels * 4; if (size < asize) { ret = AVERROR_INVALIDDATA; goto fail; } if (b->adpc) { av_log(s, AV_LOG_WARNING, "skipping additonal ADPC chunk\n"); goto skip; } else { b->adpc = av_mallocz(asize); if (!b->adpc) { ret = AVERROR(ENOMEM); goto fail; } avio_read(s->pb, b->adpc, asize); avio_skip(s->pb, size - asize); } break; case MKTAG('D','A','T','A'): if ((start < avio_tell(s->pb)) || (!b->adpc && codec == AV_CODEC_ID_ADPCM_THP)) { ret = AVERROR_INVALIDDATA; goto fail; } avio_skip(s->pb, start - avio_tell(s->pb)); return 0; default: av_log(s, AV_LOG_WARNING, "skipping unknown chunk: %X\n", chunk); skip: avio_skip(s->pb, size); } } fail: read_close(s); return ret; }
/** * Cook initialization * * @param avctx pointer to the AVCodecContext */ static av_cold int cook_decode_init(AVCodecContext *avctx) { COOKContext *q = avctx->priv_data; const uint8_t *edata_ptr = avctx->extradata; const uint8_t *edata_ptr_end = edata_ptr + avctx->extradata_size; int extradata_size = avctx->extradata_size; int s = 0; unsigned int channel_mask = 0; int samples_per_frame = 0; int ret; q->avctx = avctx; /* Take care of the codec specific extradata. */ if (extradata_size <= 0) { av_log(avctx, AV_LOG_ERROR, "Necessary extradata missing!\n"); return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_DEBUG, "codecdata_length=%d\n", avctx->extradata_size); /* Take data from the AVCodecContext (RM container). */ if (!avctx->channels) { av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); return AVERROR_INVALIDDATA; } /* Initialize RNG. */ av_lfg_init(&q->random_state, 0); ff_dsputil_init(&q->dsp, avctx); while (edata_ptr < edata_ptr_end) { /* 8 for mono, 16 for stereo, ? for multichannel Swap to right endianness so we don't need to care later on. */ if (extradata_size >= 8) { q->subpacket[s].cookversion = bytestream_get_be32(&edata_ptr); samples_per_frame = bytestream_get_be16(&edata_ptr); q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr); extradata_size -= 8; } if (extradata_size >= 8) { bytestream_get_be32(&edata_ptr); // Unknown unused q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr); q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr); extradata_size -= 8; } /* Initialize extradata related variables. */ q->subpacket[s].samples_per_channel = samples_per_frame / avctx->channels; q->subpacket[s].bits_per_subpacket = avctx->block_align * 8; /* Initialize default data states. */ q->subpacket[s].log2_numvector_size = 5; q->subpacket[s].total_subbands = q->subpacket[s].subbands; q->subpacket[s].num_channels = 1; /* Initialize version-dependent variables */ av_log(avctx, AV_LOG_DEBUG, "subpacket[%i].cookversion=%x\n", s, q->subpacket[s].cookversion); q->subpacket[s].joint_stereo = 0; switch (q->subpacket[s].cookversion) { case MONO: if (avctx->channels != 1) { av_log_ask_for_sample(avctx, "Container channels != 1.\n"); return AVERROR_PATCHWELCOME; } av_log(avctx, AV_LOG_DEBUG, "MONO\n"); break; case STEREO: if (avctx->channels != 1) { q->subpacket[s].bits_per_subpdiv = 1; q->subpacket[s].num_channels = 2; } av_log(avctx, AV_LOG_DEBUG, "STEREO\n"); break; case JOINT_STEREO: if (avctx->channels != 2) { av_log_ask_for_sample(avctx, "Container channels != 2.\n"); return AVERROR_PATCHWELCOME; } av_log(avctx, AV_LOG_DEBUG, "JOINT_STEREO\n"); if (avctx->extradata_size >= 16) { q->subpacket[s].total_subbands = q->subpacket[s].subbands + q->subpacket[s].js_subband_start; q->subpacket[s].joint_stereo = 1; q->subpacket[s].num_channels = 2; } if (q->subpacket[s].samples_per_channel > 256) { q->subpacket[s].log2_numvector_size = 6; } if (q->subpacket[s].samples_per_channel > 512) { q->subpacket[s].log2_numvector_size = 7; } break; case MC_COOK: av_log(avctx, AV_LOG_DEBUG, "MULTI_CHANNEL\n"); if (extradata_size >= 4) channel_mask |= q->subpacket[s].channel_mask = bytestream_get_be32(&edata_ptr); if (av_get_channel_layout_nb_channels(q->subpacket[s].channel_mask) > 1) { q->subpacket[s].total_subbands = q->subpacket[s].subbands + q->subpacket[s].js_subband_start; q->subpacket[s].joint_stereo = 1; q->subpacket[s].num_channels = 2; q->subpacket[s].samples_per_channel = samples_per_frame >> 1; if (q->subpacket[s].samples_per_channel > 256) { q->subpacket[s].log2_numvector_size = 6; } if (q->subpacket[s].samples_per_channel > 512) { q->subpacket[s].log2_numvector_size = 7; } } else q->subpacket[s].samples_per_channel = samples_per_frame; break; default: av_log_ask_for_sample(avctx, "Unknown Cook version.\n"); return AVERROR_PATCHWELCOME; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { AnmContext *s = avctx->priv_data; const uint8_t *buf = avpkt->data; const int buf_size = avpkt->size; const uint8_t *buf_end = buf + buf_size; uint8_t *dst, *dst_end; int count; if(avctx->reget_buffer(avctx, &s->frame) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } dst = s->frame.data[0]; dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height; if (buf[0] != 0x42) { av_log_ask_for_sample(avctx, "unknown record type\n"); return buf_size; } if (buf[1]) { av_log_ask_for_sample(avctx, "padding bytes not supported\n"); return buf_size; } buf += 4; s->x = 0; do { /* if statements are ordered by probability */ #define OP(buf, pixel, count) \ op(&dst, dst_end, (buf), buf_end, (pixel), (count), &s->x, avctx->width, s->frame.linesize[0]) int type = bytestream_get_byte(&buf); count = type & 0x7F; type >>= 7; if (count) { if (OP(type ? NULL : &buf, -1, count)) break; } else if (!type) { int pixel; count = bytestream_get_byte(&buf); /* count==0 gives nop */ pixel = bytestream_get_byte(&buf); if (OP(NULL, pixel, count)) break; } else { int pixel; type = bytestream_get_le16(&buf); count = type & 0x3FFF; type >>= 14; if (!count) { if (type == 0) break; // stop if (type == 2) { av_log_ask_for_sample(avctx, "unknown opcode"); return AVERROR_INVALIDDATA; } continue; } pixel = type == 3 ? bytestream_get_byte(&buf) : -1; if (type == 1) count += 0x4000; if (OP(type == 2 ? &buf : NULL, pixel, count)) break; } } while (buf + 1 < buf_end); *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; return buf_size; }
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; 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; avio_skip(pb, 8); // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content st->codec->codec_tag = avio_rl32(pb); while(!url_feof(pb)) { uint64_t orig_pos; int res; const char *metadata_tag = NULL; chunk_id = avio_rl32(pb); data_size = avio_rb32(pb); orig_pos = avio_tell(pb); switch(chunk_id) { case ID_VHDR: st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (data_size < 14) return AVERROR_INVALIDDATA; avio_skip(pb, 12); st->codec->sample_rate = avio_rb16(pb); if (data_size >= 16) { avio_skip(pb, 1); iff->svx8_compression = avio_r8(pb); } break; case ID_ABIT: case ID_BODY: case ID_DBOD: iff->body_pos = avio_tell(pb); iff->body_size = data_size; break; case ID_CHAN: if (data_size < 4) return AVERROR_INVALIDDATA; st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2; break; case ID_CAMG: if (data_size < 4) return AVERROR_INVALIDDATA; screenmode = avio_rb32(pb); break; case ID_CMAP: 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: iff->bitmap_compression = -1; 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 = PIX_FMT_RGB24; else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba))) st->codec->pix_fmt = PIX_FMT_RGBA; 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); if (iff->bitmap_compression != 0) { av_log(s, AV_LOG_ERROR, "compression %i not supported\n", iff->bitmap_compression); return AVERROR_PATCHWELCOME; } 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_ANNO: case ID_TEXT: metadata_tag = "comment"; break; case ID_AUTH: metadata_tag = "artist"; break; case ID_COPYRIGHT: metadata_tag = "copyright"; break; case ID_NAME: metadata_tag = "title"; break; } if (metadata_tag) { if ((res = get_metadata(s, metadata_tag, data_size)) < 0) { av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!", metadata_tag); return res; } } avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1)); } avio_seek(pb, iff->body_pos, SEEK_SET); switch(st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); 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 = iff->svx8_compression == COMP_NONE ? 8 : 4; 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); } 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); switch (iff->bitmap_compression) { case BITMAP_RAW: st->codec->codec_id = AV_CODEC_ID_IFF_ILBM; break; case BITMAP_BYTERUN1: st->codec->codec_id = AV_CODEC_ID_IFF_BYTERUN1; break; default: av_log(s, AV_LOG_ERROR, "Unknown bitmap compression method '%d'\n", iff->bitmap_compression); return AVERROR_INVALIDDATA; } break; default: return -1; } return 0; }
static int xwma_read_header(AVFormatContext *s, AVFormatParameters *ap) { int64_t size, av_uninit(data_size); int ret; uint32_t dpds_table_size = 0; uint32_t *dpds_table = 0; unsigned int tag; AVIOContext *pb = s->pb; AVStream *st; XWMAContext *xwma = s->priv_data; int i; /* The following code is mostly copied from wav.c, with some * minor alterations. */ /* check RIFF header */ tag = avio_rl32(pb); if (tag != MKTAG('R', 'I', 'F', 'F')) return -1; avio_rl32(pb); /* file size */ tag = avio_rl32(pb); if (tag != MKTAG('X', 'W', 'M', 'A')) return -1; /* parse fmt header */ tag = avio_rl32(pb); if (tag != MKTAG('f', 'm', 't', ' ')) return -1; size = avio_rl32(pb); st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); ret = ff_get_wav_header(pb, st->codec, size); if (ret < 0) return ret; st->need_parsing = AVSTREAM_PARSE_NONE; /* All xWMA files I have seen contained WMAv2 data. If there are files * using WMA Pro or some other codec, then we need to figure out the right * extradata for that. Thus, ask the user for feedback, but try to go on * anyway. */ if (st->codec->codec_id != CODEC_ID_WMAV2) { av_log(s, AV_LOG_WARNING, "unexpected codec (tag 0x04%x; id %d)\n", st->codec->codec_tag, st->codec->codec_id); av_log_ask_for_sample(s, NULL); } else { /* In all xWMA files I have seen, there is no extradata. But the WMA * codecs require extradata, so we provide our own fake extradata. * * First, check that there really was no extradata in the header. If * there was, then try to use it, after asking the user to provide a * sample of this unusual file. */ if (st->codec->extradata_size != 0) { /* Surprise, surprise: We *did* get some extradata. No idea * if it will work, but just go on and try it, after asking * the user for a sample. */ av_log(s, AV_LOG_WARNING, "unexpected extradata (%d bytes)\n", st->codec->extradata_size); av_log_ask_for_sample(s, NULL); } else { st->codec->extradata_size = 6; st->codec->extradata = av_mallocz(6 + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); /* setup extradata with our experimentally obtained value */ st->codec->extradata[4] = 31; } } /* set the sample rate */ av_set_pts_info(st, 64, 1, st->codec->sample_rate); /* parse the remaining RIFF chunks */ for (;;) { if (pb->eof_reached) return -1; /* read next chunk tag */ tag = avio_rl32(pb); size = avio_rl32(pb); if (tag == MKTAG('d', 'a', 't', 'a')) { /* We assume that the data chunk comes last. */ break; } else if (tag == MKTAG('d','p','d','s')) { /* Quoting the MSDN xWMA docs on the dpds chunk: "Contains the * decoded packet cumulative data size array, each element is the * number of bytes accumulated after the corresponding xWMA packet * is decoded in order." * * Each packet has size equal to st->codec->block_align, which in * all cases I saw so far was always 2230. Thus, we can use the * dpds data to compute a seeking index. */ /* Error out if there is more than one dpds chunk. */ if (dpds_table) { av_log(s, AV_LOG_ERROR, "two dpds chunks present\n"); return -1; } /* Compute the number of entries in the dpds chunk. */ if (size & 3) { /* Size should be divisible by four */ av_log(s, AV_LOG_WARNING, "dpds chunk size %"PRId64" not divisible by 4\n", size); } dpds_table_size = size / 4; if (dpds_table_size == 0 || dpds_table_size >= INT_MAX / 4) { av_log(s, AV_LOG_ERROR, "dpds chunk size %"PRId64" invalid\n", size); return -1; } /* Allocate some temporary storage to keep the dpds data around. * for processing later on. */ dpds_table = av_malloc(dpds_table_size * sizeof(uint32_t)); if (!dpds_table) { return AVERROR(ENOMEM); } for (i = 0; i < dpds_table_size; ++i) { dpds_table[i] = avio_rl32(pb); size -= 4; } } avio_skip(pb, size); } /* Determine overall data length */ if (size < 0) return -1; if (!size) { xwma->data_end = INT64_MAX; } else xwma->data_end = avio_tell(pb) + size; if (dpds_table && dpds_table_size) { int64_t cur_pos; const uint32_t bytes_per_sample = (st->codec->channels * st->codec->bits_per_coded_sample) >> 3; /* Estimate the duration from the total number of output bytes. */ const uint64_t total_decoded_bytes = dpds_table[dpds_table_size - 1]; st->duration = total_decoded_bytes / bytes_per_sample; /* Use the dpds data to build a seek table. We can only do this after * we know the offset to the data chunk, as we need that to determine * the actual offset to each input block. * Note: If we allowed ourselves to assume that the data chunk always * follows immediately after the dpds block, we could of course guess * the data block's start offset already while reading the dpds chunk. * I decided against that, just in case other chunks ever are * discovered. */ cur_pos = avio_tell(pb); for (i = 0; i < dpds_table_size; ++i) { /* From the number of output bytes that would accumulate in the * output buffer after decoding the first (i+1) packets, we compute * an offset / timestamp pair. */ av_add_index_entry(st, cur_pos + (i+1) * st->codec->block_align, /* pos */ dpds_table[i] / bytes_per_sample, /* timestamp */ st->codec->block_align, /* size */ 0, /* duration */ AVINDEX_KEYFRAME); } } else if (st->codec->bit_rate) {