static int read_packet(AVFormatContext *s, AVPacket *pkt) { PAFDemuxContext *p = s->priv_data; AVIOContext *pb = s->pb; uint32_t count, offset; int size, i; if (p->current_frame >= p->nb_frames) return AVERROR_EOF; if (url_feof(pb)) return AVERROR_EOF; if (p->got_audio) { if (av_new_packet(pkt, p->audio_size) < 0) return AVERROR(ENOMEM); memcpy(pkt->data, p->temp_audio_frame, p->audio_size); pkt->duration = PAF_SOUND_SAMPLES * (p->audio_size / PAF_SOUND_FRAME_SIZE); pkt->flags |= AV_PKT_FLAG_KEY; pkt->stream_index = 1; p->got_audio = 0; return pkt->size; } count = (p->current_frame == 0) ? p->preload_count : p->blocks_count_table[p->current_frame - 1]; for (i = 0; i < count; i++) { if (p->current_frame_block >= p->frame_blks) return AVERROR_INVALIDDATA; offset = p->blocks_offset_table[p->current_frame_block] & ~(1U << 31); if (p->blocks_offset_table[p->current_frame_block] & (1U << 31)) { if (offset > p->audio_size - p->buffer_size) return AVERROR_INVALIDDATA; avio_read(pb, p->audio_frame + offset, p->buffer_size); if (offset == (p->max_audio_blks - 2) * p->buffer_size) { memcpy(p->temp_audio_frame, p->audio_frame, p->audio_size); p->got_audio = 1; } } else { if (offset > p->video_size - p->buffer_size) return AVERROR_INVALIDDATA; avio_read(pb, p->video_frame + offset, p->buffer_size); } p->current_frame_block++; } size = p->video_size - p->frames_offset_table[p->current_frame]; if (size < 1) return AVERROR_INVALIDDATA; if (av_new_packet(pkt, size) < 0) return AVERROR(ENOMEM); pkt->stream_index = 0; pkt->duration = 1; memcpy(pkt->data, p->video_frame + p->frames_offset_table[p->current_frame], size); if (pkt->data[0] & 0x20) pkt->flags |= AV_PKT_FLAG_KEY; p->current_frame++; return pkt->size; }