static int
ebml_read_element_level_up (MatroskaDemuxContext *matroska)
{
    ByteIOContext *pb = matroska->ctx->pb;
    offset_t pos = url_ftell(pb);
    int num = 0;
    while (matroska->num_levels > 0) {
        MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1];
        if (pos >= level->start + level->length) {
            matroska->num_levels--;
            num++;
        } else {
            break;
        }
    }
    return num;
}
['static int\nmatroska_parse_seekhead (MatroskaDemuxContext *matroska)\n{\n    int res = 0;\n    uint32_t id;\n    av_log(matroska->ctx, AV_LOG_DEBUG, "parsing seekhead...\\n");\n    while (res == 0) {\n        if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {\n            res = AVERROR(EIO);\n            break;\n        } else if (matroska->level_up) {\n            matroska->level_up--;\n            break;\n        }\n        switch (id) {\n            case MATROSKA_ID_SEEKENTRY: {\n                uint32_t seek_id = 0, peek_id_cache = 0;\n                uint64_t seek_pos = (uint64_t) -1, t;\n                if ((res = ebml_read_master(matroska, &id)) < 0)\n                    break;\n                while (res == 0) {\n                    if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {\n                        res = AVERROR(EIO);\n                        break;\n                    } else if (matroska->level_up) {\n                        matroska->level_up--;\n                        break;\n                    }\n                    switch (id) {\n                        case MATROSKA_ID_SEEKID:\n                            res = ebml_read_uint(matroska, &id, &t);\n                            seek_id = t;\n                            break;\n                        case MATROSKA_ID_SEEKPOSITION:\n                            res = ebml_read_uint(matroska, &id, &seek_pos);\n                            break;\n                        default:\n                            av_log(matroska->ctx, AV_LOG_INFO,\n                                   "Unknown seekhead ID 0x%x\\n", id);\n                        case EBML_ID_VOID:\n                            res = ebml_read_skip(matroska);\n                            break;\n                    }\n                    if (matroska->level_up) {\n                        matroska->level_up--;\n                        break;\n                    }\n                }\n                if (!seek_id || seek_pos == (uint64_t) -1) {\n                    av_log(matroska->ctx, AV_LOG_INFO,\n                           "Incomplete seekhead entry (0x%x/%"PRIu64")\\n",\n                           seek_id, seek_pos);\n                    break;\n                }\n                switch (seek_id) {\n                    case MATROSKA_ID_CUES:\n                    case MATROSKA_ID_TAGS: {\n                        uint32_t level_up = matroska->level_up;\n                        offset_t before_pos;\n                        uint64_t length;\n                        MatroskaLevel level;\n                        peek_id_cache = matroska->peek_id;\n                        before_pos = url_ftell(matroska->ctx->pb);\n                        if ((res = ebml_read_seek(matroska, seek_pos +\n                                               matroska->segment_start)) < 0)\n                            return res;\n                        if (matroska->num_levels == EBML_MAX_DEPTH) {\n                            av_log(matroska->ctx, AV_LOG_INFO,\n                                   "Max EBML element depth (%d) reached, "\n                                   "cannot parse further.\\n", EBML_MAX_DEPTH);\n                            return AVERROR_UNKNOWN;\n                        }\n                        level.start = 0;\n                        level.length = (uint64_t)-1;\n                        matroska->levels[matroska->num_levels] = level;\n                        matroska->num_levels++;\n                        if (!(id = ebml_peek_id (matroska,\n                                                 &matroska->level_up)))\n                            goto finish;\n                        if (id != seek_id) {\n                            av_log(matroska->ctx, AV_LOG_INFO,\n                                   "We looked for ID=0x%x but got "\n                                   "ID=0x%x (pos=%"PRIu64")",\n                                   seek_id, id, seek_pos +\n                                   matroska->segment_start);\n                            goto finish;\n                        }\n                        if ((res = ebml_read_master(matroska, &id)) < 0)\n                            goto finish;\n                        switch (id) {\n                            case MATROSKA_ID_CUES:\n                                if (!(res = matroska_parse_index(matroska)) ||\n                                    url_feof(matroska->ctx->pb)) {\n                                    matroska->index_parsed = 1;\n                                    res = 0;\n                                }\n                                break;\n                            case MATROSKA_ID_TAGS:\n                                if (!(res = matroska_parse_metadata(matroska)) ||\n                                   url_feof(matroska->ctx->pb)) {\n                                    matroska->metadata_parsed = 1;\n                                    res = 0;\n                                }\n                                break;\n                        }\n                    finish:\n                        while (matroska->num_levels) {\n                            matroska->num_levels--;\n                            length =\n                                matroska->levels[matroska->num_levels].length;\n                            if (length == (uint64_t)-1)\n                                break;\n                        }\n                        if ((res = ebml_read_seek(matroska, before_pos)) < 0)\n                            return res;\n                        matroska->peek_id = peek_id_cache;\n                        matroska->level_up = level_up;\n                        break;\n                    }\n                    default:\n                        av_log(matroska->ctx, AV_LOG_INFO,\n                               "Ignoring seekhead entry for ID=0x%x\\n",\n                               seek_id);\n                        break;\n                }\n                break;\n            }\n            default:\n                av_log(matroska->ctx, AV_LOG_INFO,\n                       "Unknown seekhead ID 0x%x\\n", id);\n            case EBML_ID_VOID:\n                res = ebml_read_skip(matroska);\n                break;\n        }\n        if (matroska->level_up) {\n            matroska->level_up--;\n            break;\n        }\n    }\n    return res;\n}', 'static uint32_t\nebml_peek_id (MatroskaDemuxContext *matroska,\n              int                  *level_up)\n{\n    uint32_t id;\n    if (ebml_read_element_id(matroska, &id, level_up) < 0)\n        return 0;\n    return id;\n}', 'static int\nebml_read_element_id (MatroskaDemuxContext *matroska,\n                      uint32_t             *id,\n                      int                  *level_up)\n{\n    int read;\n    uint64_t total;\n    if (matroska->peek_id != 0) {\n        if (level_up)\n            *level_up = 0;\n        *id = matroska->peek_id;\n        return 0;\n    }\n    if ((read = ebml_read_num(matroska, 4, &total)) < 0)\n        return read;\n    *id = matroska->peek_id  = total | (1 << (read * 7));\n    if (level_up)\n        *level_up = ebml_read_element_level_up(matroska);\n    return read;\n}', 'static int\nebml_read_master (MatroskaDemuxContext *matroska,\n                  uint32_t             *id)\n{\n    ByteIOContext *pb = matroska->ctx->pb;\n    uint64_t length;\n    MatroskaLevel *level;\n    int res;\n    if ((res = ebml_read_element_id(matroska, id, NULL)) < 0 ||\n        (res = ebml_read_element_length(matroska, &length)) < 0)\n        return res;\n    if (matroska->num_levels >= EBML_MAX_DEPTH) {\n        av_log(matroska->ctx, AV_LOG_ERROR,\n               "File moves beyond max. allowed depth (%d)\\n", EBML_MAX_DEPTH);\n        return AVERROR(ENOSYS);\n    }\n    level = &matroska->levels[matroska->num_levels++];\n    level->start = url_ftell(pb);\n    level->length = length;\n    return 0;\n}', 'static int\nebml_read_element_level_up (MatroskaDemuxContext *matroska)\n{\n    ByteIOContext *pb = matroska->ctx->pb;\n    offset_t pos = url_ftell(pb);\n    int num = 0;\n    while (matroska->num_levels > 0) {\n        MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1];\n        if (pos >= level->start + level->length) {\n            matroska->num_levels--;\n            num++;\n        } else {\n            break;\n        }\n    }\n    return num;\n}']