static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb    = s->pb;
    unsigned int chunk_type, chunk_size;
    int ret = 0, packet_read = 0, key = 0;
    int av_uninit(num_samples);
    while (!packet_read) {
        chunk_type = avio_rl32(pb);
        chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
        if (chunk_size <= 8)
            return AVERROR_INVALIDDATA;
        chunk_size -= 8;
        switch (chunk_type) {
        case ISNh_TAG:
            if (chunk_size < 32)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, 32);
            chunk_size -= 32;
        case ISNd_TAG:
        case SCDl_TAG:
        case SNDC_TAG:
        case SDEN_TAG:
            if (!ea->audio_codec) {
                avio_skip(pb, chunk_size);
                break;
            } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR ||
                       ea->audio_codec == AV_CODEC_ID_MP3) {
                num_samples = avio_rl32(pb);
                avio_skip(pb, 8);
                chunk_size -= 12;
            }
            ret = av_get_packet(pb, pkt, chunk_size);
            if (ret < 0)
                return ret;
            pkt->stream_index = ea->audio_stream_index;
            switch (ea->audio_codec) {
            case AV_CODEC_ID_ADPCM_EA:
            case AV_CODEC_ID_ADPCM_EA_R1:
            case AV_CODEC_ID_ADPCM_EA_R2:
            case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
            case AV_CODEC_ID_ADPCM_EA_R3:
                if (pkt->size < 4) {
                    av_log(s, AV_LOG_ERROR, "Packet is too short\n");
                    av_free_packet(pkt);
                    return AVERROR_INVALIDDATA;
                }
                if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3)
                    pkt->duration = AV_RB32(pkt->data);
                else
                    pkt->duration = AV_RL32(pkt->data);
                break;
            case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
                pkt->duration = ret * 2 / ea->num_channels;
                break;
            case AV_CODEC_ID_PCM_S16LE_PLANAR:
            case AV_CODEC_ID_MP3:
                pkt->duration = num_samples;
                break;
            default:
                pkt->duration = chunk_size / (ea->bytes * ea->num_channels);
            }
            packet_read = 1;
            break;
        case 0:
        case ISNe_TAG:
        case SCEl_TAG:
        case SEND_TAG:
        case SEEN_TAG:
            ret         = AVERROR(EIO);
            packet_read = 1;
            break;
        case MVIh_TAG:
        case kVGT_TAG:
        case pQGT_TAG:
        case TGQs_TAG:
        case MADk_TAG:
            key = AV_PKT_FLAG_KEY;
        case MVIf_TAG:
        case fVGT_TAG:
        case MADm_TAG:
        case MADe_TAG:
            avio_seek(pb, -8, SEEK_CUR);
            chunk_size += 8;
            goto get_video_packet;
        case mTCD_TAG:
            avio_skip(pb, 8);
            chunk_size -= 8;
            goto get_video_packet;
        case MV0K_TAG:
        case MPCh_TAG:
        case pIQT_TAG:
            key = AV_PKT_FLAG_KEY;
        case MV0F_TAG:
get_video_packet:
            ret = av_get_packet(pb, pkt, chunk_size);
            if (ret < 0)
                return ret;
            pkt->stream_index = ea->video_stream_index;
            pkt->flags       |= key;
            packet_read       = 1;
            break;
        default:
            avio_skip(pb, chunk_size);
            break;
        }
    }
    return ret;
}
['static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)\n{\n    EaDemuxContext *ea = s->priv_data;\n    AVIOContext *pb    = s->pb;\n    unsigned int chunk_type, chunk_size;\n    int ret = 0, packet_read = 0, key = 0;\n    int av_uninit(num_samples);\n    while (!packet_read) {\n        chunk_type = avio_rl32(pb);\n        chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);\n        if (chunk_size <= 8)\n            return AVERROR_INVALIDDATA;\n        chunk_size -= 8;\n        switch (chunk_type) {\n        case ISNh_TAG:\n            if (chunk_size < 32)\n                return AVERROR_INVALIDDATA;\n            avio_skip(pb, 32);\n            chunk_size -= 32;\n        case ISNd_TAG:\n        case SCDl_TAG:\n        case SNDC_TAG:\n        case SDEN_TAG:\n            if (!ea->audio_codec) {\n                avio_skip(pb, chunk_size);\n                break;\n            } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR ||\n                       ea->audio_codec == AV_CODEC_ID_MP3) {\n                num_samples = avio_rl32(pb);\n                avio_skip(pb, 8);\n                chunk_size -= 12;\n            }\n            ret = av_get_packet(pb, pkt, chunk_size);\n            if (ret < 0)\n                return ret;\n            pkt->stream_index = ea->audio_stream_index;\n            switch (ea->audio_codec) {\n            case AV_CODEC_ID_ADPCM_EA:\n            case AV_CODEC_ID_ADPCM_EA_R1:\n            case AV_CODEC_ID_ADPCM_EA_R2:\n            case AV_CODEC_ID_ADPCM_IMA_EA_EACS:\n            case AV_CODEC_ID_ADPCM_EA_R3:\n                if (pkt->size < 4) {\n                    av_log(s, AV_LOG_ERROR, "Packet is too short\\n");\n                    av_free_packet(pkt);\n                    return AVERROR_INVALIDDATA;\n                }\n                if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3)\n                    pkt->duration = AV_RB32(pkt->data);\n                else\n                    pkt->duration = AV_RL32(pkt->data);\n                break;\n            case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:\n                pkt->duration = ret * 2 / ea->num_channels;\n                break;\n            case AV_CODEC_ID_PCM_S16LE_PLANAR:\n            case AV_CODEC_ID_MP3:\n                pkt->duration = num_samples;\n                break;\n            default:\n                pkt->duration = chunk_size / (ea->bytes * ea->num_channels);\n            }\n            packet_read = 1;\n            break;\n        case 0:\n        case ISNe_TAG:\n        case SCEl_TAG:\n        case SEND_TAG:\n        case SEEN_TAG:\n            ret         = AVERROR(EIO);\n            packet_read = 1;\n            break;\n        case MVIh_TAG:\n        case kVGT_TAG:\n        case pQGT_TAG:\n        case TGQs_TAG:\n        case MADk_TAG:\n            key = AV_PKT_FLAG_KEY;\n        case MVIf_TAG:\n        case fVGT_TAG:\n        case MADm_TAG:\n        case MADe_TAG:\n            avio_seek(pb, -8, SEEK_CUR);\n            chunk_size += 8;\n            goto get_video_packet;\n        case mTCD_TAG:\n            avio_skip(pb, 8);\n            chunk_size -= 8;\n            goto get_video_packet;\n        case MV0K_TAG:\n        case MPCh_TAG:\n        case pIQT_TAG:\n            key = AV_PKT_FLAG_KEY;\n        case MV0F_TAG:\nget_video_packet:\n            ret = av_get_packet(pb, pkt, chunk_size);\n            if (ret < 0)\n                return ret;\n            pkt->stream_index = ea->video_stream_index;\n            pkt->flags       |= key;\n            packet_read       = 1;\n            break;\n        default:\n            avio_skip(pb, chunk_size);\n            break;\n        }\n    }\n    return ret;\n}', 'unsigned int avio_rb32(AVIOContext *s)\n{\n    unsigned int val;\n    val = avio_rb16(s) << 16;\n    val |= avio_rb16(s);\n    return val;\n}', 'unsigned int avio_rb16(AVIOContext *s)\n{\n    unsigned int val;\n    val = avio_r8(s) << 8;\n    val |= avio_r8(s);\n    return val;\n}', 'int avio_r8(AVIOContext *s)\n{\n    if (s->buf_ptr >= s->buf_end)\n        fill_buffer(s);\n    if (s->buf_ptr < s->buf_end)\n        return *s->buf_ptr++;\n    return 0;\n}']