static int bmv_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    BMVContext *c = s->priv_data;
    int type, err;

    while (c->get_next) {
        if (s->pb->eof_reached)
            return AVERROR_EOF;
        type = avio_r8(s->pb);
        if (type == BMV_NOP)
            continue;
        if (type == BMV_END)
            return AVERROR_EOF;
        c->size = avio_rl24(s->pb);
        if (!c->size)
            return AVERROR_INVALIDDATA;
        if ((err = av_reallocp(&c->packet, c->size + 1)) < 0)
            return err;
        c->packet[0] = type;
        if (avio_read(s->pb, c->packet + 1, c->size) != c->size)
            return AVERROR(EIO);
        if (type & BMV_AUDIO) {
            int audio_size = c->packet[1] * 65 + 1;
            if (audio_size >= c->size) {
                av_log(s, AV_LOG_ERROR, "Reported audio size %d is bigger than packet size (%d)\n",
                       audio_size, c->size);
                return AVERROR_INVALIDDATA;
            }
            if (av_new_packet(pkt, audio_size) < 0)
                return AVERROR(ENOMEM);
            memcpy(pkt->data, c->packet + 1, pkt->size);
            pkt->stream_index = 1;
            pkt->pts          = c->audio_pos;
            pkt->duration     = c->packet[1] * 32;
            c->audio_pos += pkt->duration;
            c->get_next   = 0;
            return pkt->size;
        } else
            break;
    }
    if (av_new_packet(pkt, c->size + 1) < 0)
        return AVERROR(ENOMEM);
    pkt->stream_index = 0;
    c->get_next = 1;
    memcpy(pkt->data, c->packet, pkt->size);
    return pkt->size;
}