static int idcin_read_packet(AVFormatContext *s,

                             AVPacket *pkt)

{

    int ret;

    unsigned int command;

    unsigned int chunk_size;

    IdcinDemuxContext *idcin = s->priv_data;

    AVIOContext *pb = s->pb;

    int i;

    int palette_scale;

    unsigned char r, g, b;

    unsigned char palette_buffer[768];

    uint32_t palette[256];



    if (s->pb->eof_reached)

        return AVERROR(EIO);



    if (idcin->next_chunk_is_video) {

        command = avio_rl32(pb);

        if (command == 2) {

            return AVERROR(EIO);

        } else if (command == 1) {

            /* trigger a palette change */

            if (avio_read(pb, palette_buffer, 768) != 768)

                return AVERROR(EIO);

            /* scale the palette as necessary */

            palette_scale = 2;

            for (i = 0; i < 768; i++)

                if (palette_buffer[i] > 63) {

                    palette_scale = 0;

                    break;

                }



            for (i = 0; i < 256; i++) {

                r = palette_buffer[i * 3    ] << palette_scale;

                g = palette_buffer[i * 3 + 1] << palette_scale;

                b = palette_buffer[i * 3 + 2] << palette_scale;

                palette[i] = (r << 16) | (g << 8) | (b);

            }

        }



        chunk_size = avio_rl32(pb);

        if (chunk_size < 4 || chunk_size > INT_MAX - 4) {

            av_log(s, AV_LOG_ERROR, "invalid chunk size: %u\n", chunk_size);

            return AVERROR_INVALIDDATA;

        }

        /* skip the number of decoded bytes (always equal to width * height) */

        avio_skip(pb, 4);

        chunk_size -= 4;

        ret= av_get_packet(pb, pkt, chunk_size);

        if (ret < 0)

            return ret;

        if (command == 1) {

            uint8_t *pal;



            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,

                                          AVPALETTE_SIZE);

            if (ret < 0)

                return ret;

            memcpy(pal, palette, AVPALETTE_SIZE);

            pkt->flags |= AV_PKT_FLAG_KEY;

        }

        pkt->stream_index = idcin->video_stream_index;

        pkt->duration     = 1;

    } else {

        /* send out the audio chunk */

        if (idcin->current_audio_chunk)

            chunk_size = idcin->audio_chunk_size2;

        else

            chunk_size = idcin->audio_chunk_size1;

        ret= av_get_packet(pb, pkt, chunk_size);

        if (ret < 0)

            return ret;

        pkt->stream_index = idcin->audio_stream_index;

        pkt->duration     = chunk_size / idcin->block_align;



        idcin->current_audio_chunk ^= 1;

    }



    if (idcin->audio_present)

        idcin->next_chunk_is_video ^= 1;



    return ret;

}
