void av_md5_final(AVMD5 *ctx, uint8_t *dst) { int i; uint64_t finalcount = av_le2ne64(ctx->len << 3); av_md5_update(ctx, "\200", 1); while ((ctx->len & 63) != 56) av_md5_update(ctx, "", 1); av_md5_update(ctx, (uint8_t *)&finalcount, 8); for (i = 0; i < 4; i++) AV_WL32(dst + 4*i, ctx->ABCD[3 - i]); }
void av_cold av_lfg_init(AVLFG *c, unsigned int seed){ uint8_t tmp[16]={0}; int i; for(i=8; i<64; i+=4){ AV_WL32(tmp, seed); tmp[4]=i; av_md5_sum(tmp, tmp, 16); c->state[i ]= AV_RL32(tmp); c->state[i+1]= AV_RL32(tmp+4); c->state[i+2]= AV_RL32(tmp+8); c->state[i+3]= AV_RL32(tmp+12); } c->index=0; }
static int read_packet(AVFormatContext *s, AVPacket *pkt) { JVDemuxContext *jv = s->priv_data; AVIOContext *pb = s->pb; AVStream *ast = s->streams[0]; while (!s->pb->eof_reached && jv->pts < ast->nb_index_entries) { const AVIndexEntry *e = ast->index_entries + jv->pts; const JVFrame *jvf = jv->frames + jv->pts; switch(jv->state) { case JV_AUDIO: jv->state++; if (jvf->audio_size ) { if (av_get_packet(s->pb, pkt, jvf->audio_size) < 0) return AVERROR(ENOMEM); pkt->stream_index = 0; pkt->pts = e->timestamp; pkt->flags |= PKT_FLAG_KEY; return 0; } case JV_VIDEO: jv->state++; if (jvf->video_size || jvf->palette_size) { int size = jvf->video_size + jvf->palette_size; if (av_new_packet(pkt, size + JV_PREAMBLE_SIZE)) return AVERROR(ENOMEM); AV_WL32(pkt->data, jvf->video_size); pkt->data[4] = jvf->video_type; if (avio_read(pb, pkt->data + JV_PREAMBLE_SIZE, size) < 0) return AVERROR(EIO); pkt->size = size + JV_PREAMBLE_SIZE; pkt->stream_index = 1; pkt->pts = jv->pts; if (jvf->video_type != 1) pkt->flags |= PKT_FLAG_KEY; return 0; } case JV_PADDING: avio_skip(pb, FFMAX(e->size - jvf->audio_size - jvf->video_size - jvf->palette_size, 0)); jv->state = JV_AUDIO; jv->pts++; } } return AVERROR(EIO); }
/** Send a prepared MMST command packet. */ static int send_command_packet(MMSContext *mms) { int len= mms->write_out_ptr - mms->out_buffer; int exact_length = (len + 7) & ~7; int first_length= exact_length - 16; int len8= first_length/8; int write_result; // update packet length fields. AV_WL32(mms->out_buffer + 8, first_length); AV_WL32(mms->out_buffer + 16, len8); AV_WL32(mms->out_buffer + 32, len8-2); memset(mms->write_out_ptr, 0, exact_length - len); // write it out. write_result= url_write(mms->mms_hd, mms->out_buffer, exact_length); if(write_result != exact_length) { dprintf(NULL, "url_write returned: %d != %d\n", write_result, exact_length); return AVERROR_IO; } return 0; }
static int encode_init(AVCodecContext * avctx){ WMACodecContext *s = avctx->priv_data; int i, flags1, flags2; uint8_t *extradata; s->avctx = avctx; if(avctx->channels > MAX_CHANNELS) return -1; if(avctx->bit_rate < 24*1000) return -1; /* extract flag infos */ flags1 = 0; flags2 = 1; if (avctx->codec->id == CODEC_ID_WMAV1) { extradata= av_malloc(4); avctx->extradata_size= 4; AV_WL16(extradata, flags1); AV_WL16(extradata+2, flags2); } else if (avctx->codec->id == CODEC_ID_WMAV2) { extradata= av_mallocz(10); avctx->extradata_size= 10; AV_WL32(extradata, flags1); AV_WL16(extradata+4, flags2); }else assert(0); avctx->extradata= extradata; s->use_exp_vlc = flags2 & 0x0001; s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; ff_wma_init(avctx, flags2); /* init MDCT */ for(i = 0; i < s->nb_block_sizes; i++) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0); avctx->block_align= s->block_align= avctx->bit_rate*(int64_t)s->frame_len / (avctx->sample_rate*8); //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", s->block_align, avctx->bit_rate, s->frame_len, avctx->sample_rate); avctx->frame_size= s->frame_len; return 0; }
static void rgbpack_fields(void *ctx_, uint8_t *src[AVS_MAX_COMPONENTS], int sstrides[AVS_MAX_COMPONENTS], uint8_t *dst[AVS_MAX_COMPONENTS], int dstrides[AVS_MAX_COMPONENTS], int w, int h) { RGBPackContext *ctx = ctx_; uint8_t *rgb[3], *dest; unsigned val; int i, j, c; rgb[0] = src[0]; rgb[1] = src[1]; rgb[2] = src[2]; dest = dst[0]; for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { val = 0; if (ctx->inbpp <= 8) { for (c = 0; c < 3; c++) val |= rgb[c][i] << ctx->shift[c]; } else { for (c = 0; c < 3; c++) val |= AV_RN16(rgb[c] + i * 2) << ctx->shift[c]; } switch (ctx->step) { case 1: dest[i] = val; break; case 2: if (ctx->be) AV_WB16(dest + i * 2, val); else AV_WL16(dest + i * 2, val); break; case 4: if (ctx->be) AV_WB32(dest + i * 4, val); else AV_WL32(dest + i * 4, val); break; } } for (c = 0; c < 3; c++) rgb[c] += sstrides[0]; dest += dstrides[0]; } }
int ff_read_riff_info(AVFormatContext *s, int64_t size) { int64_t start, end, cur; AVIOContext *pb = s->pb; start = avio_tell(pb); end = start + size; while ((cur = avio_tell(pb)) >= 0 && cur <= end - 8 /* = tag + size */) { uint32_t chunk_code; int64_t chunk_size; char key[5] = {0}; char *value; chunk_code = avio_rl32(pb); chunk_size = avio_rl32(pb); if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) { av_log(s, AV_LOG_ERROR, "too big INFO subchunk\n"); return AVERROR_INVALIDDATA; } chunk_size += (chunk_size & 1); value = av_malloc(chunk_size + 1); if (!value) { av_log(s, AV_LOG_ERROR, "out of memory, unable to read INFO tag\n"); return AVERROR(ENOMEM); } AV_WL32(key, chunk_code); if (avio_read(pb, value, chunk_size) != chunk_size) { av_freep(key); av_freep(value); av_log(s, AV_LOG_ERROR, "premature end of file while reading INFO tag\n"); return AVERROR_INVALIDDATA; } value[chunk_size] = 0; av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); } return 0; }
static int dxv_decompress_dxt1(AVCodecContext *avctx) { DXVContext *ctx = avctx->priv_data; GetByteContext *gbc = &ctx->gbc; uint32_t value, prev, op; int idx = 0, state = 0; int pos = 2; /* Copy the first two elements */ AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc)); AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc)); /* Process input until the whole texture has been filled */ while (pos < ctx->tex_size / 4) { CHECKPOINT(2); /* Copy two elements from a previous offset or from the input buffer */ if (op) { prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; } else { CHECKPOINT(2); if (op) prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); else prev = bytestream2_get_le32(gbc); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; CHECKPOINT(2); if (op) prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); else prev = bytestream2_get_le32(gbc); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; } } return 0; }
static int v410_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) { uint8_t *dst; uint16_t *y, *u, *v; uint32_t val; int i, j, ret; if ((ret = ff_alloc_packet(pkt, avctx->width * avctx->height * 4)) < 0) { av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); return ret; } dst = pkt->data; avctx->coded_frame->reference = 0; avctx->coded_frame->key_frame = 1; avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; y = (uint16_t *)pic->data[0]; u = (uint16_t *)pic->data[1]; v = (uint16_t *)pic->data[2]; for (i = 0; i < avctx->height; i++) { for (j = 0; j < avctx->width; j++) { val = u[j] << 2; val |= y[j] << 12; val |= (uint32_t) v[j] << 22; AV_WL32(dst, val); dst += 4; } y += pic->linesize[0] >> 1; u += pic->linesize[1] >> 1; v += pic->linesize[2] >> 1; } pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; }
static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color) { const uint8_t *font; int font_height; int i; font = avpriv_cga_font, font_height = 8; for (i = 0; txt[i]; i++) { int char_y, mask; uint8_t *p = pic->data[0] + y * pic->linesize[0] + (x + i * 8) * 4; for (char_y = 0; char_y < font_height; char_y++) { for (mask = 0x80; mask; mask >>= 1) { if (font[txt[i] * font_height + char_y] & mask) AV_WL32(p, color); p += 4; } p += pic->linesize[0] - 8 * 4; } } }
int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type) { uint8_t *side_data; int side_data_size; int i; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size); if (!side_data) { side_data_size = 4+4+8*error_count; side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, side_data_size); } if (!side_data || side_data_size < 4+4+8*error_count) return AVERROR(ENOMEM); AV_WL32(side_data , quality ); side_data[4] = pict_type; side_data[5] = error_count; for (i = 0; i<error_count; i++) AV_WL64(side_data+8 + 8*i , error[i]); return 0; }
static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, AVStream *st, RMStream *ast, int read_all) { char buf[256]; uint32_t version; int ret; /* ra type header */ version = avio_rb16(pb); /* version */ if (version == 3) { unsigned bytes_per_minute; int header_size = avio_rb16(pb); int64_t startpos = avio_tell(pb); avio_skip(pb, 8); bytes_per_minute = avio_rb16(pb); avio_skip(pb, 4); rm_read_metadata(s, pb, 0); if ((startpos + header_size) >= avio_tell(pb) + 2) { // fourcc (should always be "lpcJ") avio_r8(pb); get_str8(pb, buf, sizeof(buf)); } // Skip extra header crap (this should never happen) if ((startpos + header_size) > avio_tell(pb)) avio_skip(pb, header_size + startpos - avio_tell(pb)); if (bytes_per_minute) st->codec->bit_rate = 8LL * bytes_per_minute / 60; st->codec->sample_rate = 8000; st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_RA_144; ast->deint_id = DEINT_ID_INT0; } else { int flavor, sub_packet_h, coded_framesize, sub_packet_size; int codecdata_length; unsigned bytes_per_minute; /* old version (4) */ avio_skip(pb, 2); /* unused */ avio_rb32(pb); /* .ra4 */ avio_rb32(pb); /* data size */ avio_rb16(pb); /* version2 */ avio_rb32(pb); /* header size */ flavor= avio_rb16(pb); /* add codec info / flavor */ ast->coded_framesize = coded_framesize = avio_rb32(pb); /* coded frame size */ avio_rb32(pb); /* ??? */ bytes_per_minute = avio_rb32(pb); if (version == 4) { if (bytes_per_minute) st->codec->bit_rate = 8LL * bytes_per_minute / 60; } avio_rb32(pb); /* ??? */ ast->sub_packet_h = sub_packet_h = avio_rb16(pb); /* 1 */ st->codec->block_align= avio_rb16(pb); /* frame size */ ast->sub_packet_size = sub_packet_size = avio_rb16(pb); /* sub packet size */ avio_rb16(pb); /* ??? */ if (version == 5) { avio_rb16(pb); avio_rb16(pb); avio_rb16(pb); } st->codec->sample_rate = avio_rb16(pb); avio_rb32(pb); st->codec->channels = avio_rb16(pb); if (version == 5) { ast->deint_id = avio_rl32(pb); avio_read(pb, buf, 4); buf[4] = 0; } else { AV_WL32(buf, 0); get_str8(pb, buf, sizeof(buf)); /* desc */ ast->deint_id = AV_RL32(buf); get_str8(pb, buf, sizeof(buf)); /* desc */ } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = AV_RL32(buf); st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags, st->codec->codec_tag); switch (st->codec->codec_id) { case AV_CODEC_ID_AC3: st->need_parsing = AVSTREAM_PARSE_FULL; break; case AV_CODEC_ID_RA_288: st->codec->extradata_size= 0; ast->audio_framesize = st->codec->block_align; st->codec->block_align = coded_framesize; break; case AV_CODEC_ID_COOK: st->need_parsing = AVSTREAM_PARSE_HEADERS; case AV_CODEC_ID_ATRAC3: case AV_CODEC_ID_SIPR: if (read_all) { codecdata_length = 0; } else { avio_rb16(pb); avio_r8(pb); if (version == 5) avio_r8(pb); codecdata_length = avio_rb32(pb); if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); return -1; } } ast->audio_framesize = st->codec->block_align; if (st->codec->codec_id == AV_CODEC_ID_SIPR) { if (flavor > 3) { av_log(s, AV_LOG_ERROR, "bad SIPR file flavor %d\n", flavor); return -1; } st->codec->block_align = ff_sipr_subpk_size[flavor]; } else { if(sub_packet_size <= 0){ av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n"); return -1; } st->codec->block_align = ast->sub_packet_size; } if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0) return ret; break; case AV_CODEC_ID_AAC: avio_rb16(pb); avio_r8(pb); if (version == 5) avio_r8(pb); codecdata_length = avio_rb32(pb); if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); return -1; } if (codecdata_length >= 1) { avio_r8(pb); if ((ret = rm_read_extradata(pb, st->codec, codecdata_length - 1)) < 0) return ret; } break; } switch (ast->deint_id) { case DEINT_ID_INT4: if (ast->coded_framesize > ast->audio_framesize || sub_packet_h <= 1 || ast->coded_framesize * sub_packet_h > (2 + (sub_packet_h & 1)) * ast->audio_framesize) return AVERROR_INVALIDDATA; if (ast->coded_framesize * sub_packet_h != 2*ast->audio_framesize) { avpriv_request_sample(s, "mismatching interleaver parameters"); return AVERROR_INVALIDDATA; } break; case DEINT_ID_GENR: if (ast->sub_packet_size <= 0 || ast->sub_packet_size > ast->audio_framesize) return AVERROR_INVALIDDATA; if (ast->audio_framesize % ast->sub_packet_size) return AVERROR_INVALIDDATA; break; case DEINT_ID_SIPR: case DEINT_ID_INT0: case DEINT_ID_VBRS: case DEINT_ID_VBRF: break; default: av_log(s, AV_LOG_ERROR ,"Unknown interleaver %"PRIX32"\n", ast->deint_id); return AVERROR_INVALIDDATA; } if (ast->deint_id == DEINT_ID_INT4 || ast->deint_id == DEINT_ID_GENR || ast->deint_id == DEINT_ID_SIPR) { if (st->codec->block_align <= 0 || ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX || ast->audio_framesize * sub_packet_h < st->codec->block_align) return AVERROR_INVALIDDATA; if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0) return AVERROR(ENOMEM); } if (read_all) { avio_r8(pb); avio_r8(pb); avio_r8(pb); rm_read_metadata(s, pb, 0); } } return 0; }
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb, RMDemuxContext *rm, RMStream *vst, AVPacket *pkt, int len, int *pseq, int64_t *timestamp) { int hdr; int seq = 0, pic_num = 0, len2 = 0, pos = 0; //init to silcense compiler warning int type; int ret; hdr = avio_r8(pb); len--; type = hdr >> 6; if(type != 3){ // not frame as a part of packet seq = avio_r8(pb); len--; } if(type != 1){ // not whole frame len2 = get_num(pb, &len); pos = get_num(pb, &len); pic_num = avio_r8(pb); len--; } if(len<0) { av_log(s, AV_LOG_ERROR, "Insufficient data\n"); return -1; } rm->remaining_len = len; if(type&1){ // frame, not slice if(type == 3){ // frame as a part of packet len= len2; *timestamp = pos; } if(rm->remaining_len < len) { av_log(s, AV_LOG_ERROR, "Insufficient remaining len\n"); return -1; } rm->remaining_len -= len; if(av_new_packet(pkt, len + 9) < 0) return AVERROR(EIO); pkt->data[0] = 0; AV_WL32(pkt->data + 1, 1); AV_WL32(pkt->data + 5, 0); if ((ret = avio_read(pb, pkt->data + 9, len)) != len) { av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Failed to read %d bytes\n", len); return ret < 0 ? ret : AVERROR(EIO); } return 0; } //now we have to deal with single slice *pseq = seq; if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ if (len2 > ffio_limit(pb, len2)) { av_log(s, AV_LOG_ERROR, "Impossibly sized packet\n"); return AVERROR_INVALIDDATA; } vst->slices = ((hdr & 0x3F) << 1) + 1; vst->videobufsize = len2 + 8*vst->slices + 1; av_free_packet(&vst->pkt); //FIXME this should be output. if(av_new_packet(&vst->pkt, vst->videobufsize) < 0) return AVERROR(ENOMEM); memset(vst->pkt.data, 0, vst->pkt.size); vst->videobufpos = 8*vst->slices + 1; vst->cur_slice = 0; vst->curpic_num = pic_num; vst->pktpos = avio_tell(pb); } if(type == 2) len = FFMIN(len, pos); if(++vst->cur_slice > vst->slices) { av_log(s, AV_LOG_ERROR, "cur slice %d, too large\n", vst->cur_slice); return 1; } if(!vst->pkt.data) return AVERROR(ENOMEM); AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1); AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); if(vst->videobufpos + len > vst->videobufsize) { av_log(s, AV_LOG_ERROR, "outside videobufsize\n"); return 1; } if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len) return AVERROR(EIO); vst->videobufpos += len; rm->remaining_len-= len; if (type == 2 || vst->videobufpos == vst->videobufsize) { vst->pkt.data[0] = vst->cur_slice-1; *pkt= vst->pkt; vst->pkt.data= NULL; vst->pkt.size= 0; vst->pkt.buf = NULL; #if FF_API_DESTRUCT_PACKET FF_DISABLE_DEPRECATION_WARNINGS vst->pkt.destruct = NULL; FF_ENABLE_DEPRECATION_WARNINGS #endif if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, vst->videobufpos - 1 - 8*vst->slices); pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices); pkt->pts = AV_NOPTS_VALUE; pkt->pos = vst->pktpos; vst->slices = 0; return 0; }
int ff_read_riff_info(AVFormatContext *s, int64_t size) { int64_t start, end, cur; AVIOContext *pb = s->pb; start = avio_tell(pb); end = start + size; while ((cur = avio_tell(pb)) >= 0 && cur <= end - 8 /* = tag + size */) { uint32_t chunk_code; int64_t chunk_size; char key[5] = { 0 }; char *value; chunk_code = avio_rl32(pb); chunk_size = avio_rl32(pb); if (url_feof(pb)) { if (chunk_code || chunk_size) { av_log(s, AV_LOG_WARNING, "INFO subchunk truncated\n"); return AVERROR_INVALIDDATA; } return AVERROR_EOF; } if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) { avio_seek(pb, -9, SEEK_CUR); chunk_code = avio_rl32(pb); chunk_size = avio_rl32(pb); if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) { av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n"); return AVERROR_INVALIDDATA; } } chunk_size += (chunk_size & 1); if (!chunk_code) { if (chunk_size) avio_skip(pb, chunk_size); else if (pb->eof_reached) { av_log(s, AV_LOG_WARNING, "truncated file\n"); return AVERROR_EOF; } continue; } value = av_mallocz(chunk_size + 1); if (!value) { av_log(s, AV_LOG_ERROR, "out of memory, unable to read INFO tag\n"); return AVERROR(ENOMEM); } AV_WL32(key, chunk_code); if (avio_read(pb, value, chunk_size) != chunk_size) { av_log(s, AV_LOG_WARNING, "premature end of file while reading INFO tag\n"); } av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); } return 0; }
static int wv_read_packet(AVFormatContext *s, AVPacket *pkt) { WVContext *wc = s->priv_data; int ret; int size, ver, off; int64_t pos; uint32_t block_samples; if (s->pb->eof_reached) return AVERROR_EOF; if(wc->block_parsed) { if ((ret = wv_read_block_header(s, s->pb, 0)) < 0) return ret; } pos = wc->pos; off = wc->multichannel ? 4 : 0; if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0) return AVERROR(ENOMEM); if(wc->multichannel) AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12); memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE); ret = avio_read(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize); if(ret != wc->blksize) { av_free_packet(pkt); return AVERROR(EIO); } while(!(wc->flags & WV_END_BLOCK)) { if(avio_rl32(s->pb) != MKTAG('w', 'v', 'p', 'k')) { av_free_packet(pkt); return AVERROR_INVALIDDATA; } if((ret = av_append_packet(s->pb, pkt, 4)) < 0) { av_free_packet(pkt); return ret; } size = AV_RL32(pkt->data + pkt->size - 4); if(size < 24 || size > WV_BLOCK_LIMIT) { av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size); return AVERROR_INVALIDDATA; } wc->blksize = size; ver = avio_rl16(s->pb); if(ver < 0x402 || ver > 0x410) { av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return AVERROR_PATCHWELCOME; } avio_r8(s->pb); // track no avio_r8(s->pb); // track sub index wc->samples = avio_rl32(s->pb); // total samples in file wc->soff = avio_rl32(s->pb); // offset in samples of current block if((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0) { av_free_packet(pkt); return ret; } memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE); if ((ret = wv_read_block_header(s, s->pb, 1)) < 0) { av_free_packet(pkt); return ret; } ret = av_append_packet(s->pb, pkt, wc->blksize); if(ret < 0) { av_free_packet(pkt); return ret; } } pkt->stream_index = 0; wc->block_parsed = 1; pkt->pts = wc->soff; block_samples = AV_RN32(wc->extra); if (block_samples > INT32_MAX) av_log(s, AV_LOG_WARNING, "Too many samples in block: %"PRIu32"\n", block_samples); else pkt->duration = block_samples; av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; }
static int encode_init(AVCodecContext * avctx){ WMACodecContext *s = avctx->priv_data; int i, flags1, flags2; uint8_t *extradata; s->avctx = avctx; if(avctx->channels > MAX_CHANNELS) { av_log(avctx, AV_LOG_ERROR, "too many channels: got %i, need %i or fewer", avctx->channels, MAX_CHANNELS); return AVERROR(EINVAL); } if (avctx->sample_rate > 48000) { av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz", avctx->sample_rate); return AVERROR(EINVAL); } if(avctx->bit_rate < 24*1000) { av_log(avctx, AV_LOG_ERROR, "bitrate too low: got %i, need 24000 or higher\n", avctx->bit_rate); return AVERROR(EINVAL); } /* extract flag infos */ flags1 = 0; flags2 = 1; if (avctx->codec->id == AV_CODEC_ID_WMAV1) { extradata= av_malloc(4); avctx->extradata_size= 4; AV_WL16(extradata, flags1); AV_WL16(extradata+2, flags2); } else if (avctx->codec->id == AV_CODEC_ID_WMAV2) { extradata= av_mallocz(10); avctx->extradata_size= 10; AV_WL32(extradata, flags1); AV_WL16(extradata+4, flags2); }else assert(0); avctx->extradata= extradata; s->use_exp_vlc = flags2 & 0x0001; s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; if (avctx->channels == 2) s->ms_stereo = 1; ff_wma_init(avctx, flags2); /* init MDCT */ for(i = 0; i < s->nb_block_sizes; i++) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0); s->block_align = avctx->bit_rate * (int64_t)s->frame_len / (avctx->sample_rate * 8); s->block_align = FFMIN(s->block_align, MAX_CODED_SUPERFRAME_SIZE); avctx->block_align = s->block_align; avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate / s->frame_len; avctx->frame_size = avctx->delay = s->frame_len; #if FF_API_OLD_ENCODE_AUDIO avctx->coded_frame = &s->frame; avcodec_get_frame_defaults(avctx->coded_frame); #endif return 0; }
/* wav input */ static int wav_read_header(AVFormatContext *s) { int64_t size, av_uninit(data_size); int64_t sample_count = 0; int rf64; uint32_t tag; AVIOContext *pb = s->pb; AVStream *st = NULL; WAVDemuxContext *wav = s->priv_data; int ret, got_fmt = 0; int64_t next_tag_ofs, data_ofs = -1; wav->smv_data_ofs = -1; /* check RIFF header */ tag = avio_rl32(pb); rf64 = tag == MKTAG('R', 'F', '6', '4'); if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) return AVERROR_INVALIDDATA; avio_rl32(pb); /* file size */ tag = avio_rl32(pb); if (tag != MKTAG('W', 'A', 'V', 'E')) return AVERROR_INVALIDDATA; if (rf64) { if (avio_rl32(pb) != MKTAG('d', 's', '6', '4')) return AVERROR_INVALIDDATA; size = avio_rl32(pb); if (size < 24) return AVERROR_INVALIDDATA; avio_rl64(pb); /* RIFF size */ data_size = avio_rl64(pb); sample_count = avio_rl64(pb); if (data_size < 0 || sample_count < 0) { av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in " "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n", data_size, sample_count); return AVERROR_INVALIDDATA; } avio_skip(pb, size - 24); /* skip rest of ds64 chunk */ } for (;;) { AVStream *vst; size = next_tag(pb, &tag); next_tag_ofs = avio_tell(pb) + size; if (url_feof(pb)) break; switch (tag) { case MKTAG('f', 'm', 't', ' '): /* only parse the first 'fmt ' tag found */ if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st)) < 0) { return ret; } else if (got_fmt) av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n"); got_fmt = 1; break; case MKTAG('d', 'a', 't', 'a'): if (!got_fmt) { av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n"); return AVERROR_INVALIDDATA; } if (rf64) { next_tag_ofs = wav->data_end = avio_tell(pb) + data_size; } else { data_size = size; next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX; } data_ofs = avio_tell(pb); /* don't look for footer metadata if we can't seek or if we don't * know where the data tag ends */ if (!pb->seekable || (!rf64 && !size)) goto break_loop; break; case MKTAG('f', 'a', 'c', 't'): if (!sample_count) sample_count = avio_rl32(pb); break; case MKTAG('b', 'e', 'x', 't'): if ((ret = wav_parse_bext_tag(s, size)) < 0) return ret; break; case MKTAG('S','M','V','0'): if (!got_fmt) { av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n"); return AVERROR_INVALIDDATA; } // SMV file, a wav file with video appended. if (size != MKTAG('0','2','0','0')) { av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n"); goto break_loop; } av_log(s, AV_LOG_DEBUG, "Found SMV data\n"); wav->smv_given_first = 0; vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); avio_r8(pb); vst->id = 1; vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_SMVJPEG; vst->codec->width = avio_rl24(pb); vst->codec->height = avio_rl24(pb); vst->codec->extradata_size = 4; vst->codec->extradata = av_malloc(vst->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!vst->codec->extradata) { av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n"); return AVERROR(ENOMEM); } size = avio_rl24(pb); wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3; avio_rl24(pb); wav->smv_block_size = avio_rl24(pb); avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb)); vst->duration = avio_rl24(pb); avio_rl24(pb); avio_rl24(pb); wav->smv_frames_per_jpeg = avio_rl24(pb); AV_WL32(vst->codec->extradata, wav->smv_frames_per_jpeg); wav->smv_cur_pt = 0; goto break_loop; case MKTAG('L', 'I', 'S', 'T'): if (size < 4) { av_log(s, AV_LOG_ERROR, "too short LIST tag\n"); return AVERROR_INVALIDDATA; } switch (avio_rl32(pb)) { case MKTAG('I', 'N', 'F', 'O'): ff_read_riff_info(s, size - 4); } break; } /* seek to next tag unless we know that we'll run into EOF */ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) || wav_seek_tag(pb, next_tag_ofs, SEEK_SET) < 0) { break; } } break_loop: if (data_ofs < 0) { av_log(s, AV_LOG_ERROR, "no 'data' tag found\n"); return AVERROR_INVALIDDATA; } avio_seek(pb, data_ofs, SEEK_SET); if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb)) sample_count = (data_size << 3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); if (sample_count) st->duration = sample_count; ff_metadata_conv_ctx(s, NULL, wav_metadata_conv); ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); return 0; }
static int apng_read_header(AVFormatContext *s) { APNGDemuxContext *ctx = s->priv_data; AVIOContext *pb = s->pb; uint32_t len, tag; AVStream *st; int ret = AVERROR_INVALIDDATA, acTL_found = 0; /* verify PNGSIG */ if (avio_rb64(pb) != PNGSIG) return ret; /* parse IHDR (must be first chunk) */ len = avio_rb32(pb); tag = avio_rl32(pb); if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R')) return ret; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_APNG; st->codec->width = avio_rb32(pb); st->codec->height = avio_rb32(pb); if ((ret = av_image_check_size(st->codec->width, st->codec->height, 0, s)) < 0) return ret; /* extradata will contain every chunk up to the first fcTL (excluded) */ st->codec->extradata = av_malloc(len + 12 + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); st->codec->extradata_size = len + 12; AV_WB32(st->codec->extradata, len); AV_WL32(st->codec->extradata+4, tag); AV_WB32(st->codec->extradata+8, st->codec->width); AV_WB32(st->codec->extradata+12, st->codec->height); if ((ret = avio_read(pb, st->codec->extradata+16, 9)) < 0) goto fail; while (!avio_feof(pb)) { if (acTL_found && ctx->num_play != 1) { int64_t size = avio_size(pb); int64_t offset = avio_tell(pb); if (size < 0) { ret = size; goto fail; } else if (offset < 0) { ret = offset; goto fail; } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) { av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n"); ctx->num_play = 1; } } if ((ctx->num_play == 1 || !acTL_found) && ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0)) goto fail; len = avio_rb32(pb); if (len > 0x7fffffff) { ret = AVERROR_INVALIDDATA; goto fail; } tag = avio_rl32(pb); switch (tag) { case MKTAG('a', 'c', 'T', 'L'): if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || (ret = append_extradata(st->codec, pb, len + 12)) < 0) goto fail; acTL_found = 1; ctx->num_frames = AV_RB32(st->codec->extradata + ret + 8); ctx->num_play = AV_RB32(st->codec->extradata + ret + 12); av_log(s, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n", ctx->num_frames, ctx->num_play); break; case MKTAG('f', 'c', 'T', 'L'): if (!acTL_found) { ret = AVERROR_INVALIDDATA; goto fail; } if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0) goto fail; return 0; default: if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || (ret = append_extradata(st->codec, pb, len + 12)) < 0) goto fail; } } fail: if (st->codec->extradata_size) { av_freep(&st->codec->extradata); st->codec->extradata_size = 0; } return ret; }
static int rm_assemble_video_frame(ffmpeg_video* p,const packet* Packet) { int32_t hdr, seq, pic_num, len2, pos; int32_t type; uint8_t* buf = (uint8_t*)Packet->Data[0]; int32_t len = Packet->Length; int32_t used=0; RMVideo* rm = &p->rm; hdr = *buf++; len--; type = hdr >> 6; switch(type) { case 0: // slice case 2: // last slice seq = *buf++; len--; len2 = get_num(p,buf, &used); buf+=used; len-=used; used=0; pos = get_num(p,buf, &used); buf+=used; len-=used; pic_num = *buf++; len--; break; case 1: //whole frame { uint8_t addbuf[9]={0,1,1,1,1,0,0,0,0}; seq = *buf++; len--; BufferWrite(&p->Buffer,addbuf,9,1); BufferWrite(&p->Buffer,buf,len,2048); } return ERR_NONE; case 3: //frame as a part of packet { uint8_t addbuf[9]={0,1,1,1,1,0,0,0,0}; len2 = get_num(p,buf, &used); buf+=used; len-=used; used=0; pos = get_num(p,buf, &used); buf+=used; len-=used; pic_num = *buf++; len--; BufferWrite(&p->Buffer,addbuf,9,1); BufferWrite(&p->Buffer,buf,len2,2048); } return ERR_NONE; } //now we have to deal with single slice if((seq & 0x7F) == 1 || rm->curpic_num != pic_num) { rm->slices = ((hdr & 0x3F) << 1) + 1; rm->videobufsize = len2 + 8*rm->slices + 1; av_free(rm->videobuf); if(!(rm->videobuf = av_malloc(rm->videobufsize))) return ERR_OUT_OF_MEMORY; rm->videobufpos = 8*rm->slices + 1; rm->cur_slice = 0; rm->curpic_num = pic_num; } if(type == 2) len = FFMIN(len, pos); if(++rm->cur_slice > rm->slices) return ERR_OUT_OF_MEMORY; AV_WL32(rm->videobuf - 7 + 8*rm->cur_slice, 1); AV_WL32(rm->videobuf - 3 + 8*rm->cur_slice, rm->videobufpos - 8*rm->slices - 1); if(rm->videobufpos + len > rm->videobufsize) return ERR_OUT_OF_MEMORY; memcpy(rm->videobuf+rm->videobufpos,buf,len); rm->videobufpos += len; rm->remaining_len-= len; if(type == 2 || (rm->videobufpos) == rm->videobufsize) { rm->videobuf[0] = rm->cur_slice-1; BufferWrite(&p->Buffer,rm->videobuf,1 + 8*rm->cur_slice,1); BufferWrite(&p->Buffer,rm->videobuf + 1 + 8*rm->slices,rm->videobufpos - 1 - 8*rm->slices,2048); return ERR_NONE; } return ERR_NEED_MORE_DATA; }
static int flac_read_header(AVFormatContext *s) { int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0; uint8_t header[4]; uint8_t *buffer=NULL,*tmp=NULL; AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_FLAC; st->need_parsing = AVSTREAM_PARSE_FULL_RAW; /* the parameters will be extracted from the compressed bitstream */ /* if fLaC marker is not found, assume there is no header */ if (avio_rl32(s->pb) != MKTAG('f','L','a','C')) { avio_seek(s->pb, -4, SEEK_CUR); return 0; } /* process metadata blocks */ while (!url_feof(s->pb) && !metadata_last) { avio_read(s->pb, header, 4); avpriv_flac_parse_block_header(header, &metadata_last, &metadata_type, &metadata_size); switch (metadata_type) { /* allocate and read metadata block for supported types */ case FLAC_METADATA_TYPE_STREAMINFO: case FLAC_METADATA_TYPE_CUESHEET: case FLAC_METADATA_TYPE_PICTURE: case FLAC_METADATA_TYPE_VORBIS_COMMENT: buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!buffer) { return AVERROR(ENOMEM); } if (avio_read(s->pb, buffer, metadata_size) != metadata_size) { RETURN_ERROR(AVERROR(EIO)); } break; /* skip metadata block for unsupported types */ default: ret = avio_skip(s->pb, metadata_size); if (ret < 0) return ret; } if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) { FLACStreaminfo si; /* STREAMINFO can only occur once */ if (found_streaminfo) { RETURN_ERROR(AVERROR_INVALIDDATA); } if (metadata_size != FLAC_STREAMINFO_SIZE) { RETURN_ERROR(AVERROR_INVALIDDATA); } found_streaminfo = 1; st->codec->extradata = av_malloc(metadata_size + 8 + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { RETURN_ERROR(AVERROR(ENOMEM)); } st->codec->extradata_size = metadata_size + 8; AV_WL32(st->codec->extradata, MKTAG('f','L','a','C')); memcpy(st->codec->extradata + 4, header, 4); memcpy(st->codec->extradata + 8, buffer, metadata_size); av_freep(&buffer); /* get codec params from STREAMINFO header */ avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata + 8); /* set time base and duration */ if (si.samplerate > 0) { avpriv_set_pts_info(st, 64, 1, si.samplerate); if (si.samples > 0) st->duration = si.samples; } } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) { uint8_t isrc[13]; uint64_t start; const uint8_t *offset; int i, chapters, track, ti; if (metadata_size < 431) RETURN_ERROR(AVERROR_INVALIDDATA); offset = buffer + 395; chapters = bytestream_get_byte(&offset) - 1; if (chapters <= 0) RETURN_ERROR(AVERROR_INVALIDDATA); for (i = 0; i < chapters; i++) { if (offset + 36 - buffer > metadata_size) RETURN_ERROR(AVERROR_INVALIDDATA); start = bytestream_get_be64(&offset); track = bytestream_get_byte(&offset); bytestream_get_buffer(&offset, isrc, 12); isrc[12] = 0; offset += 14; ti = bytestream_get_byte(&offset); if (ti <= 0) RETURN_ERROR(AVERROR_INVALIDDATA); offset += ti * 12; avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc); } av_freep(&buffer); } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) { ret = parse_picture(s, buffer, metadata_size); av_freep(&buffer); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n"); return ret; } } else { /* STREAMINFO must be the first block */ if (!found_streaminfo) { RETURN_ERROR(AVERROR_INVALIDDATA); } /* process supported blocks other than STREAMINFO */ if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) { /* append VorbisComment to extradata */ tmp = av_realloc(st->codec->extradata, st->codec->extradata_size + 4 + metadata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!tmp) { RETURN_ERROR(AVERROR(ENOMEM)); } st->codec->extradata = tmp; tmp += st->codec->extradata_size; memcpy(tmp, header, 4); memcpy(tmp + 4, buffer, metadata_size); st->codec->extradata_size = st->codec->extradata_size + 4 + metadata_size; if (ff_vorbis_comment(s, &s->metadata, buffer, metadata_size)) { av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n"); } } av_freep(&buffer); } } return 0; fail: av_free(buffer); return ret; }
static int dxv_decompress_dxt5(AVCodecContext *avctx) { DXVContext *ctx = avctx->priv_data; GetByteContext *gbc = &ctx->gbc; uint32_t value, op; int idx, prev, state = 0; int pos = 4; int run = 0; int probe, check; /* Copy the first four elements */ AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc)); AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc)); AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc)); AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc)); /* Process input until the whole texture has been filled */ while (pos < ctx->tex_size / 4) { if (run) { run--; prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; } else { if (state == 0) { value = bytestream2_get_le32(gbc); state = 16; } op = value & 0x3; value >>= 2; state--; switch (op) { case 0: /* Long copy */ check = bytestream2_get_byte(gbc) + 1; if (check == 256) { do { probe = bytestream2_get_le16(gbc); check += probe; } while (probe == 0xFFFF); } while (check && pos < ctx->tex_size / 4) { prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; check--; } /* Restart (or exit) the loop */ continue; break; case 1: /* Load new run value */ run = bytestream2_get_byte(gbc); if (run == 255) { do { probe = bytestream2_get_le16(gbc); run += probe; } while (probe == 0xFFFF); } /* Copy two dwords from previous data */ prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; break; case 2: /* Copy two dwords from a previous index */ idx = 8 + bytestream2_get_le16(gbc); prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; break; case 3: /* Copy two dwords from input */ prev = bytestream2_get_le32(gbc); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = bytestream2_get_le32(gbc); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; break; } } CHECKPOINT(4); /* Copy two elements from a previous offset or from the input buffer */ if (op) { prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; } else { CHECKPOINT(4); if (op) prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); else prev = bytestream2_get_le32(gbc); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; CHECKPOINT(4); if (op) prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); else prev = bytestream2_get_le32(gbc); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; } } return 0; }
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb, RMDemuxContext *rm, RMStream *vst, AVPacket *pkt, int len, int *pseq, int64_t *timestamp) { int hdr, seq, pic_num, len2, pos; int type; hdr = avio_r8(pb); len--; type = hdr >> 6; if(type != 3){ // not frame as a part of packet seq = avio_r8(pb); len--; } if(type != 1){ // not whole frame len2 = get_num(pb, &len); pos = get_num(pb, &len); pic_num = avio_r8(pb); len--; } if(len<0) return -1; rm->remaining_len = len; if(type&1){ // frame, not slice if(type == 3){ // frame as a part of packet len= len2; *timestamp = pos; } if(rm->remaining_len < len) return -1; rm->remaining_len -= len; if(av_new_packet(pkt, len + 9) < 0) return AVERROR(EIO); pkt->data[0] = 0; AV_WL32(pkt->data + 1, 1); AV_WL32(pkt->data + 5, 0); avio_read(pb, pkt->data + 9, len); return 0; } //now we have to deal with single slice *pseq = seq; if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ vst->slices = ((hdr & 0x3F) << 1) + 1; vst->videobufsize = len2 + 8*vst->slices + 1; av_free_packet(&vst->pkt); //FIXME this should be output. if(av_new_packet(&vst->pkt, vst->videobufsize) < 0) return AVERROR(ENOMEM); vst->videobufpos = 8*vst->slices + 1; vst->cur_slice = 0; vst->curpic_num = pic_num; vst->pktpos = avio_tell(pb); } if(type == 2) len = FFMIN(len, pos); if(++vst->cur_slice > vst->slices) return 1; AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1); AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); if(vst->videobufpos + len > vst->videobufsize) return 1; if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len) return AVERROR(EIO); vst->videobufpos += len; rm->remaining_len-= len; if (type == 2 || vst->videobufpos == vst->videobufsize) { vst->pkt.data[0] = vst->cur_slice-1; *pkt= vst->pkt; vst->pkt.data= NULL; vst->pkt.size= 0; vst->pkt.buf = NULL; #if FF_API_DESTRUCT_PACKET vst->pkt.destruct = NULL; #endif if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, vst->videobufpos - 1 - 8*vst->slices); pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices); pkt->pts = AV_NOPTS_VALUE; pkt->pos = vst->pktpos; vst->slices = 0; return 0; } return 1; }
static void super2xsai(AVFilterContext *ctx, uint8_t *src, int src_linesize, uint8_t *dst, int dst_linesize, int width, int height) { Super2xSaIContext *sai = ctx->priv; unsigned int x, y; uint32_t color[4][4]; unsigned char *src_line[4]; const int bpp = sai->bpp; const uint32_t hi_pixel_mask = sai->hi_pixel_mask; const uint32_t lo_pixel_mask = sai->lo_pixel_mask; const uint32_t q_hi_pixel_mask = sai->q_hi_pixel_mask; const uint32_t q_lo_pixel_mask = sai->q_lo_pixel_mask; /* Point to the first 4 lines, first line is duplicated */ src_line[0] = src; src_line[1] = src; src_line[2] = src + src_linesize*FFMIN(1, height-1); src_line[3] = src + src_linesize*FFMIN(2, height-1); #define READ_COLOR4(dst, src_line, off) dst = *((const uint32_t *)src_line + off) #define READ_COLOR3(dst, src_line, off) dst = AV_RL24 (src_line + 3*off) #define READ_COLOR2(dst, src_line, off) dst = sai->is_be ? AV_RB16(src_line + 2 * off) : AV_RL16(src_line + 2 * off) for (y = 0; y < height; y++) { uint8_t *dst_line[2]; dst_line[0] = dst + dst_linesize*2*y; dst_line[1] = dst + dst_linesize*(2*y+1); switch (bpp) { case 4: READ_COLOR4(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR4(color[0][2], src_line[0], 1); READ_COLOR4(color[0][3], src_line[0], 2); READ_COLOR4(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR4(color[1][2], src_line[1], 1); READ_COLOR4(color[1][3], src_line[1], 2); READ_COLOR4(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR4(color[2][2], src_line[2], 1); READ_COLOR4(color[2][3], src_line[2], 2); READ_COLOR4(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR4(color[3][2], src_line[3], 1); READ_COLOR4(color[3][3], src_line[3], 2); break; case 3: READ_COLOR3(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR3(color[0][2], src_line[0], 1); READ_COLOR3(color[0][3], src_line[0], 2); READ_COLOR3(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR3(color[1][2], src_line[1], 1); READ_COLOR3(color[1][3], src_line[1], 2); READ_COLOR3(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR3(color[2][2], src_line[2], 1); READ_COLOR3(color[2][3], src_line[2], 2); READ_COLOR3(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR3(color[3][2], src_line[3], 1); READ_COLOR3(color[3][3], src_line[3], 2); break; default: READ_COLOR2(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR2(color[0][2], src_line[0], 1); READ_COLOR2(color[0][3], src_line[0], 2); READ_COLOR2(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR2(color[1][2], src_line[1], 1); READ_COLOR2(color[1][3], src_line[1], 2); READ_COLOR2(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR2(color[2][2], src_line[2], 1); READ_COLOR2(color[2][3], src_line[2], 2); READ_COLOR2(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR2(color[3][2], src_line[3], 1); READ_COLOR2(color[3][3], src_line[3], 2); } for (x = 0; x < width; x++) { uint32_t product1a, product1b, product2a, product2b; //--------------------------------------- B0 B1 B2 B3 0 1 2 3 // 4 5* 6 S2 -> 4 5* 6 7 // 1 2 3 S1 8 9 10 11 // A0 A1 A2 A3 12 13 14 15 //-------------------------------------- if (color[2][1] == color[1][2] && color[1][1] != color[2][2]) { product2b = color[2][1]; product1b = product2b; } else if (color[1][1] == color[2][2] && color[2][1] != color[1][2]) { product2b = color[1][1]; product1b = product2b; } else if (color[1][1] == color[2][2] && color[2][1] == color[1][2]) { int r = 0; r += GET_RESULT(color[1][2], color[1][1], color[1][0], color[3][1]); r += GET_RESULT(color[1][2], color[1][1], color[2][0], color[0][1]); r += GET_RESULT(color[1][2], color[1][1], color[3][2], color[2][3]); r += GET_RESULT(color[1][2], color[1][1], color[0][2], color[1][3]); if (r > 0) product1b = color[1][2]; else if (r < 0) product1b = color[1][1]; else product1b = INTERPOLATE(color[1][1], color[1][2]); product2b = product1b; } else { if (color[1][2] == color[2][2] && color[2][2] == color[3][1] && color[2][1] != color[3][2] && color[2][2] != color[3][0]) product2b = Q_INTERPOLATE(color[2][2], color[2][2], color[2][2], color[2][1]); else if (color[1][1] == color[2][1] && color[2][1] == color[3][2] && color[3][1] != color[2][2] && color[2][1] != color[3][3]) product2b = Q_INTERPOLATE(color[2][1], color[2][1], color[2][1], color[2][2]); else product2b = INTERPOLATE(color[2][1], color[2][2]); if (color[1][2] == color[2][2] && color[1][2] == color[0][1] && color[1][1] != color[0][2] && color[1][2] != color[0][0]) product1b = Q_INTERPOLATE(color[1][2], color[1][2], color[1][2], color[1][1]); else if (color[1][1] == color[2][1] && color[1][1] == color[0][2] && color[0][1] != color[1][2] && color[1][1] != color[0][3]) product1b = Q_INTERPOLATE(color[1][2], color[1][1], color[1][1], color[1][1]); else product1b = INTERPOLATE(color[1][1], color[1][2]); } if (color[1][1] == color[2][2] && color[2][1] != color[1][2] && color[1][0] == color[1][1] && color[1][1] != color[3][2]) product2a = INTERPOLATE(color[2][1], color[1][1]); else if (color[1][1] == color[2][0] && color[1][2] == color[1][1] && color[1][0] != color[2][1] && color[1][1] != color[3][0]) product2a = INTERPOLATE(color[2][1], color[1][1]); else product2a = color[2][1]; if (color[2][1] == color[1][2] && color[1][1] != color[2][2] && color[2][0] == color[2][1] && color[2][1] != color[0][2]) product1a = INTERPOLATE(color[2][1], color[1][1]); else if (color[1][0] == color[2][1] && color[2][2] == color[2][1] && color[2][0] != color[1][1] && color[2][1] != color[0][0]) product1a = INTERPOLATE(color[2][1], color[1][1]); else product1a = color[1][1]; /* Set the calculated pixels */ switch (bpp) { case 4: AV_WN32A(dst_line[0] + x * 8, product1a); AV_WN32A(dst_line[0] + x * 8 + 4, product1b); AV_WN32A(dst_line[1] + x * 8, product2a); AV_WN32A(dst_line[1] + x * 8 + 4, product2b); break; case 3: AV_WL24(dst_line[0] + x * 6, product1a); AV_WL24(dst_line[0] + x * 6 + 3, product1b); AV_WL24(dst_line[1] + x * 6, product2a); AV_WL24(dst_line[1] + x * 6 + 3, product2b); break; default: // bpp = 2 if (sai->is_be) { AV_WB32(dst_line[0] + x * 4, product1a | (product1b << 16)); AV_WB32(dst_line[1] + x * 4, product2a | (product2b << 16)); } else { AV_WL32(dst_line[0] + x * 4, product1a | (product1b << 16)); AV_WL32(dst_line[1] + x * 4, product2a | (product2b << 16)); } } /* Move color matrix forward */ color[0][0] = color[0][1]; color[0][1] = color[0][2]; color[0][2] = color[0][3]; color[1][0] = color[1][1]; color[1][1] = color[1][2]; color[1][2] = color[1][3]; color[2][0] = color[2][1]; color[2][1] = color[2][2]; color[2][2] = color[2][3]; color[3][0] = color[3][1]; color[3][1] = color[3][2]; color[3][2] = color[3][3]; if (x < width - 3) { x += 3; switch (bpp) { case 4: READ_COLOR4(color[0][3], src_line[0], x); READ_COLOR4(color[1][3], src_line[1], x); READ_COLOR4(color[2][3], src_line[2], x); READ_COLOR4(color[3][3], src_line[3], x); break; case 3: READ_COLOR3(color[0][3], src_line[0], x); READ_COLOR3(color[1][3], src_line[1], x); READ_COLOR3(color[2][3], src_line[2], x); READ_COLOR3(color[3][3], src_line[3], x); break; default: /* case 2 */ READ_COLOR2(color[0][3], src_line[0], x); READ_COLOR2(color[1][3], src_line[1], x); READ_COLOR2(color[2][3], src_line[2], x); READ_COLOR2(color[3][3], src_line[3], x); } x -= 3; } } /* We're done with one line, so we shift the source lines up */ src_line[0] = src_line[1]; src_line[1] = src_line[2]; src_line[2] = src_line[3]; /* Read next line */ src_line[3] = src_line[2]; if (y < height - 3) src_line[3] += src_linesize; } // y loop }
static int fourxm_read_header(AVFormatContext *s, AVFormatParameters *ap) { 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 (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 = 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= -1; goto fail; } if (current_track + 1 > fourxm->track_count) { fourxm->tracks = av_realloc(fourxm->tracks, (current_track + 1) * sizeof(AudioTrack)); 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= -1; 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 = CODEC_ID_ADPCM_4XM; }else if (st->codec->bits_per_coded_sample == 8){ st->codec->codec_id = CODEC_ID_PCM_U8; }else st->codec->codec_id = 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 wv_read_packet(AVFormatContext *s, AVPacket *pkt) { WVContext *wc = s->priv_data; int ret; int size, ver, off; if (url_feof(s->pb)) return AVERROR(EIO); if(wc->block_parsed){ if(wv_read_block_header(s, s->pb, 0) < 0) return -1; } off = wc->multichannel ? 4 : 0; if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0) return AVERROR(ENOMEM); if(wc->multichannel) AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12); memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE); ret = get_buffer(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize); if(ret != wc->blksize){ av_free_packet(pkt); return AVERROR(EIO); } while(!(wc->flags & WV_END_BLOCK)){ if(get_le32(s->pb) != MKTAG('w', 'v', 'p', 'k')){ av_free_packet(pkt); return -1; } if((ret = av_append_packet(s->pb, pkt, 4)) < 0){ av_free_packet(pkt); return ret; } size = AV_RL32(pkt->data + pkt->size - 4); if(size < 24 || size > WV_BLOCK_LIMIT){ av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size); return -1; } wc->blksize = size; ver = get_le16(s->pb); if(ver < 0x402 || ver > 0x410){ av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return -1; } get_byte(s->pb); // track no get_byte(s->pb); // track sub index wc->samples = get_le32(s->pb); // total samples in file wc->soff = get_le32(s->pb); // offset in samples of current block if((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0){ av_free_packet(pkt); return ret; } memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE); if(wv_read_block_header(s, s->pb, 1) < 0){ av_free_packet(pkt); return -1; } ret = av_append_packet(s->pb, pkt, wc->blksize); if(ret < 0){ av_free_packet(pkt); return ret; } } pkt->stream_index = 0; wc->block_parsed = 1; pkt->pts = wc->soff; av_add_index_entry(s->streams[0], wc->pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; }
static int read_header(AVFormatContext *s) { BinkDemuxContext *bink = s->priv_data; AVIOContext *pb = s->pb; uint32_t fps_num, fps_den; AVStream *vst, *ast; unsigned int i; uint32_t pos, next_pos; uint16_t flags; int keyframe; vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_tag = avio_rl32(pb); bink->file_size = avio_rl32(pb) + 8; vst->duration = avio_rl32(pb); if (vst->duration > 1000000) { av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); return AVERROR(EIO); } if (avio_rl32(pb) > bink->file_size) { av_log(s, AV_LOG_ERROR, "invalid header: largest frame size greater than file size\n"); return AVERROR(EIO); } avio_skip(pb, 4); vst->codec->width = avio_rl32(pb); vst->codec->height = avio_rl32(pb); fps_num = avio_rl32(pb); fps_den = avio_rl32(pb); if (fps_num == 0 || fps_den == 0) { av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den); return AVERROR(EIO); } avpriv_set_pts_info(vst, 64, fps_den, fps_num); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = CODEC_ID_BINKVIDEO; vst->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); vst->codec->extradata_size = 4; avio_read(pb, vst->codec->extradata, 4); bink->num_audio_tracks = avio_rl32(pb); if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { av_log(s, AV_LOG_ERROR, "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n", bink->num_audio_tracks); return AVERROR(EIO); } if (bink->num_audio_tracks) { avio_skip(pb, 4 * bink->num_audio_tracks); for (i = 0; i < bink->num_audio_tracks; i++) { ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_tag = 0; ast->codec->sample_rate = avio_rl16(pb); avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); flags = avio_rl16(pb); ast->codec->codec_id = flags & BINK_AUD_USEDCT ? CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT; ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1; ast->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); if (!ast->codec->extradata) return AVERROR(ENOMEM); ast->codec->extradata_size = 4; AV_WL32(ast->codec->extradata, vst->codec->codec_tag); } for (i = 0; i < bink->num_audio_tracks; i++) s->streams[i + 1]->id = avio_rl32(pb); } /* frame index table */ next_pos = avio_rl32(pb); for (i = 0; i < vst->duration; i++) { pos = next_pos; if (i == vst->duration - 1) { next_pos = bink->file_size; keyframe = 0; } else { next_pos = avio_rl32(pb); keyframe = pos & 1; } pos &= ~1; next_pos &= ~1; if (next_pos <= pos) { av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); return AVERROR(EIO); } av_add_index_entry(vst, pos, i, next_pos - pos, 0, keyframe ? AVINDEX_KEYFRAME : 0); } avio_skip(pb, 4); bink->current_track = -1; return 0; }
static av_cold int encode_init(AVCodecContext *avctx) { WMACodecContext *s = avctx->priv_data; int i, flags1, flags2, block_align; uint8_t *extradata; int ret; s->avctx = avctx; if (avctx->channels > MAX_CHANNELS) { av_log(avctx, AV_LOG_ERROR, "too many channels: got %i, need %i or fewer\n", avctx->channels, MAX_CHANNELS); return AVERROR(EINVAL); } if (avctx->sample_rate > 48000) { av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz\n", avctx->sample_rate); return AVERROR(EINVAL); } if (avctx->bit_rate < 24 * 1000) { av_log(avctx, AV_LOG_ERROR, "bitrate too low: got %i, need 24000 or higher\n", avctx->bit_rate); return AVERROR(EINVAL); } /* extract flag infos */ flags1 = 0; flags2 = 1; if (avctx->codec->id == AV_CODEC_ID_WMAV1) { extradata = av_malloc(4); if (!extradata) return AVERROR(ENOMEM); avctx->extradata_size = 4; AV_WL16(extradata, flags1); AV_WL16(extradata + 2, flags2); } else if (avctx->codec->id == AV_CODEC_ID_WMAV2) { extradata = av_mallocz(10); if (!extradata) return AVERROR(ENOMEM); avctx->extradata_size = 10; AV_WL32(extradata, flags1); AV_WL16(extradata + 4, flags2); } else { av_assert0(0); } avctx->extradata = extradata; s->use_exp_vlc = flags2 & 0x0001; s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; if (avctx->channels == 2) s->ms_stereo = 1; if ((ret = ff_wma_init(avctx, flags2)) < 0) return ret; /* init MDCT */ for (i = 0; i < s->nb_block_sizes; i++) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0); block_align = avctx->bit_rate * (int64_t) s->frame_len / (avctx->sample_rate * 8); block_align = FFMIN(block_align, MAX_CODED_SUPERFRAME_SIZE); avctx->block_align = block_align; avctx->frame_size = avctx->initial_padding = s->frame_len; return 0; }
static int read_header(AVFormatContext *s) { BinkDemuxContext *bink = s->priv_data; AVIOContext *pb = s->pb; uint32_t fps_num, fps_den; AVStream *vst, *ast; unsigned int i; uint32_t pos, next_pos; uint16_t flags; int keyframe; int ret; vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); vst->codecpar->codec_tag = avio_rl32(pb); bink->file_size = avio_rl32(pb) + 8; vst->duration = avio_rl32(pb); if (vst->duration > 1000000) { av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); return AVERROR(EIO); } if (avio_rl32(pb) > bink->file_size) { av_log(s, AV_LOG_ERROR, "invalid header: largest frame size greater than file size\n"); return AVERROR(EIO); } avio_skip(pb, 4); vst->codecpar->width = avio_rl32(pb); vst->codecpar->height = avio_rl32(pb); fps_num = avio_rl32(pb); fps_den = avio_rl32(pb); if (fps_num == 0 || fps_den == 0) { av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%"PRIu32"/%"PRIu32")\n", fps_num, fps_den); return AVERROR(EIO); } avpriv_set_pts_info(vst, 64, fps_den, fps_num); vst->avg_frame_rate = av_inv_q(vst->time_base); vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; vst->codecpar->codec_id = AV_CODEC_ID_BINKVIDEO; if ((vst->codecpar->codec_tag & 0xFFFFFF) == MKTAG('K', 'B', '2', 0)) { av_log(s, AV_LOG_WARNING, "Bink 2 video is not implemented\n"); vst->codecpar->codec_id = AV_CODEC_ID_NONE; } if (ff_get_extradata(vst->codecpar, pb, 4) < 0) return AVERROR(ENOMEM); bink->num_audio_tracks = avio_rl32(pb); if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { av_log(s, AV_LOG_ERROR, "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%"PRIu32")\n", bink->num_audio_tracks); return AVERROR(EIO); } if (bink->num_audio_tracks) { avio_skip(pb, 4 * bink->num_audio_tracks); for (i = 0; i < bink->num_audio_tracks; i++) { ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; ast->codecpar->codec_tag = 0; ast->codecpar->sample_rate = avio_rl16(pb); avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate); flags = avio_rl16(pb); ast->codecpar->codec_id = flags & BINK_AUD_USEDCT ? AV_CODEC_ID_BINKAUDIO_DCT : AV_CODEC_ID_BINKAUDIO_RDFT; if (flags & BINK_AUD_STEREO) { ast->codecpar->channels = 2; ast->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; } else { ast->codecpar->channels = 1; ast->codecpar->channel_layout = AV_CH_LAYOUT_MONO; } if (ff_alloc_extradata(ast->codecpar, 4)) return AVERROR(ENOMEM); AV_WL32(ast->codecpar->extradata, vst->codecpar->codec_tag); } for (i = 0; i < bink->num_audio_tracks; i++) s->streams[i + 1]->id = avio_rl32(pb); } /* frame index table */ next_pos = avio_rl32(pb); for (i = 0; i < vst->duration; i++) { pos = next_pos; if (i == vst->duration - 1) { next_pos = bink->file_size; keyframe = 0; } else { next_pos = avio_rl32(pb); keyframe = pos & 1; } pos &= ~1; next_pos &= ~1; if (next_pos <= pos) { av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); return AVERROR(EIO); } if ((ret = av_add_index_entry(vst, pos, i, next_pos - pos, 0, keyframe ? AVINDEX_KEYFRAME : 0)) < 0) return ret; } if (vst->index_entries) avio_seek(pb, vst->index_entries[0].pos, SEEK_SET); else avio_skip(pb, 4); bink->current_track = -1; return 0; }
static int smush_read_header(AVFormatContext *ctx) { SMUSHContext *smush = ctx->priv_data; AVIOContext *pb = ctx->pb; AVStream *vst, *ast; uint32_t magic, nframes, size, subversion, i; uint32_t width = 0, height = 0, got_audio = 0, read = 0; uint32_t sample_rate, channels, palette[256]; magic = avio_rb32(pb); avio_skip(pb, 4); // skip movie size if (magic == MKBETAG('A', 'N', 'I', 'M')) { if (avio_rb32(pb) != MKBETAG('A', 'H', 'D', 'R')) return AVERROR_INVALIDDATA; size = avio_rb32(pb); if (size < 3 * 256 + 6) return AVERROR_INVALIDDATA; smush->version = 0; subversion = avio_rl16(pb); nframes = avio_rl16(pb); if (!nframes) return AVERROR_INVALIDDATA; avio_skip(pb, 2); // skip pad for (i = 0; i < 256; i++) palette[i] = avio_rb24(pb); avio_skip(pb, size - (3 * 256 + 6)); } else if (magic == MKBETAG('S', 'A', 'N', 'M')) { if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R')) return AVERROR_INVALIDDATA; size = avio_rb32(pb); if (size < 14) return AVERROR_INVALIDDATA; smush->version = 1; subversion = avio_rl16(pb); nframes = avio_rl32(pb); if (!nframes) return AVERROR_INVALIDDATA; avio_skip(pb, 2); // skip pad width = avio_rl16(pb); height = avio_rl16(pb); avio_skip(pb, 2); // skip pad avio_skip(pb, size - 14); if (avio_rb32(pb) != MKBETAG('F', 'L', 'H', 'D')) return AVERROR_INVALIDDATA; size = avio_rb32(pb); while (!got_audio && ((read + 8) < size)) { uint32_t sig, chunk_size; if (avio_feof(pb)) return AVERROR_EOF; sig = avio_rb32(pb); chunk_size = avio_rb32(pb); read += 8; switch (sig) { case MKBETAG('W', 'a', 'v', 'e'): got_audio = 1; sample_rate = avio_rl32(pb); if (!sample_rate) return AVERROR_INVALIDDATA; channels = avio_rl32(pb); if (!channels) return AVERROR_INVALIDDATA; avio_skip(pb, chunk_size - 8); read += chunk_size; break; case MKBETAG('B', 'l', '1', '6'): case MKBETAG('A', 'N', 'N', 'O'): avio_skip(pb, chunk_size); read += chunk_size; break; default: return AVERROR_INVALIDDATA; break; } } avio_skip(pb, size - read); } else { av_log(ctx, AV_LOG_ERROR, "Wrong magic\n"); return AVERROR_INVALIDDATA; } vst = avformat_new_stream(ctx, 0); if (!vst) return AVERROR(ENOMEM); smush->video_stream_index = vst->index; avpriv_set_pts_info(vst, 64, 1, 15); vst->start_time = 0; vst->duration = vst->nb_frames = nframes; vst->avg_frame_rate = av_inv_q(vst->time_base); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_SANM; vst->codec->codec_tag = 0; vst->codec->width = width; vst->codec->height = height; if (!smush->version) { if (ff_alloc_extradata(vst->codec, 1024 + 2)) return AVERROR(ENOMEM); AV_WL16(vst->codec->extradata, subversion); for (i = 0; i < 256; i++) AV_WL32(vst->codec->extradata + 2 + i * 4, palette[i]); } if (got_audio) { ast = avformat_new_stream(ctx, 0); if (!ast) return AVERROR(ENOMEM); smush->audio_stream_index = ast->index; ast->start_time = 0; ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = AV_CODEC_ID_ADPCM_VIMA; ast->codec->codec_tag = 0; ast->codec->sample_rate = sample_rate; ast->codec->channels = channels; avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); } return 0; }
static int fourxm_read_header(AVFormatContext *s, AVFormatParameters *ap) { ByteIOContext *pb = s->pb; unsigned int fourcc_tag; unsigned int size; int header_size; FourxmDemuxContext *fourxm = s->priv_data; unsigned char *header; int i; int current_track = -1; AVStream *st; fourxm->track_count = 0; fourxm->tracks = NULL; fourxm->selected_track = 0; fourxm->fps = 1.0; /* skip the first 3 32-bit numbers */ url_fseek(pb, 12, SEEK_CUR); /* check for LIST-HEAD */ GET_LIST_HEADER(); header_size = size - 4; if (fourcc_tag != HEAD_TAG) return AVERROR_INVALIDDATA; /* allocate space for the header and load the whole thing */ header = av_malloc(header_size); if (!header) return AVERROR(ENOMEM); if (get_buffer(pb, header, header_size) != header_size) return AVERROR(EIO); /* take the lazy approach and search for any and all vtrk and strk chunks */ for (i = 0; i < header_size - 8; i++) { fourcc_tag = AV_RL32(&header[i]); size = AV_RL32(&header[i + 4]); if (fourcc_tag == std__TAG) { fourxm->fps = av_int2flt(AV_RL32(&header[i + 12])); } else if (fourcc_tag == vtrk_TAG) { /* check that there is enough data */ if (size != vtrk_SIZE) { av_free(header); return AVERROR_INVALIDDATA; } fourxm->width = AV_RL32(&header[i + 36]); fourxm->height = AV_RL32(&header[i + 40]); /* allocate a new AVStream */ st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); av_set_pts_info(st, 60, 1, fourxm->fps); fourxm->video_stream_index = st->index; st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = 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) { /* check that there is enough data */ if (size != strk_SIZE) { av_free(header); return AVERROR_INVALIDDATA; } current_track = AV_RL32(&header[i + 8]); if (current_track + 1 > fourxm->track_count) { fourxm->track_count = current_track + 1; if((unsigned)fourxm->track_count >= UINT_MAX / sizeof(AudioTrack)) return -1; fourxm->tracks = av_realloc(fourxm->tracks, fourxm->track_count * sizeof(AudioTrack)); if (!fourxm->tracks) { av_free(header); return AVERROR(ENOMEM); } } 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]); i += 8 + size; /* allocate a new AVStream */ st = av_new_stream(s, current_track); if (!st) return AVERROR(ENOMEM); av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate); fourxm->tracks[current_track].stream_index = st->index; st->codec->codec_type = CODEC_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_sample = fourxm->tracks[current_track].bits; st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_sample; st->codec->block_align = st->codec->channels * st->codec->bits_per_sample; if (fourxm->tracks[current_track].adpcm) st->codec->codec_id = CODEC_ID_ADPCM_4XM; else if (st->codec->bits_per_sample == 8) st->codec->codec_id = CODEC_ID_PCM_U8; else st->codec->codec_id = CODEC_ID_PCM_S16LE; } } av_free(header); /* skip over the LIST-MOVI chunk (which is where the stream should be */ GET_LIST_HEADER(); if (fourcc_tag != MOVI_TAG) return AVERROR_INVALIDDATA; /* initialize context members */ fourxm->video_pts = -1; /* first frame will push to 0 */ fourxm->audio_pts = 0; return 0; }