static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) { int ret; int nblocks; APEContext *ape = s->priv_data; uint32_t extra_size = 8; if (url_feof(s->pb)) return AVERROR_EOF; if (ape->currentframe >= ape->totalframes) return AVERROR_EOF; if (avio_seek(s->pb, ape->frames[ape->currentframe].pos, SEEK_SET) < 0) return AVERROR(EIO); /* Calculate how many blocks there are in this frame */ if (ape->currentframe == (ape->totalframes - 1)) nblocks = ape->finalframeblocks; else nblocks = ape->blocksperframe; if (ape->frames[ape->currentframe].size <= 0 || ape->frames[ape->currentframe].size > INT_MAX - extra_size) { av_log(s, AV_LOG_ERROR, "invalid packet size: %d\n", ape->frames[ape->currentframe].size); ape->currentframe++; return AVERROR(EIO); } if (av_new_packet(pkt, ape->frames[ape->currentframe].size + extra_size) < 0) return AVERROR(ENOMEM); AV_WL32(pkt->data , nblocks); AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip); ret = avio_read(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size); pkt->pts = ape->frames[ape->currentframe].pts; pkt->stream_index = 0; /* note: we need to modify the packet size here to handle the last packet */ pkt->size = ret + extra_size; ape->currentframe++; return 0; }