static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int file)

{

    MlvContext *mlv = avctx->priv_data;

    AVIOContext *pb = mlv->pb[file];

    int ret;

    while (!avio_feof(pb)) {

        int type;

        unsigned int size;

        type = avio_rl32(pb);

        size = avio_rl32(pb);

        avio_skip(pb, 8); //timestamp

        if (size < 16)

            break;

        size -= 16;

        if (vst && type == MKTAG('R','A','W','I') && size >= 164) {

            vst->codec->width  = avio_rl16(pb);

            vst->codec->height = avio_rl16(pb);

            if (avio_rl32(pb) != 1)

                avpriv_request_sample(avctx, "raw api version");

            avio_skip(pb, 20); // pointer, width, height, pitch, frame_size

            vst->codec->bits_per_coded_sample = avio_rl32(pb);

            avio_skip(pb, 8 + 16 + 24); // black_level, white_level, xywh, active_area, exposure_bias

            if (avio_rl32(pb) != 0x2010100) /* RGGB */

                avpriv_request_sample(avctx, "cfa_pattern");

            avio_skip(pb, 80); // calibration_illuminant1, color_matrix1, dynamic_range

            vst->codec->pix_fmt  = AV_PIX_FMT_BAYER_RGGB16LE;

            vst->codec->codec_tag = MKTAG('B', 'I', 'T', 16);

            size -= 164;

        } else if (ast && type == MKTAG('W', 'A', 'V', 'I') && size >= 16) {

            ret = ff_get_wav_header(pb, ast->codec, 16);

            if (ret < 0)

                return ret;

            size -= 16;

        } else if (type == MKTAG('I','N','F','O')) {

            if (size > 0)

                read_string(avctx, pb, "info", size);

            continue;

        } else if (type == MKTAG('I','D','N','T') && size >= 36) {

            read_string(avctx, pb, "cameraName", 32);

            read_uint32(avctx, pb, "cameraModel", "0x%"PRIx32);

            size -= 36;

            if (size >= 32) {

                read_string(avctx, pb, "cameraSerial", 32);

                size -= 32;

            }

        } else if (type == MKTAG('L','E','N','S') && size >= 48) {

            read_uint16(avctx, pb, "focalLength", "%i");

            read_uint16(avctx, pb, "focalDist", "%i");

            read_uint16(avctx, pb, "aperture", "%i");

            read_uint8(avctx, pb, "stabilizerMode", "%i");

            read_uint8(avctx, pb, "autofocusMode", "%i");

            read_uint32(avctx, pb, "flags", "0x%"PRIx32);

            read_uint32(avctx, pb, "lensID", "%"PRIi32);

            read_string(avctx, pb, "lensName", 32);

            size -= 48;

            if (size >= 32) {

                read_string(avctx, pb, "lensSerial", 32);

                size -= 32;

            }

        } else if (vst && type == MKTAG('V', 'I', 'D', 'F') && size >= 4) {

            uint64_t pts = avio_rl32(pb);

            ff_add_index_entry(&vst->index_entries, &vst->nb_index_entries, &vst->index_entries_allocated_size,

                               avio_tell(pb) - 20, pts, file, 0, AVINDEX_KEYFRAME);

            size -= 4;

        } else if (ast && type == MKTAG('A', 'U', 'D', 'F') && size >= 4) {

            uint64_t pts = avio_rl32(pb);

            ff_add_index_entry(&ast->index_entries, &ast->nb_index_entries, &ast->index_entries_allocated_size,

                               avio_tell(pb) - 20, pts, file, 0, AVINDEX_KEYFRAME);

            size -= 4;

        } else if (vst && type == MKTAG('W','B','A','L') && size >= 28) {

            read_uint32(avctx, pb, "wb_mode", "%"PRIi32);

            read_uint32(avctx, pb, "kelvin", "%"PRIi32);

            read_uint32(avctx, pb, "wbgain_r", "%"PRIi32);

            read_uint32(avctx, pb, "wbgain_g", "%"PRIi32);

            read_uint32(avctx, pb, "wbgain_b", "%"PRIi32);

            read_uint32(avctx, pb, "wbs_gm", "%"PRIi32);

            read_uint32(avctx, pb, "wbs_ba", "%"PRIi32);

            size -= 28;

        } else if (type == MKTAG('R','T','C','I') && size >= 20) {

            char str[32];

            struct tm time = { 0 };

            time.tm_sec    = avio_rl16(pb);

            time.tm_min    = avio_rl16(pb);

            time.tm_hour   = avio_rl16(pb);

            time.tm_mday   = avio_rl16(pb);

            time.tm_mon    = avio_rl16(pb);

            time.tm_year   = avio_rl16(pb);

            time.tm_wday   = avio_rl16(pb);

            time.tm_yday   = avio_rl16(pb);

            time.tm_isdst  = avio_rl16(pb);

            avio_skip(pb, 2);

            strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &time);

            av_dict_set(&avctx->metadata, "time", str, 0);

            size -= 20;

        } else if (type == MKTAG('E','X','P','O') && size >= 16) {

            av_dict_set(&avctx->metadata, "isoMode", avio_rl32(pb) ? "auto" : "manual", 0);

            read_uint32(avctx, pb, "isoValue", "%"PRIi32);

            read_uint32(avctx, pb, "isoAnalog", "%"PRIi32);

            read_uint32(avctx, pb, "digitalGain", "%"PRIi32);

            size -= 16;

            if (size >= 8) {

                read_uint64(avctx, pb, "shutterValue", "%"PRIi64);

                size -= 8;

            }

        } else if (type == MKTAG('S','T','Y','L') && size >= 36) {

            read_uint32(avctx, pb, "picStyleId", "%"PRIi32);

            read_uint32(avctx, pb, "contrast", "%"PRIi32);

            read_uint32(avctx, pb, "sharpness", "%"PRIi32);

            read_uint32(avctx, pb, "saturation", "%"PRIi32);

            read_uint32(avctx, pb, "colortone", "%"PRIi32);

            read_string(avctx, pb, "picStyleName", 16);

            size -= 36;

        } else if (type == MKTAG('M','A','R','K')) {

        } else if (type == MKTAG('N','U','L','L')) {

        } else if (type == MKTAG('M','L','V','I')) { /* occurs when MLV and Mnn files are concatenated */

        } else {

            av_log(avctx, AV_LOG_INFO, "unsupported tag %c%c%c%c, size %u\n", type&0xFF, (type>>8)&0xFF, (type>>16)&0xFF, (type>>24)&0xFF, size);

        }

        avio_skip(pb, size);

    }

    return 0;

}
